Add ability to one-click generate an authorization access token in the applications panel
This commit is contained in:
parent
ccc16fd6f4
commit
58ca76239b
8 changed files with 66 additions and 4 deletions
|
@ -9,6 +9,7 @@ from data.database import (OAuthApplication, OAuthAuthorizationCode, OAuthAccess
|
|||
random_string_generator)
|
||||
from data.model.legacy import get_user
|
||||
from auth import scopes
|
||||
from flask import render_template
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
@ -154,6 +155,7 @@ class DatabaseAuthorizationProvider(AuthorizationProvider):
|
|||
|
||||
|
||||
def get_token_response(self, response_type, client_id, redirect_uri, **params):
|
||||
|
||||
# Ensure proper response_type
|
||||
if response_type != 'token':
|
||||
err = 'unsupported_response_type'
|
||||
|
@ -161,7 +163,7 @@ class DatabaseAuthorizationProvider(AuthorizationProvider):
|
|||
|
||||
# Check redirect URI
|
||||
is_valid_redirect_uri = self.validate_redirect_uri(client_id, redirect_uri)
|
||||
if not is_valid_redirect_uri:
|
||||
if redirect_uri != 'display' and not is_valid_redirect_uri:
|
||||
return self._invalid_redirect_uri_response()
|
||||
|
||||
# Check conditions
|
||||
|
@ -196,6 +198,10 @@ class DatabaseAuthorizationProvider(AuthorizationProvider):
|
|||
url = utils.build_url(redirect_uri, params)
|
||||
url += '#access_token=%s&token_type=%s&expires_in=%s' % (access_token, token_type, expires_in)
|
||||
|
||||
if redirect_uri == 'display':
|
||||
return self._make_response(
|
||||
render_template("message.html", message="Access Token: " + access_token))
|
||||
|
||||
return self._make_response(headers={'Location': url}, status_code=302)
|
||||
|
||||
|
||||
|
|
|
@ -198,6 +198,7 @@ def render_page_template(name, **kwargs):
|
|||
feature_set=json.dumps(features.get_features()),
|
||||
config_set=json.dumps(getFrontendVisibleConfig(app.config)),
|
||||
oauth_set=json.dumps(get_oauth_config()),
|
||||
scope_set=json.dumps(scopes.ALL_SCOPES),
|
||||
mixpanel_key=app.config.get('MIXPANEL_KEY', ''),
|
||||
google_analytics_key=app.config.get('GOOGLE_ANALYTICS_KEY', ''),
|
||||
sentry_public_dsn=app.config.get('SENTRY_PUBLIC_DSN', ''),
|
||||
|
|
|
@ -376,7 +376,7 @@ def request_authorization_code():
|
|||
|
||||
if (not current_user.is_authenticated() or
|
||||
not provider.validate_has_scopes(client_id, current_user.db_user().username, scope)):
|
||||
if not provider.validate_redirect_uri(client_id, redirect_uri):
|
||||
if redirect_uri != 'display' and not provider.validate_redirect_uri(client_id, redirect_uri):
|
||||
current_app = provider.get_application_for_client_id(client_id)
|
||||
if not current_app:
|
||||
abort(404)
|
||||
|
@ -416,7 +416,6 @@ def request_authorization_code():
|
|||
else:
|
||||
return provider.get_authorization_code(response_type, client_id, redirect_uri, scope=scope)
|
||||
|
||||
|
||||
@web.route('/oauth/access_token', methods=['POST'])
|
||||
@no_cache
|
||||
@param_required('grant_type')
|
||||
|
|
|
@ -4871,4 +4871,12 @@ i.slack-icon {
|
|||
#startTriggerDialog #runForm .field-title {
|
||||
width: 120px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
#gen-token table {
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
#gen-token input[type="checkbox"] {
|
||||
margin-right: 10px;
|
||||
}
|
|
@ -1711,6 +1711,12 @@ quayApp = angular.module('quay', quayDependencies, function($provide, cfpLoading
|
|||
return notificationService;
|
||||
}]);
|
||||
|
||||
$provide.factory('OAuthService', ['$location', 'Config', function($location, Config) {
|
||||
var oauthService = {};
|
||||
oauthService.SCOPES = window.__auth_scopes;
|
||||
return oauthService;
|
||||
}]);
|
||||
|
||||
$provide.factory('KeyService', ['$location', 'Config', function($location, Config) {
|
||||
var keyService = {}
|
||||
var oauth = window.__oauth;
|
||||
|
|
|
@ -2676,12 +2676,28 @@ function OrgMemberLogsCtrl($scope, $routeParams, $rootScope, $timeout, Restangul
|
|||
}
|
||||
|
||||
|
||||
function ManageApplicationCtrl($scope, $routeParams, $rootScope, $location, $timeout, ApiService) {
|
||||
function ManageApplicationCtrl($scope, $routeParams, $rootScope, $location, $timeout, OAuthService, ApiService, UserService, Config) {
|
||||
var orgname = $routeParams.orgname;
|
||||
var clientId = $routeParams.clientid;
|
||||
|
||||
$scope.Config = Config;
|
||||
$scope.OAuthService = OAuthService;
|
||||
$scope.updating = false;
|
||||
|
||||
$scope.genScopes = {};
|
||||
|
||||
UserService.updateUserIn($scope);
|
||||
|
||||
$scope.getScopes = function(scopes) {
|
||||
var checked = [];
|
||||
for (var scopeName in scopes) {
|
||||
if (scopes.hasOwnProperty(scopeName) && scopes[scopeName]) {
|
||||
checked.push(scopeName);
|
||||
}
|
||||
}
|
||||
return checked;
|
||||
};
|
||||
|
||||
$scope.askResetClientSecret = function() {
|
||||
$('#resetSecretModal').modal({});
|
||||
};
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
<ul class="nav nav-pills nav-stacked">
|
||||
<li class="active"><a href="javascript:void(0)" data-toggle="tab" data-target="#settings">Settings</a></li>
|
||||
<li><a href="javascript:void(0)" data-toggle="tab" data-target="#oauth">OAuth Information</a></li>
|
||||
<li><a href="javascript:void(0)" data-toggle="tab" data-target="#gen-token">Generate Token</a></li>
|
||||
<li><a href="javascript:void(0)" data-toggle="tab" data-target="#delete">Delete Application</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -91,6 +92,30 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Generate Token tab -->
|
||||
<div id="gen-token" class="tab-pane">
|
||||
<div style="margin-bottom: 20px">
|
||||
Click the button below to generate a new <a href="http://tools.ietf.org/html/rfc6749#section-1.4" target="_new">OAuth 2 Access Token</a>.
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 20px">
|
||||
<strong>Note:</strong> The generated token will act on behalf of user <img src="//www.gravatar.com/avatar/{{ user.gravatar }}?s=16&d=identicon" style="margin-left: 6px; margin-right: 4px;">
|
||||
{{ user.username }}
|
||||
</div>
|
||||
|
||||
<table>
|
||||
<tr ng-repeat="(scopeName, scopeInfo) in OAuthService.SCOPES">
|
||||
<td><label onclick="event.stopPropagation()"><input type="checkbox" value="scopeInfo[0]" ng-model="genScopes[scopeName]">{{ scopeInfo[3] }}</label></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<a class="btn btn-success"
|
||||
href="{{ Config.getUrl('/oauth/authorize?response_type=token&client_id=' + application.client_id + '&scope=' + getScopes(genScopes).join(',') + '&redirect_uri=display') }}"
|
||||
ng-disabled="!getScopes(genScopes).length" target="_blank">
|
||||
Generate Access Token
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- OAuth tab -->
|
||||
<div id="oauth" class="tab-pane">
|
||||
<table style="margin-top: 20px;">
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
window.__features = {{ feature_set|safe }};
|
||||
window.__config = {{ config_set|safe }};
|
||||
window.__oauth = {{ oauth_set|safe }};
|
||||
window.__auth_scopes = {{ scope_set|safe }};
|
||||
window.__token = '{{ csrf_token() }}';
|
||||
</script>
|
||||
|
||||
|
|
Reference in a new issue