Work in progress: bitbucket support
This commit is contained in:
parent
d180524b23
commit
c480fb2105
12 changed files with 321 additions and 86 deletions
|
@ -113,6 +113,9 @@ class DefaultConfig(object):
|
|||
# Google Config.
|
||||
GOOGLE_LOGIN_CONFIG = None
|
||||
|
||||
# Bitbucket Config.
|
||||
BITBUCKET_TRIGGER_CONFIG = None
|
||||
|
||||
# Requests based HTTP client with a large request pool
|
||||
HTTPCLIENT = build_requests_session()
|
||||
|
||||
|
@ -151,6 +154,9 @@ class DefaultConfig(object):
|
|||
# Feature Flag: Whether to support GitHub build triggers.
|
||||
FEATURE_GITHUB_BUILD = False
|
||||
|
||||
# Feature Flag: Whether to support Bitbucket build triggers.
|
||||
FEATURE_BITBUCKET_BUILD = False
|
||||
|
||||
# Feature Flag: Dockerfile build support.
|
||||
FEATURE_BUILD_SUPPORT = True
|
||||
|
||||
|
|
|
@ -2433,12 +2433,21 @@ def log_action(kind_name, user_or_organization_name, performer=None,
|
|||
datetime=timestamp)
|
||||
|
||||
|
||||
def create_build_trigger(repo, service_name, auth_token, user, pull_robot=None):
|
||||
def update_build_trigger(trigger, config, auth_token=None):
|
||||
trigger.config = json.dumps(config or {})
|
||||
if auth_token is not None:
|
||||
trigger.auth_token = auth_token
|
||||
trigger.save()
|
||||
|
||||
|
||||
def create_build_trigger(repo, service_name, auth_token, user, pull_robot=None, config=None):
|
||||
config = config or {}
|
||||
service = BuildTriggerService.get(name=service_name)
|
||||
trigger = RepositoryBuildTrigger.create(repository=repo, service=service,
|
||||
auth_token=auth_token,
|
||||
connected_user=user,
|
||||
pull_robot=pull_robot)
|
||||
pull_robot=pull_robot,
|
||||
config=json.dumps(config))
|
||||
return trigger
|
||||
|
||||
|
||||
|
|
43
endpoints/bitbuckettrigger.py
Normal file
43
endpoints/bitbuckettrigger.py
Normal file
|
@ -0,0 +1,43 @@
|
|||
import logging
|
||||
|
||||
from flask import request, redirect, url_for, Blueprint
|
||||
from flask.ext.login import current_user
|
||||
|
||||
from endpoints.trigger import BitbucketBuildTrigger
|
||||
from endpoints.common import route_show_if
|
||||
from app import app
|
||||
from data import model
|
||||
from util.names import parse_repository_name
|
||||
from util.http import abort
|
||||
from auth.auth import require_session_login
|
||||
|
||||
import features
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
client = app.config['HTTPCLIENT']
|
||||
bitbuckettrigger = Blueprint('bitbuckettrigger', __name__)
|
||||
|
||||
|
||||
@bitbuckettrigger.route('/bitbucket/callback/trigger/<trigger_uuid>', methods=['GET'])
|
||||
@route_show_if(features.BITBUCKET_BUILD)
|
||||
@require_session_login
|
||||
def attach_bitbucket_build_trigger(trigger_uuid):
|
||||
trigger = model.get_build_trigger(trigger_uuid)
|
||||
if not trigger or trigger.service.name != BitbucketBuildTrigger.service_name():
|
||||
abort(404)
|
||||
|
||||
if trigger.connected_user != current_user.db_user():
|
||||
abort(404)
|
||||
|
||||
verifier = request.args.get('oauth_verifier')
|
||||
result = BitbucketBuildTrigger.exchange_verifier(trigger, verifier)
|
||||
print result
|
||||
return 'hello'
|
||||
|
||||
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)
|
51
endpoints/githubtrigger.py
Normal file
51
endpoints/githubtrigger.py
Normal file
|
@ -0,0 +1,51 @@
|
|||
import logging
|
||||
|
||||
from flask import request, redirect, url_for, Blueprint
|
||||
from flask.ext.login import current_user
|
||||
|
||||
from endpoints.common import route_show_if
|
||||
from app import app, github_trigger
|
||||
from data import model
|
||||
from util.names import parse_repository_name
|
||||
from util.http import abort
|
||||
from auth.permissions import AdministerRepositoryPermission
|
||||
from auth.auth import require_session_login
|
||||
|
||||
import features
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
client = app.config['HTTPCLIENT']
|
||||
githubtrigger = Blueprint('callback', __name__)
|
||||
|
||||
@githubtrigger.route('/github/callback/trigger/<path:repository>', methods=['GET'])
|
||||
@githubtrigger.route('/github/callback/trigger/<path:repository>/__new', methods=['GET'])
|
||||
@route_show_if(features.GITHUB_BUILD)
|
||||
@require_session_login
|
||||
@parse_repository_name
|
||||
def attach_github_build_trigger(namespace, repository):
|
||||
permission = AdministerRepositoryPermission(namespace, repository)
|
||||
if permission.can():
|
||||
code = request.args.get('code')
|
||||
token = github_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, 'github', token, current_user.db_user())
|
||||
|
||||
# TODO(jschorr): Remove once the new layout is in place.
|
||||
admin_path = '%s/%s/%s' % (namespace, repository, 'admin')
|
||||
full_url = '%s%s%s' % (url_for('web.repository', path=admin_path), '?tab=trigger&new_trigger=',
|
||||
trigger.uuid)
|
||||
|
||||
if '__new' in request.url:
|
||||
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)
|
|
@ -5,23 +5,19 @@ from flask import request, redirect, url_for, Blueprint
|
|||
from flask.ext.login import current_user
|
||||
|
||||
from endpoints.common import render_page_template, common_login, route_show_if
|
||||
from app import app, analytics, get_app_url, github_login, google_login, github_trigger
|
||||
from app import app, analytics, get_app_url, github_login, google_login
|
||||
from data import model
|
||||
from util.names import parse_repository_name
|
||||
from util.validation import generate_valid_usernames
|
||||
from util.http import abort
|
||||
from auth.permissions import AdministerRepositoryPermission
|
||||
from auth.auth import require_session_login
|
||||
from peewee import IntegrityError
|
||||
|
||||
import features
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
client = app.config['HTTPCLIENT']
|
||||
|
||||
|
||||
callback = Blueprint('callback', __name__)
|
||||
oauthlogin = Blueprint('oauthlogin', __name__)
|
||||
|
||||
def render_ologin_error(service_name,
|
||||
error_message='Could not load user data. The token may have expired.'):
|
||||
|
@ -30,36 +26,6 @@ def render_ologin_error(service_name,
|
|||
service_url=get_app_url(),
|
||||
user_creation=features.USER_CREATION)
|
||||
|
||||
def exchange_code_for_token(code, service, form_encode=False, redirect_suffix=''):
|
||||
code = request.args.get('code')
|
||||
payload = {
|
||||
'client_id': service.client_id(),
|
||||
'client_secret': service.client_secret(),
|
||||
'code': code,
|
||||
'grant_type': 'authorization_code',
|
||||
'redirect_uri': '%s://%s/oauth2/%s/callback%s' % (app.config['PREFERRED_URL_SCHEME'],
|
||||
app.config['SERVER_HOSTNAME'],
|
||||
service.service_name().lower(),
|
||||
redirect_suffix)
|
||||
}
|
||||
|
||||
headers = {
|
||||
'Accept': 'application/json'
|
||||
}
|
||||
|
||||
token_url = service.token_endpoint()
|
||||
if form_encode:
|
||||
get_access_token = client.post(token_url, data=payload, headers=headers)
|
||||
else:
|
||||
get_access_token = client.post(token_url, params=payload, headers=headers)
|
||||
|
||||
json_data = get_access_token.json()
|
||||
if not json_data:
|
||||
return ''
|
||||
|
||||
token = json_data.get('access_token', '')
|
||||
return token
|
||||
|
||||
|
||||
def get_user(service, token):
|
||||
token_param = {
|
||||
|
@ -129,14 +95,15 @@ def get_google_username(user_data):
|
|||
return username
|
||||
|
||||
|
||||
@callback.route('/google/callback', methods=['GET'])
|
||||
@oauthlogin.route('/google/callback', methods=['GET'])
|
||||
@route_show_if(features.GOOGLE_LOGIN)
|
||||
def google_oauth_callback():
|
||||
error = request.args.get('error', None)
|
||||
if error:
|
||||
return render_ologin_error('Google', error)
|
||||
|
||||
token = exchange_code_for_token(request.args.get('code'), google_login, form_encode=True)
|
||||
code = request.args.get('code')
|
||||
token = google_login.exchange_code_for_token(app.config, client, code, form_encode=True)
|
||||
user_data = get_user(google_login, token)
|
||||
if not user_data or not user_data.get('id', None) or not user_data.get('email', None):
|
||||
return render_ologin_error('Google')
|
||||
|
@ -150,7 +117,7 @@ def google_oauth_callback():
|
|||
metadata=metadata)
|
||||
|
||||
|
||||
@callback.route('/github/callback', methods=['GET'])
|
||||
@oauthlogin.route('/github/callback', methods=['GET'])
|
||||
@route_show_if(features.GITHUB_LOGIN)
|
||||
def github_oauth_callback():
|
||||
error = request.args.get('error', None)
|
||||
|
@ -158,7 +125,8 @@ def github_oauth_callback():
|
|||
return render_ologin_error('GitHub', error)
|
||||
|
||||
# Exchange the OAuth code.
|
||||
token = exchange_code_for_token(request.args.get('code'), github_login)
|
||||
code = request.args.get('code')
|
||||
token = google_login.exchange_code_for_token(app.config, client, code)
|
||||
|
||||
# Retrieve the user's information.
|
||||
user_data = get_user(github_login, token)
|
||||
|
@ -211,12 +179,13 @@ def github_oauth_callback():
|
|||
return conduct_oauth_login(github_login, github_id, username, found_email, metadata=metadata)
|
||||
|
||||
|
||||
@callback.route('/google/callback/attach', methods=['GET'])
|
||||
@oauthlogin.route('/google/callback/attach', methods=['GET'])
|
||||
@route_show_if(features.GOOGLE_LOGIN)
|
||||
@require_session_login
|
||||
def google_oauth_attach():
|
||||
token = exchange_code_for_token(request.args.get('code'), google_login,
|
||||
redirect_suffix='/attach', form_encode=True)
|
||||
code = request.args.get('code')
|
||||
token = google_login.exchange_code_for_token(app.config, client, code,
|
||||
redirect_suffix='/attach', form_encode=True)
|
||||
|
||||
user_data = get_user(google_login, token)
|
||||
if not user_data or not user_data.get('id', None):
|
||||
|
@ -240,11 +209,12 @@ def google_oauth_attach():
|
|||
return redirect(url_for('web.user'))
|
||||
|
||||
|
||||
@callback.route('/github/callback/attach', methods=['GET'])
|
||||
@oauthlogin.route('/github/callback/attach', methods=['GET'])
|
||||
@route_show_if(features.GITHUB_LOGIN)
|
||||
@require_session_login
|
||||
def github_oauth_attach():
|
||||
token = exchange_code_for_token(request.args.get('code'), github_login)
|
||||
code = request.args.get('code')
|
||||
token = google_login.exchange_code_for_token(app.config, client, code)
|
||||
user_data = get_user(github_login, token)
|
||||
if not user_data:
|
||||
return render_ologin_error('GitHub')
|
||||
|
@ -266,36 +236,3 @@ def github_oauth_attach():
|
|||
return render_ologin_error('GitHub', err)
|
||||
|
||||
return redirect(url_for('web.user'))
|
||||
|
||||
|
||||
@callback.route('/github/callback/trigger/<path:repository>', methods=['GET'])
|
||||
@callback.route('/github/callback/trigger/<path:repository>/__new', methods=['GET'])
|
||||
@route_show_if(features.GITHUB_BUILD)
|
||||
@require_session_login
|
||||
@parse_repository_name
|
||||
def attach_github_build_trigger(namespace, repository):
|
||||
permission = AdministerRepositoryPermission(namespace, repository)
|
||||
if permission.can():
|
||||
token = exchange_code_for_token(request.args.get('code'), github_trigger)
|
||||
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, 'github', token, current_user.db_user())
|
||||
|
||||
# TODO(jschorr): Remove once the new layout is in place.
|
||||
admin_path = '%s/%s/%s' % (namespace, repository, 'admin')
|
||||
full_url = '%s%s%s' % (url_for('web.repository', path=admin_path), '?tab=trigger&new_trigger=',
|
||||
trigger.uuid)
|
||||
|
||||
if '__new' in request.url:
|
||||
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)
|
|
@ -7,10 +7,11 @@ import re
|
|||
import json
|
||||
|
||||
from github import Github, UnknownObjectException, GithubException
|
||||
from bitbucket.bitbucket import Bitbucket
|
||||
from tempfile import SpooledTemporaryFile
|
||||
from jsonschema import validate
|
||||
|
||||
from app import app, userfiles as user_files, github_trigger
|
||||
from app import app, userfiles as user_files, github_trigger, get_app_url
|
||||
from util.tarfileappender import TarfileAppender
|
||||
from util.ssh import generate_ssh_keypair
|
||||
|
||||
|
@ -58,6 +59,9 @@ class EmptyRepositoryException(Exception):
|
|||
class RepositoryReadException(Exception):
|
||||
pass
|
||||
|
||||
class TriggerProviderException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class BuildTrigger(object):
|
||||
def __init__(self):
|
||||
|
@ -158,6 +162,87 @@ def get_trigger_config(trigger):
|
|||
return {}
|
||||
|
||||
|
||||
class BitbucketBuildTrigger(BuildTrigger):
|
||||
"""
|
||||
BuildTrigger for Bitbucket.
|
||||
"""
|
||||
@classmethod
|
||||
def service_name(cls):
|
||||
return 'bitbucket'
|
||||
|
||||
@staticmethod
|
||||
def _get_authorized_client(trigger_uuid):
|
||||
key = app.config.get('BITBUCKET_TRIGGER_CONFIG', {}).get('CONSUMER_KEY', '')
|
||||
secret = app.config.get('BITBUCKET_TRIGGER_CONFIG', {}).get('CONSUMER_SECRET', '')
|
||||
|
||||
callback_url = '%s/oauth1/bitbucket/callback/trigger/%s' % (get_app_url(), trigger_uuid)
|
||||
bitbucket_client = Bitbucket()
|
||||
(result, err_message) = bitbucket_client.authorize(key, secret, callback_url)
|
||||
if not result:
|
||||
raise TriggerProviderException(err_message)
|
||||
|
||||
return bitbucket_client
|
||||
|
||||
|
||||
@staticmethod
|
||||
def get_oauth_url(trigger_uuid):
|
||||
bitbucket_client = BitbucketBuildTrigger._get_authorized_client(trigger_uuid)
|
||||
url = bitbucket_client.url('AUTHENTICATE', token=bitbucket_client.access_token)
|
||||
return {
|
||||
'access_token': bitbucket_client.access_token,
|
||||
'access_token_secret': bitbucket_client.access_token_secret,
|
||||
'url': url
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def exchange_verifier(trigger, verifier):
|
||||
trigger_config = get_trigger_config(trigger.config)
|
||||
bitbucket_client = BitbucketBuildTrigger._get_authorized_client(trigger.uuid)
|
||||
print trigger.config
|
||||
print trigger.auth_token
|
||||
print bitbucket_client.verify(verifier, access_token=trigger_config.get('access_token', ''),
|
||||
access_token_secret=trigger.auth_token)
|
||||
return None
|
||||
#(result, _) = bitbucket_client.verify(verifier)
|
||||
|
||||
#if not result:
|
||||
# return None
|
||||
|
||||
#return (bitbucket_client.access_token, bitbucket_client.access_token_secret)
|
||||
|
||||
def is_active(self, config):
|
||||
return False
|
||||
|
||||
def activate(self, trigger_uuid, standard_webhook_url, auth_token, config):
|
||||
return {}
|
||||
|
||||
def deactivate(self, auth_token, config):
|
||||
return config
|
||||
|
||||
def list_build_sources(self, auth_token):
|
||||
return []
|
||||
|
||||
|
||||
def list_build_subdirs(self, auth_token, config):
|
||||
raise RepositoryReadException('Not supported')
|
||||
|
||||
def dockerfile_url(self, auth_token, config):
|
||||
return None
|
||||
|
||||
def load_dockerfile_contents(self, auth_token, config):
|
||||
raise RepositoryReadException('Not supported')
|
||||
|
||||
@staticmethod
|
||||
def _build_commit_info(repo, commit_sha):
|
||||
return {}
|
||||
|
||||
def handle_trigger_request(self, request, trigger):
|
||||
return
|
||||
|
||||
def manual_start(self, trigger, run_parameters=None):
|
||||
return None
|
||||
|
||||
|
||||
class GithubBuildTrigger(BuildTrigger):
|
||||
"""
|
||||
BuildTrigger for GitHub that uses the archive API and buildpacks.
|
||||
|
|
|
@ -20,7 +20,7 @@ from util.cache import no_cache
|
|||
from endpoints.common import common_login, render_page_template, route_show_if, param_required
|
||||
from endpoints.csrf import csrf_protect, generate_csrf_token, verify_csrf
|
||||
from endpoints.registry import set_cache_headers
|
||||
from endpoints.trigger import CustomBuildTrigger
|
||||
from endpoints.trigger import CustomBuildTrigger, BitbucketBuildTrigger, TriggerProviderException
|
||||
from util.names import parse_repository_name, parse_repository_name_and_tag
|
||||
from util.useremails import send_email_changed
|
||||
from util.systemlogs import build_logs_archive
|
||||
|
@ -495,6 +495,41 @@ def download_logs_archive():
|
|||
|
||||
abort(403)
|
||||
|
||||
|
||||
@web.route('/bitbucket/setup/<path:repository>', methods=['GET'])
|
||||
@require_session_login
|
||||
@parse_repository_name
|
||||
@route_show_if(features.BITBUCKET_BUILD)
|
||||
def attach_bitbucket_trigger(namespace, repository_name):
|
||||
permission = AdministerRepositoryPermission(namespace, repository_name)
|
||||
if permission.can():
|
||||
repo = model.get_repository(namespace, repository_name)
|
||||
if not repo:
|
||||
msg = 'Invalid repository: %s/%s' % (namespace, repository_name)
|
||||
abort(404, message=msg)
|
||||
|
||||
trigger = model.create_build_trigger(repo, BitbucketBuildTrigger.service_name(),
|
||||
None,
|
||||
current_user.db_user())
|
||||
|
||||
try:
|
||||
oauth_info = BitbucketBuildTrigger.get_oauth_url(trigger.uuid)
|
||||
|
||||
config = {
|
||||
'access_token': oauth_info['access_token']
|
||||
}
|
||||
|
||||
access_token_secret = oauth_info['access_token_secret']
|
||||
model.update_build_trigger(trigger, config, auth_token=access_token_secret)
|
||||
|
||||
return redirect(oauth_info['url'])
|
||||
except TriggerProviderException:
|
||||
trigger.delete_instance()
|
||||
abort(400, message='Could not retrieve OAuth URL from Bitbucket')
|
||||
|
||||
abort(403)
|
||||
|
||||
|
||||
@web.route('/customtrigger/setup/<path:repository>', methods=['GET'])
|
||||
@require_session_login
|
||||
@parse_repository_name
|
||||
|
|
|
@ -204,6 +204,7 @@ def initialize_database():
|
|||
|
||||
BuildTriggerService.create(name='github')
|
||||
BuildTriggerService.create(name='custom-git')
|
||||
BuildTriggerService.create(name='bitbucket')
|
||||
|
||||
AccessTokenKind.create(name='build-worker')
|
||||
AccessTokenKind.create(name='pushpull-token')
|
||||
|
|
|
@ -92,7 +92,7 @@
|
|||
<b class="caret"></b>
|
||||
</button>
|
||||
<ul class="dropdown-menu dropdown-menu-right pull-right">
|
||||
<li ng-repeat="type in TriggerService.getTypes()">
|
||||
<li ng-repeat="type in TriggerService.getTypes()" ng-if="TriggerService.isEnabled(type)">
|
||||
<a href="{{ TriggerService.getRedirectUrl(type, repository.namespace, repository.name) }}" target="{{ TriggerService.getMetadata(type).is_external ? '' : '_self' }}">
|
||||
<i class="fa fa-lg" ng-class="TriggerService.getMetadata(type).icon"></i>
|
||||
{{ TriggerService.getTitle(type) }}
|
||||
|
|
|
@ -52,6 +52,32 @@ angular.module('quay').factory('TriggerService', ['UtilService', '$sanitize', 'K
|
|||
}
|
||||
},
|
||||
|
||||
'bitbucket': {
|
||||
'description': function(config) {
|
||||
var source = UtilService.textToSafeHtml(config['build_source']);
|
||||
var desc = '<i class="fa fa-bitbucket fa-lg" style="margin-left: 2px; margin-right: 2px"></i> Push to Bitbucket Repository ';
|
||||
desc += '<a href="https://bitbucket.org/' + source + '" target="_blank">' + source + '</a>';
|
||||
desc += '<br>Dockerfile folder: //' + UtilService.textToSafeHtml(config['subdir']);
|
||||
return desc;
|
||||
},
|
||||
'run_parameters': [
|
||||
{
|
||||
'title': 'Branch',
|
||||
'type': 'option',
|
||||
'name': 'branch_name'
|
||||
}
|
||||
],
|
||||
'get_redirect_url': function(namespace, repository) {
|
||||
return Config.getUrl('/bitbucket/setup/' + namespace + '/' + repository);
|
||||
},
|
||||
'is_external': false,
|
||||
'is_enabled': function() {
|
||||
return Features.BITBUCKET_BUILD;
|
||||
},
|
||||
'icon': 'fa-bitbucket',
|
||||
'title': function() { return 'Bitbucket Repository Push'; }
|
||||
},
|
||||
|
||||
'custom-git': {
|
||||
'description': function(config) {
|
||||
var source = UtilService.textToSafeHtml(config['build_source']);
|
||||
|
@ -104,6 +130,14 @@ angular.module('quay').factory('TriggerService', ['UtilService', '$sanitize', 'K
|
|||
return '//' + trigger.config.subdir.replace(new RegExp('(^\/+|\/+$)'), '') + '/Dockerfile';
|
||||
};
|
||||
|
||||
triggerService.isEnabled = function(name) {
|
||||
var type = triggerTypes[name];
|
||||
if (!type) {
|
||||
return false;
|
||||
}
|
||||
return type['is_enabled']();
|
||||
};
|
||||
|
||||
triggerService.getTitle = function(name) {
|
||||
var type = triggerTypes[name];
|
||||
if (!type) {
|
||||
|
|
|
@ -33,6 +33,36 @@ class OAuthConfig(object):
|
|||
|
||||
return endpoint
|
||||
|
||||
def exchange_code_for_token(self, app_config, http_client, code, form_encode=False,
|
||||
redirect_suffix=''):
|
||||
payload = {
|
||||
'client_id': self.client_id(),
|
||||
'client_secret': self.client_secret(),
|
||||
'code': code,
|
||||
'grant_type': 'authorization_code',
|
||||
'redirect_uri': '%s://%s/oauth2/%s/callback%s' % (app_config['PREFERRED_URL_SCHEME'],
|
||||
app_config['SERVER_HOSTNAME'],
|
||||
self.service_name().lower(),
|
||||
redirect_suffix)
|
||||
}
|
||||
|
||||
headers = {
|
||||
'Accept': 'application/json'
|
||||
}
|
||||
|
||||
token_url = self.token_endpoint()
|
||||
if form_encode:
|
||||
get_access_token = http_client.post(token_url, data=payload, headers=headers)
|
||||
else:
|
||||
get_access_token = http_client.post(token_url, params=payload, headers=headers)
|
||||
|
||||
json_data = get_access_token.json()
|
||||
if not json_data:
|
||||
return ''
|
||||
|
||||
token = json_data.get('access_token', '')
|
||||
return token
|
||||
|
||||
|
||||
class GithubOAuthConfig(OAuthConfig):
|
||||
def __init__(self, config, key_name):
|
||||
|
|
8
web.py
8
web.py
|
@ -7,10 +7,14 @@ from endpoints.api import api_bp
|
|||
from endpoints.web import web
|
||||
from endpoints.webhooks import webhooks
|
||||
from endpoints.realtime import realtime
|
||||
from endpoints.callbacks import callback
|
||||
from endpoints.oauthlogin import oauthlogin
|
||||
from endpoints.githubtrigger import githubtrigger
|
||||
from endpoints.bitbuckettrigger import bitbuckettrigger
|
||||
|
||||
application.register_blueprint(web)
|
||||
application.register_blueprint(callback, url_prefix='/oauth2')
|
||||
application.register_blueprint(githubtrigger, 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')
|
||||
application.register_blueprint(webhooks, url_prefix='/webhooks')
|
||||
application.register_blueprint(realtime, url_prefix='/realtime')
|
||||
|
|
Reference in a new issue