Add ID-based pagination to logs using new decorators and an encrypted token

Fixes #599
This commit is contained in:
Joseph Schorr 2015-12-22 09:05:17 -05:00
parent af77b92bcf
commit bd0a098282
8 changed files with 110 additions and 36 deletions

View file

@ -8,15 +8,14 @@ from dateutil.relativedelta import relativedelta
from endpoints.api import (resource, nickname, ApiResource, query_param, parse_args,
RepositoryParamResource, require_repo_admin, related_user_resource,
format_date, Unauthorized, NotFound, require_user_admin,
internal_only, path_param, require_scope)
internal_only, path_param, require_scope, page_support)
from auth.permissions import AdministerOrganizationPermission, AdministerOrganizationPermission
from auth.auth_context import get_authenticated_user
from data import model
from data import model, database
from auth import scopes
from app import avatar
LOGS_PER_PAGE = 50
MAX_PAGES = 20
LOGS_PER_PAGE = 20
def log_view(log, kinds):
view = {
@ -79,20 +78,22 @@ def _validate_logs_arguments(start_time, end_time, performer_name):
return (start_time, end_time, performer)
def get_logs(start_time, end_time, performer_name=None, repository=None, namespace=None, page=None):
def get_logs(start_time, end_time, performer_name=None, repository=None, namespace=None,
page_token=None):
(start_time, end_time, performer) = _validate_logs_arguments(start_time, end_time, performer_name)
page = min(MAX_PAGES, page if page else 1)
kinds = model.log.get_log_entry_kinds()
logs = model.log.list_logs(start_time, end_time, performer=performer, repository=repository,
namespace=namespace, page=page, count=LOGS_PER_PAGE + 1)
logs_query = model.log.get_logs_query(start_time, end_time, performer=performer,
repository=repository, namespace=namespace)
logs, next_page_token = model.modelutil.paginate(logs_query, database.LogEntry, descending=True,
page_token=page_token, limit=LOGS_PER_PAGE)
return {
'start_time': format_date(start_time),
'end_time': format_date(end_time),
'logs': [log_view(log, kinds) for log in logs[0:LOGS_PER_PAGE]],
'page': page,
'has_additional': len(logs) > LOGS_PER_PAGE,
}
'logs': [log_view(log, kinds) for log in logs],
}, next_page_token
def get_aggregate_logs(start_time, end_time, performer_name=None, repository=None, namespace=None):
(start_time, end_time, performer) = _validate_logs_arguments(start_time, end_time, performer_name)
@ -116,7 +117,8 @@ class RepositoryLogs(RepositoryParamResource):
@query_param('starttime', 'Earliest time from which to get logs (%m/%d/%Y %Z)', type=str)
@query_param('endtime', 'Latest time to which to get logs (%m/%d/%Y %Z)', type=str)
@query_param('page', 'The page number for the logs', type=int, default=1)
def get(self, args, namespace, repository):
@page_support
def get(self, args, page_token, namespace, repository):
""" List the logs for the specified repository. """
repo = model.repository.get_repository(namespace, repository)
if not repo:
@ -124,7 +126,7 @@ class RepositoryLogs(RepositoryParamResource):
start_time = args['starttime']
end_time = args['endtime']
return get_logs(start_time, end_time, repository=repo, page=args['page'])
return get_logs(start_time, end_time, repository=repo, page_token=page_token)
@resource('/v1/user/logs')
@ -137,8 +139,8 @@ class UserLogs(ApiResource):
@query_param('starttime', 'Earliest time from which to get logs. (%m/%d/%Y %Z)', type=str)
@query_param('endtime', 'Latest time to which to get logs. (%m/%d/%Y %Z)', type=str)
@query_param('performer', 'Username for which to filter logs.', type=str)
@query_param('page', 'The page number for the logs', type=int, default=1)
def get(self, args):
@page_support
def get(self, args, page_token):
""" List the logs for the current user. """
performer_name = args['performer']
start_time = args['starttime']
@ -146,7 +148,7 @@ class UserLogs(ApiResource):
user = get_authenticated_user()
return get_logs(start_time, end_time, performer_name=performer_name, namespace=user.username,
page=args['page'])
page_token=page_token)
@resource('/v1/organization/<orgname>/logs')
@ -160,8 +162,9 @@ class OrgLogs(ApiResource):
@query_param('endtime', 'Latest time to which to get logs. (%m/%d/%Y %Z)', type=str)
@query_param('performer', 'Username for which to filter logs.', type=str)
@query_param('page', 'The page number for the logs', type=int, default=1)
@page_support
@require_scope(scopes.ORG_ADMIN)
def get(self, args, orgname):
def get(self, args, page_token, orgname):
""" List the logs for the specified organization. """
permission = AdministerOrganizationPermission(orgname)
if permission.can():
@ -170,7 +173,7 @@ class OrgLogs(ApiResource):
end_time = args['endtime']
return get_logs(start_time, end_time, namespace=orgname, performer_name=performer_name,
page=args['page'])
page_token=page_token)
raise Unauthorized()