Split out callbacks into their own blueprint. Add build trigger DB information and connect it with some APIs. Stub out the UI to allow for generation of triggers. Split out the triggers into a plugin-ish architecture for easily adding new triggers.
This commit is contained in:
parent
fc4983ed8b
commit
b5d4919364
13 changed files with 500 additions and 170 deletions
119
endpoints/callbacks.py
Normal file
119
endpoints/callbacks.py
Normal file
|
@ -0,0 +1,119 @@
|
|||
import requests
|
||||
import logging
|
||||
|
||||
from flask import request, redirect, url_for, Blueprint
|
||||
from flask.ext.login import login_required, current_user
|
||||
|
||||
from endpoints.common import render_page_template, common_login
|
||||
from app import app, mixpanel
|
||||
from data import model
|
||||
from util.names import parse_repository_name
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
callback = Blueprint('callback', __name__)
|
||||
|
||||
|
||||
def exchange_github_code_for_token(code):
|
||||
code = request.args.get('code')
|
||||
payload = {
|
||||
'client_id': app.config['GITHUB_CLIENT_ID'],
|
||||
'client_secret': app.config['GITHUB_CLIENT_SECRET'],
|
||||
'code': code,
|
||||
}
|
||||
headers = {
|
||||
'Accept': 'application/json'
|
||||
}
|
||||
|
||||
get_access_token = requests.post(app.config['GITHUB_TOKEN_URL'],
|
||||
params=payload, headers=headers)
|
||||
|
||||
token = get_access_token.json()['access_token']
|
||||
return token
|
||||
|
||||
|
||||
def get_github_user(token):
|
||||
token_param = {
|
||||
'access_token': token,
|
||||
}
|
||||
get_user = requests.get(app.config['GITHUB_USER_URL'], params=token_param)
|
||||
|
||||
return get_user.json()
|
||||
|
||||
|
||||
@callback.route('/github/callback', methods=['GET'])
|
||||
def github_oauth_callback():
|
||||
error = request.args.get('error', None)
|
||||
if error:
|
||||
return render_page_template('githuberror.html', error_message=error)
|
||||
|
||||
token = exchange_github_code_for_token(request.args.get('code'))
|
||||
user_data = get_github_user(token)
|
||||
|
||||
username = user_data['login']
|
||||
github_id = user_data['id']
|
||||
|
||||
v3_media_type = {
|
||||
'Accept': 'application/vnd.github.v3'
|
||||
}
|
||||
|
||||
token_param = {
|
||||
'access_token': token,
|
||||
}
|
||||
get_email = requests.get(app.config['GITHUB_USER_EMAILS'],
|
||||
params=token_param, headers=v3_media_type)
|
||||
|
||||
# We will accept any email, but we prefer the primary
|
||||
found_email = None
|
||||
for user_email in get_email.json():
|
||||
found_email = user_email['email']
|
||||
if user_email['primary']:
|
||||
break
|
||||
|
||||
to_login = model.verify_federated_login('github', github_id)
|
||||
if not to_login:
|
||||
# try to create the user
|
||||
try:
|
||||
to_login = model.create_federated_user(username, found_email, 'github',
|
||||
github_id)
|
||||
|
||||
# Success, tell mixpanel
|
||||
mixpanel.track(to_login.username, 'register', {'service': 'github'})
|
||||
|
||||
state = request.args.get('state', None)
|
||||
if state:
|
||||
logger.debug('Aliasing with state: %s' % state)
|
||||
mixpanel.alias(to_login.username, state)
|
||||
|
||||
except model.DataModelException, ex:
|
||||
return render_page_template('githuberror.html', error_message=ex.message)
|
||||
|
||||
if common_login(to_login):
|
||||
return redirect(url_for('web.index'))
|
||||
|
||||
return render_page_template('githuberror.html')
|
||||
|
||||
|
||||
@callback.route('/github/callback/attach', methods=['GET'])
|
||||
@login_required
|
||||
def github_oauth_attach():
|
||||
token = exchange_github_code_for_token(request.args.get('code'))
|
||||
user_data = get_github_user(token)
|
||||
github_id = user_data['id']
|
||||
user_obj = current_user.db_user()
|
||||
model.attach_federated_login(user_obj, 'github', github_id)
|
||||
return redirect(url_for('web.user'))
|
||||
|
||||
|
||||
@callback.route('/github/callback/trigger/<path:repository>', methods=['GET'])
|
||||
@login_required
|
||||
@parse_repository_name
|
||||
def attach_github_build_trigger(namespace, repository):
|
||||
token = exchange_github_code_for_token(request.args.get('code'))
|
||||
model.create_build_trigger(namespace, repository, 'github', token,
|
||||
current_user.db_user())
|
||||
admin_path = '%s/%s/%s' % (namespace, repository, 'admin')
|
||||
full_url = url_for('web.repository', path=admin_path) + '?tab=trigger'
|
||||
logger.debug('Redirecting to full url: %s' % full_url)
|
||||
return redirect(full_url)
|
Reference in a new issue