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:
jakedt 2014-02-18 15:50:15 -05:00
parent fc4983ed8b
commit b5d4919364
13 changed files with 500 additions and 170 deletions

119
endpoints/callbacks.py Normal file
View 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)