diff options
| author | Bryan Newbold <bnewbold@robocracy.org> | 2019-01-03 22:10:41 -0800 | 
|---|---|---|
| committer | Bryan Newbold <bnewbold@robocracy.org> | 2019-01-03 22:10:41 -0800 | 
| commit | 00c0859a7df360380a479eb9dbc79057c0245969 (patch) | |
| tree | 19f7da0d9ac3b4ffab71ffc78817dcbb0445bb82 | |
| parent | 94a6c7f58ba23b2c37b0a997fc4a5e2e16692599 (diff) | |
| download | fatcat-00c0859a7df360380a479eb9dbc79057c0245969.tar.gz fatcat-00c0859a7df360380a479eb9dbc79057c0245969.zip | |
basic OIDC auth working
| -rw-r--r-- | python/fatcat_web/__init__.py | 11 | ||||
| -rw-r--r-- | python/fatcat_web/auth.py | 57 | ||||
| -rw-r--r-- | python/fatcat_web/routes.py | 4 | ||||
| -rw-r--r-- | python/fatcat_web/templates/base.html | 2 | 
4 files changed, 44 insertions, 30 deletions
| diff --git a/python/fatcat_web/__init__.py b/python/fatcat_web/__init__.py index 0afee70e..34618076 100644 --- a/python/fatcat_web/__init__.py +++ b/python/fatcat_web/__init__.py @@ -26,14 +26,21 @@ conf = fatcat_client.Configuration()  conf.host = Config.FATCAT_API_HOST  api = fatcat_client.DefaultApi(fatcat_client.ApiClient(conf)) -from fatcat_web import routes, auth +def auth_api(token): +    conf = fatcat_client.Configuration() +    conf.api_key["Authorization"] = token +    conf.api_key_prefix["Authorization"] = "Bearer" +    conf.host = Config.FATCAT_API_HOST +    return fatcat_client.DefaultApi(fatcat_client.ApiClient(conf))  if Config.FATCAT_API_AUTH_TOKEN:      print("Found and using privileged token (eg, for account signup)") -    priv_api = auth.auth_api(Config.FATCAT_API_AUTH_TOKEN) +    priv_api = auth_api(Config.FATCAT_API_AUTH_TOKEN)  else:      print("No privileged token found")      priv_api = None +from fatcat_web import routes, auth +  gitlab_bp = create_flask_blueprint(Gitlab, oauth, auth.handle_oauth)  app.register_blueprint(gitlab_bp, url_prefix='/auth/gitlab') diff --git a/python/fatcat_web/auth.py b/python/fatcat_web/auth.py index c6e6f04c..0bdb564f 100644 --- a/python/fatcat_web/auth.py +++ b/python/fatcat_web/auth.py @@ -1,18 +1,11 @@  from flask import Flask, render_template, send_from_directory, request, \      url_for, abort, g, redirect, jsonify, session, flash -from fatcat_web import login_manager, api, Config +from fatcat_web import login_manager, api, priv_api, Config  from flask_login import logout_user, login_user, UserMixin  import pymacaroons  import fatcat_client -def auth_api(token): -    conf = fatcat_client.Configuration() -    conf.api_key["Authorization"] = token -    conf.api_key_prefix["Authorization"] = "Bearer" -    conf.host = Config.FATCAT_API_HOST -    return fatcat_client.DefaultApi(fatcat_client.ApiClient(conf)) -  def handle_logout():      logout_user()      for k in ('editor', 'token'): @@ -34,35 +27,49 @@ def handle_token_login(token):      if not editor_id:          abort(400)      # fetch editor info -    editor = api.get_editor(editor_id).to_dict() +    editor = api.get_editor(editor_id)      session['api_token'] = token -    session['editor'] = editor -    login_user(load_user(editor_id)) +    session['editor'] = editor.to_dict() +    login_user(load_user(editor.editor_id))      return redirect("/auth/account")  # This will need to login/signup via fatcatd API, then set token in session  def handle_oauth(remote, token, user_info): -    print(remote) -    if token: -        print(remote.name, token)      if user_info: -        print(user_info) -        print(user_info.iss) -        print(user_info.prefered_username) -          # fetch api login/signup using user_info -        params = AuthOidc(remote.name, user_info.sub, user_info.iss) -        resp = api.auth_oidc(params) -        editor = resp['editor'] -        api_token = resp['token'] +        # ISS is basically the API url (though more formal in OIDC) +        # SUB is the stable internal identifier for the user (not usually the username itself) +        # TODO: should have the real sub here +        # TODO: would be nicer to pass preferred_username for account creation +        iss = remote.OAUTH_CONFIG['api_base_url'] + +        # we reuse 'preferred_username' for account name auto-creation (but +        # don't store it otherwise in the backend, at least currently). But i'm +        # not sure all loginpass backends will set it +        if user_info.get('preferred_username'): +            preferred_username = user_info['preferred_username'] +        else: +            preferred_username = user_info['sub'] + +        params = fatcat_client.AuthOidc(remote.name, user_info['sub'], iss, user_info['preferred_username']) +        # this call requires admin privs +        (resp, http_status, http_headers) = priv_api.auth_oidc_with_http_info(params) +        editor = resp.editor +        api_token = resp.token + +        if http_status == 201: +            flash("Welcome to Fatcat! An account has been created for you with a temporary username; you may wish to change it under account settings") +            flash("You must use the same mechanism ({}) to login in the future".format(remote.name)) +        else: +            flash("Welcome back!")          # write token and username to session          session['api_token'] = api_token -        session['editor'] = editor.editor_id +        session['editor'] = editor.to_dict()          # call login_user(load_user(editor_id)) -        login_user(load_user(editor_id)) -        return redirect("/") +        login_user(load_user(editor.editor_id)) +        return redirect("/auth/account")      raise some_error diff --git a/python/fatcat_web/routes.py b/python/fatcat_web/routes.py index 07947fd5..ebf7e88a 100644 --- a/python/fatcat_web/routes.py +++ b/python/fatcat_web/routes.py @@ -4,8 +4,8 @@ import json  from flask import Flask, render_template, send_from_directory, request, \      url_for, abort, g, redirect, jsonify, session, flash  from flask_login import login_required -from fatcat_web import app, api -from fatcat_web.auth import handle_token_login, handle_logout, load_user, auth_api +from fatcat_web import app, api, auth_api +from fatcat_web.auth import handle_token_login, handle_logout, load_user  from fatcat_client.rest import ApiException  from fatcat_web.search import do_search diff --git a/python/fatcat_web/templates/base.html b/python/fatcat_web/templates/base.html index 27b163d2..e3824213 100644 --- a/python/fatcat_web/templates/base.html +++ b/python/fatcat_web/templates/base.html @@ -33,7 +33,7 @@        <div class="ui simple dropdown item">        {{ current_user.username }} <i class="dropdown icon"></i>          <div class="menu"> -          <a class="item" href="/editgroup/current"><i class="edit icon"></i>Edits in Progress</a> +          <a class="item" href="#"><i class="edit icon"></i>Edits in Progress</a>            <a class="item" href="/editor/{{ current_user.editor_id }}/changelog"><i class="history icon"></i>History</a>            <div class="divider"></div>            <a class="item" href="/auth/account"><i class="user icon"></i>Account</a> | 
