Underpinnings of the ability to connect a GitHub account to an existing Quay account.

This commit is contained in:
yackob03 2014-01-14 15:23:44 -05:00
parent c72cae954b
commit f311885e2a
8 changed files with 82 additions and 7 deletions

View file

@ -308,12 +308,18 @@ def create_federated_user(username, email, service_name, service_id):
return new_user
def attach_federated_login(user, service_name, service_id):
service = LoginService.get(LoginService.name == service_name)
FederatedLogin.create(user=user, service=service, service_ident=service_id)
return user
def verify_federated_login(service_name, service_id):
selected = FederatedLogin.select(FederatedLogin, User)
with_service = selected.join(LoginService)
with_user = with_service.switch(FederatedLogin).join(User)
found = with_user.where(FederatedLogin.service_ident == service_id,
LoginService.name == service_name)
LoginService.name == service_name)
found_list = list(found)
@ -323,6 +329,14 @@ def verify_federated_login(service_name, service_id):
return None
def list_federated_logins(user):
selected = FederatedLogin.select(FederatedLogin.service_ident,
LoginService.name)
joined = selected.join(LoginService)
return joined.where(LoginService.name != 'quayrobot',
FederatedLogin.user == user)
def create_confirm_email_code(user):
code = EmailConfirmation.create(user=user, email_confirm=True)
return code

View file

@ -151,6 +151,14 @@ def user_view(user):
organizations = model.get_user_organizations(user.username)
def login_view(login):
return {
'service': login.service.name,
'service_identifier': login.service_ident,
}
logins = model.list_federated_logins(user)
return {
'verified': user.verified,
'anonymous': False,
@ -159,6 +167,7 @@ def user_view(user):
'gravatar': compute_hash(user.email),
'askForPassword': user.password_hash is None,
'organizations': [org_view(o) for o in organizations],
'logins': [login_view(login) for login in logins],
'can_create_repo': True,
'invoice_email': user.invoice_email
}

View file

@ -4,7 +4,7 @@ import stripe
from flask import (abort, redirect, request, url_for, render_template,
make_response, Response)
from flask.ext.login import current_user
from flask.ext.login import login_required, current_user
from urlparse import urlparse
from data import model
@ -155,8 +155,7 @@ def receipt():
abort(404)
@app.route('/oauth2/github/callback', methods=['GET'])
def github_oauth_callback():
def exchange_github_code_for_token(code):
code = request.args.get('code')
payload = {
'client_id': app.config['GITHUB_CLIENT_ID'],
@ -171,13 +170,23 @@ def github_oauth_callback():
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)
user_data = get_user.json()
return get_user.json()
@app.route('/oauth2/github/callback', methods=['GET'])
def github_oauth_callback():
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']
@ -218,6 +227,16 @@ def github_oauth_callback():
return render_page_template('githuberror.html')
@app.route('/oauth2/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)
@app.route('/confirm', methods=['GET'])
def confirm_email():
code = request.values['code']

View file

@ -1879,6 +1879,10 @@ p.editable:hover i {
margin-top: 10px;
}
.user-admin .check-green {
color: #46ac39;
}
#image-history-container {
overflow: hidden;
min-height: 400px;

View file

@ -265,7 +265,8 @@ quayApp = angular.module('quay', ['ngRoute', 'chieffancypants.loadingBar', 'rest
username: null,
email: null,
askForPassword: false,
organizations: []
organizations: [],
logins: []
}
var userService = {}
@ -358,9 +359,11 @@ quayApp = angular.module('quay', ['ngRoute', 'chieffancypants.loadingBar', 'rest
if ($location.host() === 'quay.io') {
keyService['stripePublishableKey'] = 'pk_live_P5wLU0vGdHnZGyKnXlFG4oiu';
keyService['githubClientId'] = '5a8c08b06c48d89d4d1e';
keyService['githubRedirectUri'] = 'https://quay.io/oauth2/github/callback';
} else {
keyService['stripePublishableKey'] = 'pk_test_uEDHANKm9CHCvVa2DLcipGRh';
keyService['githubClientId'] = 'cfbc4aca88e5c1b40679';
keyService['githubRedirectUri'] = 'http://localhost:5000/oauth2/github/callback';
}
return keyService;

View file

@ -868,7 +868,7 @@ function RepoAdminCtrl($scope, Restangular, ApiService, $routeParams, $rootScope
fetchRepository();
}
function UserAdminCtrl($scope, $timeout, $location, ApiService, PlanService, UserService, KeyService, $routeParams) {
function UserAdminCtrl($scope, $timeout, $location, ApiService, PlanService, UserService, KeyService, $routeParams, $http) {
if ($routeParams['migrate']) {
$('#migrateTab').tab('show')
}
@ -876,6 +876,15 @@ function UserAdminCtrl($scope, $timeout, $location, ApiService, PlanService, Use
UserService.updateUserIn($scope, function(user) {
$scope.askForPassword = user.askForPassword;
$scope.cuser = jQuery.extend({}, user);
for (var i = 0; i < $scope.cuser.logins.length; i++) {
if ($scope.cuser.logins[i].service == 'github') {
var githubId = $scope.cuser.logins[i].service_identifier;
$http.get('https://api.github.com/user/' + githubId).success(function(resp) {
$scope.githubLogin = resp.login;
});
}
}
});
$scope.readyForPlan = function() {

View file

@ -31,6 +31,7 @@
<li ng-show="hasPaidBusinessPlan"><a href="javascript:void(0)" data-toggle="tab" data-target="#billing" ng-click="loadInvoices()">Billing History</a></li>
<li><a href="javascript:void(0)" data-toggle="tab" data-target="#robots">Robot Accounts</a></li>
<li><a href="javascript:void(0)" data-toggle="tab" data-target="#password">Set Password</a></li>
<li><a href="javascript:void(0)" data-toggle="tab" data-target="#github">GitHub Login</a></li>
<li ng-show="hasPaidBusinessPlan"><a href="javascript:void(0)" data-toggle="tab" data-target="#logs" ng-click="loadLogs()">Usage Logs</a></li>
<li><a href="javascript:void(0)" data-toggle="tab" data-target="#migrate" id="migrateTab">Convert to Organization</a></li>
</ul>
@ -69,6 +70,20 @@
</div>
</div>
</div>
<!-- Connect with GitHub tab. -->
<div id="github" class="tab-pane">
<div ng-show="githubLogin" class="lead">
<span class="fa-stack">
<i class="fa fa-circle fa-stack-2x check-green"></i>
<i class="fa fa-check fa-stack-1x fa-inverse"></i>
</span>
This account is connected with GitHub account: <b>{{githubLogin}}</b>
</div>
<div ng-show="!githubLogin">
<a href="https://github.com/login/oauth/authorize?client_id={{ githubClientId }}&scope=user:email{{ github_state_clause }}&redirect_uri={{ githubRedirectUri }}/attach class="btn btn-primary btn-block"><i class="fa fa-github fa-lg"></i> Connect with GitHub</a>
</div>
</div>
<!-- Robot accounts tab -->
<div id="robots" class="tab-pane">

View file

@ -16,6 +16,8 @@
<div>
Please register using the <a href="/">registration form</a> to continue.
You will be able to connect your github account to your Quay.io account
in the user settings.
</div>
</div>
</div>