From 10b0242982e694bfd807d888baeddd4dfcf2ce81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barbora=20Kompi=C5=A1ov=C3=A1?= <barbora.kompisova@gmail.com> Date: Fri, 23 Mar 2018 16:23:31 +0100 Subject: [PATCH] gitlab prototype --- Pipfile | 4 ++- portal/__init__.py | 7 ++++- portal/rest/auth/gitlab.py | 64 ++++++++++++++++++++++++++++++++++++++ portal/service/errors.py | 4 +++ run.py | 6 ++++ 5 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 portal/rest/auth/gitlab.py diff --git a/Pipfile b/Pipfile index d1a67df..b267e79 100644 --- a/Pipfile +++ b/Pipfile @@ -16,6 +16,8 @@ flask-jwt-extended = "*" marshmallow-enum = "*" storage = { git="git@gitlab.fi.muni.cz:grp-kontr2/kontr-storage-module.git", editable='true' } gitpython = "*" +flask-oauthlib = "*" +pyopenssl = "*" [dev-packages] @@ -24,4 +26,4 @@ gitpython = "*" [requires] -python_version = "3.6" \ No newline at end of file +python_version = "3.6" diff --git a/portal/__init__.py b/portal/__init__.py index c1b1144..6450971 100644 --- a/portal/__init__.py +++ b/portal/__init__.py @@ -1,5 +1,6 @@ from flask import Flask from flask_jwt_extended import JWTManager +from flask_oauthlib.client import OAuth from portal.config import CONFIGURATIONS from flask_sqlalchemy import SQLAlchemy @@ -9,6 +10,7 @@ from storage import Storage db = SQLAlchemy() jwt = JWTManager() +oauth = OAuth() # TODO - urgent storage = Storage({ "submissions_dir": "todo", @@ -22,7 +24,7 @@ def config_app(flask_app): config_type = os.environ.get('PORTAL_CONFIG_TYPE', 'devel') config_object = CONFIGURATIONS[config_type] if config_object is None: - raise EnvironmentError() # TODO some custom ex + raise RuntimeError() flask_app.config.from_object(config_object) # app.logger.removeHandler(default_handler) # from Flask release 1.0, not yet available @@ -35,6 +37,9 @@ def create_app(): db.init_app(app) # init the jwt jwt.init_app(app) + # init the oauth client + oauth.init_app(app) return app + import portal.database.models diff --git a/portal/rest/auth/gitlab.py b/portal/rest/auth/gitlab.py new file mode 100644 index 0000000..78be942 --- /dev/null +++ b/portal/rest/auth/gitlab.py @@ -0,0 +1,64 @@ +from flask import Blueprint, Flask, Config, url_for, request, redirect, session, jsonify, \ + make_response +from flask_oauthlib.client import OAuth, OAuthRemoteApp + +from portal import oauth + + +def extract_user_info(me: dict): + return dict( + uco=None, # TODO: Need from gitlab or prompt the user + name=me['name'], + username=me['username'], + email=me['email'] + ) + + +def create_gitlab_app(oauth: OAuth) -> OAuthRemoteApp: + base_url = "https://gitlab.fi.muni.cz" + client_id = "323ee2a6e24291f899b8415bf6af2a0e89beed711de8a59e01a1291daecea330" + client_secret = "323ee2a6e24291f899b8415bf6af2a0e89beed711de8a59e01a1291daecea330" + + return oauth.remote_app( + 'gitlab', + base_url=base_url, + request_token_url=None, + access_token_url=base_url + "/oauth/token", + authorize_url=base_url + "/oauth/authorize", + access_token_method='POST', + consumer_key=client_id, + consumer_secret=client_secret + ) + + +gitlab = create_gitlab_app(oauth=oauth) +oauth = Blueprint('oauth', __name__, url_prefix='/oauth') + + +@oauth.route('/login', methods=['GET']) +def oauth_login(): + callback = url_for('oauth.oauth_authorized', _external=True, _scheme='https') + return gitlab.authorize(callback=callback) + + +@oauth.route('/login/authorized', methods=['GET']) +def oauth_authorized(): + resp = gitlab.authorized_response() + if resp is None: + return 'Access denied: reason=%s error=%s' % ( + request.args['error'], + request.args['error_description'] + ) + + token = resp['access_token'] + session['gitlab_token'] = (token, '') + me = gitlab.get('/api/v4/user') + user_info = extract_user_info(me) + data = dict(data=me.data, token=token) + return jsonify(data) + + +@gitlab.tokengetter +def get_gitlab_oauth_token(): + token = session.get('gitlab_token') + return token diff --git a/portal/service/errors.py b/portal/service/errors.py index 72a4a30..c2e4ee1 100644 --- a/portal/service/errors.py +++ b/portal/service/errors.py @@ -6,6 +6,10 @@ class PortalError(RuntimeError): """ +class PortalConfigurationLoadError(PortalError): + pass + + class PortalAPIError(Exception): def __init__(self, code, message): self._code = code diff --git a/run.py b/run.py index e2ef812..be86174 100644 --- a/run.py +++ b/run.py @@ -1,5 +1,6 @@ from portal import create_app from portal import db +from portal.rest.auth.gitlab import oauth from portal.rest.auth.login import auth from sample_data.data_init import init_data @@ -7,6 +8,8 @@ from portal.rest.courses.courses import courses from portal.rest.users.users import users from portal.rest.roles.roles import roles from portal.rest.groups.groups import groups +from portal.rest.submissions.submissions import submissions +from portal.rest.projects.projects import projects def init_db(app): @@ -22,7 +25,10 @@ if __name__ == '__main__': app.register_blueprint(users) app.register_blueprint(roles) app.register_blueprint(groups) + app.register_blueprint(submissions) + app.register_blueprint(projects) app.register_blueprint(auth) + app.register_blueprint(oauth) # app.run(use_reloader=False) app.run() -- GitLab