Add OAuth usage information the API logs, have it be displayed in the logs UI and start on the code to display application information when clicked. Note that this does not (yet) do anything with the information returned as we need to wait for the mainline merge of Angular 1.2.9 (which is in master) before I can continue on the display
This commit is contained in:
parent
e1b704bdac
commit
9ae4506a0d
8 changed files with 104 additions and 8 deletions
|
@ -14,7 +14,7 @@ from data.model import oauth
|
||||||
from app import app
|
from app import app
|
||||||
from permissions import QuayDeferredPermissionUser
|
from permissions import QuayDeferredPermissionUser
|
||||||
from auth_context import (set_authenticated_user, set_validated_token,
|
from auth_context import (set_authenticated_user, set_validated_token,
|
||||||
set_authenticated_user_deferred)
|
set_authenticated_user_deferred, set_validated_oauth_token)
|
||||||
from util.http import abort
|
from util.http import abort
|
||||||
|
|
||||||
|
|
||||||
|
@ -140,7 +140,9 @@ def process_oauth(f):
|
||||||
scope_set = scopes.scopes_from_scope_string(validated.scope)
|
scope_set = scopes.scopes_from_scope_string(validated.scope)
|
||||||
logger.debug('Successfully validated oauth access token: %s with scope: %s', token,
|
logger.debug('Successfully validated oauth access token: %s with scope: %s', token,
|
||||||
scope_set)
|
scope_set)
|
||||||
|
|
||||||
set_authenticated_user(validated.authorized_user)
|
set_authenticated_user(validated.authorized_user)
|
||||||
|
set_validated_oauth_token(validated)
|
||||||
|
|
||||||
new_identity = QuayDeferredPermissionUser(validated.authorized_user.username, 'username',
|
new_identity = QuayDeferredPermissionUser(validated.authorized_user.username, 'username',
|
||||||
scope_set)
|
scope_set)
|
||||||
|
|
|
@ -35,6 +35,15 @@ def set_authenticated_user_deferred(username_or_robotname):
|
||||||
ctx.authenticated_username = username_or_robotname
|
ctx.authenticated_username = username_or_robotname
|
||||||
|
|
||||||
|
|
||||||
|
def get_validated_oauth_token():
|
||||||
|
return getattr(_request_ctx_stack.top, 'validated_oauth_token', None)
|
||||||
|
|
||||||
|
|
||||||
|
def set_validated_oauth_token(token):
|
||||||
|
ctx = _request_ctx_stack.top
|
||||||
|
ctx.validated_oauth_token = token
|
||||||
|
|
||||||
|
|
||||||
def get_validated_token():
|
def get_validated_token():
|
||||||
return getattr(_request_ctx_stack.top, 'validated_token', None)
|
return getattr(_request_ctx_stack.top, 'validated_token', None)
|
||||||
|
|
||||||
|
|
|
@ -176,3 +176,9 @@ def validate_access_token(access_token):
|
||||||
return found
|
return found
|
||||||
except OAuthAccessToken.DoesNotExist:
|
except OAuthAccessToken.DoesNotExist:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def get_application_for_client_id(client_id):
|
||||||
|
try:
|
||||||
|
return OAuthApplication.get(client_id=client_id)
|
||||||
|
except OAuthApplication.DoesNotExist:
|
||||||
|
return None
|
||||||
|
|
|
@ -16,7 +16,7 @@ from auth.permissions import (ReadRepositoryPermission,
|
||||||
ModifyRepositoryPermission,
|
ModifyRepositoryPermission,
|
||||||
AdministerRepositoryPermission)
|
AdministerRepositoryPermission)
|
||||||
from auth import scopes
|
from auth import scopes
|
||||||
from auth.auth_context import get_authenticated_user
|
from auth.auth_context import get_authenticated_user, get_validated_oauth_token
|
||||||
from auth.auth import process_oauth
|
from auth.auth import process_oauth
|
||||||
|
|
||||||
|
|
||||||
|
@ -213,7 +213,16 @@ def request_error(exception=None, **kwargs):
|
||||||
raise InvalidRequest(exception.message, data)
|
raise InvalidRequest(exception.message, data)
|
||||||
|
|
||||||
|
|
||||||
def log_action(kind, user_or_orgname, metadata={}, repo=None):
|
def log_action(kind, user_or_orgname, metadata=None, repo=None):
|
||||||
|
if not metadata:
|
||||||
|
metadata = {}
|
||||||
|
|
||||||
|
oauth_token = get_validated_oauth_token()
|
||||||
|
if oauth_token:
|
||||||
|
metadata['oauth_token_id'] = oauth_token.id
|
||||||
|
metadata['oauth_token_application_id'] = oauth_token.application.client_id
|
||||||
|
metadata['oauth_token_application'] = oauth_token.application.name
|
||||||
|
|
||||||
performer = get_authenticated_user()
|
performer = get_authenticated_user()
|
||||||
model.log_action(kind, user_or_orgname, performer=performer, ip=request.remote_addr,
|
model.log_action(kind, user_or_orgname, performer=performer, ip=request.remote_addr,
|
||||||
metadata=metadata, repository=repo)
|
metadata=metadata, repository=repo)
|
||||||
|
|
|
@ -248,4 +248,22 @@ class OrganizationMember(ApiResource):
|
||||||
|
|
||||||
return {'member': member_dict}
|
return {'member': member_dict}
|
||||||
|
|
||||||
raise Unauthorized()
|
raise Unauthorized()
|
||||||
|
|
||||||
|
|
||||||
|
@resource('/v1/app/<client_id>')
|
||||||
|
class ApplicationInformation(ApiResource):
|
||||||
|
""" Resource that returns public information about a registered application. """
|
||||||
|
@nickname('getApplicationInformation')
|
||||||
|
def get(self, client_id):
|
||||||
|
""" Get information on the specified application. """
|
||||||
|
application = model.oauth.get_application_for_client_id(client_id)
|
||||||
|
if not application:
|
||||||
|
raise NotFound()
|
||||||
|
|
||||||
|
return {
|
||||||
|
'name': application.name,
|
||||||
|
'description': application.description,
|
||||||
|
'uri': application.application_uri,
|
||||||
|
'organization': org_view(application.organization, [])
|
||||||
|
}
|
||||||
|
|
4
static/directives/application-reference.html
Normal file
4
static/directives/application-reference.html
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<span class="application-reference-element">
|
||||||
|
<i class="fa fa-cloud"></i>
|
||||||
|
<a href="javascript:void(0)" ng-click="showAppDetails()">{{ title }}</a>
|
||||||
|
</span>
|
|
@ -42,7 +42,7 @@
|
||||||
<thead>
|
<thead>
|
||||||
<th>Description</th>
|
<th>Description</th>
|
||||||
<th style="min-width: 226px">Date/Time</th>
|
<th style="min-width: 226px">Date/Time</th>
|
||||||
<th>User/Token</th>
|
<th>User/Token/App</th>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
<tbody>
|
<tbody>
|
||||||
|
@ -53,14 +53,24 @@
|
||||||
</td>
|
</td>
|
||||||
<td>{{ log.datetime }}</td>
|
<td>{{ log.datetime }}</td>
|
||||||
<td>
|
<td>
|
||||||
<span class="log-performer" ng-show="log.performer">
|
<span class="log-performer" ng-if="log.metadata.oauth_token_application">
|
||||||
|
<div>
|
||||||
|
<span class="application-reference" title="log.metadata.oauth_token_application"
|
||||||
|
client-id="log.metadata.oauth_token_application_id"></span>
|
||||||
|
</div>
|
||||||
|
<div style="text-align: center; font-size: 12px; color: #aaa; padding: 4px;">on behalf of</div>
|
||||||
|
<div>
|
||||||
|
<span class="entity-reference" entity="log.performer" namespace="organization.name"></span>
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
<span class="log-performer" ng-if="!log.metadata.oauth_token_application && log.performer">
|
||||||
<span class="entity-reference" entity="log.performer" namespace="organization.name"></span>
|
<span class="entity-reference" entity="log.performer" namespace="organization.name"></span>
|
||||||
</span>
|
</span>
|
||||||
<span class="log-performer" ng-show="!log.performer && log.metadata.token">
|
<span class="log-performer" ng-if="!log.performer && log.metadata.token">
|
||||||
<i class="fa fa-key"></i>
|
<i class="fa fa-key"></i>
|
||||||
<span>{{ log.metadata.token }}</span>
|
<span>{{ log.metadata.token }}</span>
|
||||||
</span>
|
</span>
|
||||||
<span ng-show="!log.performer && !log.metadata.token">
|
<span ng-if="!log.performer && !log.metadata.token">
|
||||||
(anonymous)
|
(anonymous)
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
|
|
|
@ -921,6 +921,44 @@ quayApp.directive('entityReference', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
quayApp.directive('applicationReference', function () {
|
||||||
|
var directiveDefinitionObject = {
|
||||||
|
priority: 0,
|
||||||
|
templateUrl: '/static/directives/application-reference.html',
|
||||||
|
replace: false,
|
||||||
|
transclude: false,
|
||||||
|
restrict: 'C',
|
||||||
|
scope: {
|
||||||
|
'title': '=title',
|
||||||
|
'clientId': '=clientId'
|
||||||
|
},
|
||||||
|
controller: function($scope, $element, ApiService, $modal) {
|
||||||
|
$scope.showAppDetails = function() {
|
||||||
|
var params = {
|
||||||
|
'client_id': $scope.clientId
|
||||||
|
};
|
||||||
|
|
||||||
|
ApiService.getApplicationInformation(null, params).then(function(resp) {
|
||||||
|
// TODO: display the application information here.
|
||||||
|
}, function() {
|
||||||
|
bootbox.dialog({
|
||||||
|
"message": 'The application could not be found; it might have been deleted.',
|
||||||
|
"title": "Cannot find application",
|
||||||
|
"buttons": {
|
||||||
|
"close": {
|
||||||
|
"label": "Close",
|
||||||
|
"className": "btn-primary"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return directiveDefinitionObject;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
quayApp.directive('markdownView', function () {
|
quayApp.directive('markdownView', function () {
|
||||||
var directiveDefinitionObject = {
|
var directiveDefinitionObject = {
|
||||||
priority: 0,
|
priority: 0,
|
||||||
|
|
Reference in a new issue