From 3ac884beb4ea0c8eb54acbc55e97f65ed5cd1418 Mon Sep 17 00:00:00 2001 From: Jimmy Zelinskie Date: Sat, 2 May 2015 17:54:48 -0400 Subject: [PATCH] gitlab oauth --- app.py | 5 +-- endpoints/gitlabtrigger.py | 50 ++++++++++++++++++++++++++ endpoints/oauthlogin.py | 2 +- initdb.py | 1 + static/js/services/key-service.js | 4 +-- static/js/services/trigger-service.js | 5 ++- test/data/test.db | Bin 774144 -> 774144 bytes util/oauth.py | 30 ++++++++++++++-- web.py | 5 ++- 9 files changed, 88 insertions(+), 14 deletions(-) create mode 100644 endpoints/gitlabtrigger.py diff --git a/app.py b/app.py index 33eabf1f8..cd5c6698b 100644 --- a/app.py +++ b/app.py @@ -26,7 +26,7 @@ from data.queue import WorkQueue from util.analytics import Analytics from util.exceptionlog import Sentry from util.names import urn_generator -from util.oauth import GoogleOAuthConfig, GithubOAuthConfig +from util.oauth import GoogleOAuthConfig, GithubOAuthConfig, GitLabOAuthConfig from util.signing import Signer from util.queuemetrics import QueueMetrics from util.config.provider import FileConfigProvider, TestConfigProvider @@ -124,8 +124,9 @@ tf = app.config['DB_TRANSACTION_FACTORY'] github_login = GithubOAuthConfig(app.config, 'GITHUB_LOGIN_CONFIG') github_trigger = GithubOAuthConfig(app.config, 'GITHUB_TRIGGER_CONFIG') +gitlab_trigger = GitLabOAuthConfig(app.config, 'GITLAB_TRIGGER_CONFIG') google_login = GoogleOAuthConfig(app.config, 'GOOGLE_LOGIN_CONFIG') -oauth_apps = [github_login, github_trigger, google_login] +oauth_apps = [github_login, github_trigger, gitlab_trigger, google_login] image_diff_queue = WorkQueue(app.config['DIFFS_QUEUE_NAME'], tf) dockerfile_build_queue = WorkQueue(app.config['DOCKERFILE_BUILD_QUEUE_NAME'], tf, diff --git a/endpoints/gitlabtrigger.py b/endpoints/gitlabtrigger.py new file mode 100644 index 000000000..f9323f7ab --- /dev/null +++ b/endpoints/gitlabtrigger.py @@ -0,0 +1,50 @@ +import logging + +from flask import Blueprint, request, redirect, url_for +from flask.ext.login import current_user + +from app import app, gitlab_trigger +from auth.auth import require_session_login +from auth.permissions import AdministerRepositoryPermission +from data import model +from endpoints.common import route_show_if +from util.http import abort +from util.names import parse_repository_name + +import features + + +logger = logging.getLogger(__name__) +client = app.config['HTTPCLIENT'] +gitlabtrigger = Blueprint('gitlab', __name__) + +@gitlabtrigger.route('/gitlab/callback/trigger', methods=['GET']) +@route_show_if(features.GITLAB_BUILD) +@require_session_login +def attach_gitlab_build_trigger(): + state = request.args.get('state', None) + if not state: + abort(400) + state = state[len('repo:'):] + try: + [namespace, repository] = state.split('/') + except ValueError: + abort(400) + + permission = AdministerRepositoryPermission(namespace, repository) + if permission.can(): + code = request.args.get('code') + token = gitlab_trigger.exchange_code_for_token(app.config, client, code) + repo = model.get_repository(namespace, repository) + if not repo: + msg = 'Invalid repository: %s/%s' % (namespace, repository) + abort(404, message=msg) + + trigger = model.create_build_trigger(repo, 'gitlab', token, current_user.db_user()) + repo_path = '%s/%s' % (namespace, repository) + full_url = '%s%s%s' % (url_for('web.repository', path=repo_path), '?tab=builds&newtrigger=', trigger.uuid) + + logger.debug('Redirecting to full url: %s', full_url) + return redirect(full_url) + + abort(403) diff --git a/endpoints/oauthlogin.py b/endpoints/oauthlogin.py index 7f32ca552..269659a42 100644 --- a/endpoints/oauthlogin.py +++ b/endpoints/oauthlogin.py @@ -235,4 +235,4 @@ def github_oauth_attach(): return render_ologin_error('GitHub', err) - return redirect(url_for('web.user')) \ No newline at end of file + return redirect(url_for('web.user')) diff --git a/initdb.py b/initdb.py index f99547527..b67d0440e 100644 --- a/initdb.py +++ b/initdb.py @@ -205,6 +205,7 @@ def initialize_database(): BuildTriggerService.create(name='github') BuildTriggerService.create(name='custom-git') BuildTriggerService.create(name='bitbucket') + BuildTriggerService.create(name='gitlab') AccessTokenKind.create(name='build-worker') AccessTokenKind.create(name='pushpull-token') diff --git a/static/js/services/key-service.js b/static/js/services/key-service.js index 3f373a294..12b02b41d 100644 --- a/static/js/services/key-service.js +++ b/static/js/services/key-service.js @@ -13,7 +13,7 @@ angular.module('quay').factory('KeyService', ['$location', 'Config', function($l keyService['githubLoginClientId'] = oauth['GITHUB_LOGIN_CONFIG']['CLIENT_ID']; keyService['googleLoginClientId'] = oauth['GOOGLE_LOGIN_CONFIG']['CLIENT_ID']; - keyService['gitlabRedirectUri'] = Config.getURL('/oauth2/gitlab/callback'); + keyService['gitlabRedirectUri'] = Config.getUrl('/oauth2/gitlab/callback'); keyService['githubRedirectUri'] = Config.getUrl('/oauth2/github/callback'); keyService['googleRedirectUri'] = Config.getUrl('/oauth2/google/callback'); @@ -25,7 +25,7 @@ angular.module('quay').factory('KeyService', ['$location', 'Config', function($l keyService['githubTriggerEndpoint'] = oauth['GITHUB_TRIGGER_CONFIG']['GITHUB_ENDPOINT']; keyService['githubTriggerAuthorizeUrl'] = oauth['GITHUB_TRIGGER_CONFIG']['AUTHORIZE_ENDPOINT']; - keySerivce['gitlabTriggerEndpoint'] = oauth['GITLAB_TRIGGER_CONFIG']['GITLAB_ENDPOINT']; + keyService['gitlabTriggerEndpoint'] = oauth['GITLAB_TRIGGER_CONFIG']['GITLAB_ENDPOINT']; keyService['gitlabTriggerAuthorizeUrl'] = oauth['GITLAB_TRIGGER_CONFIG']['AUTHORIZE_ENDPOINT']; keyService['githubLoginScope'] = 'user:email'; diff --git a/static/js/services/trigger-service.js b/static/js/services/trigger-service.js index 42202ee34..9ba657967 100644 --- a/static/js/services/trigger-service.js +++ b/static/js/services/trigger-service.js @@ -104,12 +104,11 @@ angular.module('quay').factory('TriggerService', ['UtilService', '$sanitize', 'K } ], 'get_redirect_url': function(namespace, repository) { - var redirect_uri = KeyService['gitlabRedirectUri'] + '/trigger/' + - namespace + '/' + repository; + var redirect_uri = KeyService['gitlabRedirectUri'] + '/trigger'; var authorize_url = KeyService['gitlabTriggerAuthorizeUrl']; var client_id = KeyService['gitlabTriggerClientId']; - return authorize_url + 'client_id=' + client_id + '&redirect_uri=' + redirect_uri; + return authorize_url + '?client_id=' + client_id + '&redirect_uri=' + redirect_uri + '&response_type=code&state=repo:' + namespace + '/' + repository; }, 'is_external': false, 'is_enabled': function() { diff --git a/test/data/test.db b/test/data/test.db index 52b190882a71076bc58df17daa4a92f492b1c4bd..c90d531f0beab5ca51e9be0a70010338563e1ade 100644 GIT binary patch delta 11693 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 delta 11622 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 z z4<>DdW6{q=Je9e4BPX}u&5dxZ@Fk(2#hKThihQ=P0Els%Z-Qe@JUMeV@xtmaVjezt7Bm1jmgeoH z8}zXsZ;@LtW-|!+;22T8dF?{0=U$a=n-oTJRB zUAX9}da!g0oDHUZ@dje)J_Lui!l6)Z-Uf4S#BsR=W4FPfn8HVY%t|~`HP?RR4sd82 zwj^Zg=+U0(xhrbqwtGtZb&tWDt|0#&Y=hD7rniuwGcm{ctS{Gqv-e;`z)yKmj`h&xA%Vm>i7b{ diff --git a/util/oauth.py b/util/oauth.py index 3e920110a..a9a571eae 100644 --- a/util/oauth.py +++ b/util/oauth.py @@ -15,9 +15,6 @@ class OAuthConfig(object): def user_endpoint(self): raise NotImplementedError - def login_endpoint(self): - raise NotImplementedError - def validate_client_id_and_secret(self, http_client): raise NotImplementedError @@ -200,4 +197,31 @@ class GoogleOAuthConfig(OAuthConfig): } +class GitLabOAuthConfig(OAuthConfig): + def __init__(self, config, key_name): + super(GitLabOAuthConfig, self).__init__(config, key_name) + def _endpoint(self): + endpoint = self.config.get('GITLAB_ENDPOINT', 'https://gitlab.com') + if not endpoint.endswith('/'): + endpoint = endpoint + '/' + return endpoint + + def service_name(self): + return 'GitLab' + + def authorize_endpoint(self): + return self._get_url(self._endpoint(), '/oauth/authorize') + + def token_endpoint(self): + return self._get_url(self._endpoint(), '/oauth/token') + + def validate_client_id_and_secret(self, http_client): + pass + + def get_public_config(self): + return { + 'CLIENT_ID': self.client_id(), + 'AUTHORIZE_ENDPOINT': self.authorize_endpoint(), + 'GITLAB_ENDPOINT': self._endpoint(), + } diff --git a/web.py b/web.py index f90eecc9f..b71884583 100644 --- a/web.py +++ b/web.py @@ -1,6 +1,3 @@ -import logging -import logging.config - from app import app as application from endpoints.api import api_bp @@ -9,10 +6,12 @@ from endpoints.webhooks import webhooks from endpoints.realtime import realtime from endpoints.oauthlogin import oauthlogin from endpoints.githubtrigger import githubtrigger +from endpoints.gitlabtrigger import gitlabtrigger from endpoints.bitbuckettrigger import bitbuckettrigger application.register_blueprint(web) application.register_blueprint(githubtrigger, url_prefix='/oauth2') +application.register_blueprint(gitlabtrigger, url_prefix='/oauth2') application.register_blueprint(oauthlogin, url_prefix='/oauth2') application.register_blueprint(bitbuckettrigger, url_prefix='/oauth1') application.register_blueprint(api_bp, url_prefix='/api')