More fully replicate the swagger API.
This commit is contained in:
parent
de1a44f853
commit
b3e0dfae48
3 changed files with 157 additions and 43 deletions
|
@ -1,34 +1,23 @@
|
|||
import logging
|
||||
import json
|
||||
|
||||
from functools import wraps
|
||||
from flask.ext.restful import Resource, Api, reqparse, abort, fields
|
||||
from flask.ext.restful import Resource, Api, reqparse, abort
|
||||
from flask.ext.login import current_user
|
||||
|
||||
from data import model
|
||||
from endpoints.api import api, truthy_bool, format_date, nickname
|
||||
from util.names import parse_namespace_repository
|
||||
from endpoints.api import (api, truthy_bool, format_date, nickname, log_action,
|
||||
validate_json_request, require_repo_read,
|
||||
RepositoryParamResource)
|
||||
from auth.permissions import (ReadRepositoryPermission,
|
||||
ModifyRepositoryPermission,
|
||||
AdministerRepositoryPermission)
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
repo_api = Api(api)
|
||||
|
||||
|
||||
def parse_repository_name(f):
|
||||
@wraps(f)
|
||||
def wrapper(repository, *args, **kwargs):
|
||||
(namespace, repository) = parse_namespace_repository(repository)
|
||||
return f(namespace, repository, *args, **kwargs)
|
||||
return wrapper
|
||||
|
||||
|
||||
class RepositoryParamResource(Resource):
|
||||
method_decorators = [parse_repository_name]
|
||||
|
||||
|
||||
def resource(*urls, **kwargs):
|
||||
def wrapper(api_resource):
|
||||
repo_api.add_resource(api_resource, *urls, **kwargs)
|
||||
|
@ -36,32 +25,76 @@ def resource(*urls, **kwargs):
|
|||
return wrapper
|
||||
|
||||
|
||||
def require_repo_permission(permission_class, allow_public=False):
|
||||
def wrapper(func):
|
||||
@wraps(func)
|
||||
def wrapped(self, namespace, repository, *args, **kwargs):
|
||||
permission = permission_class(namespace, repository)
|
||||
if (permission.can() or
|
||||
(allow_public and
|
||||
model.repository_is_public(namespace, repository))):
|
||||
return func(self, namespace, repository, *args, **kwargs)
|
||||
abort(403)
|
||||
func.__required_permission = 'read'
|
||||
return wrapped
|
||||
return wrapper
|
||||
|
||||
|
||||
require_repo_read = require_repo_permission(ReadRepositoryPermission, True)
|
||||
require_repo_write = require_repo_permission(ModifyRepositoryPermission)
|
||||
require_repo_admin = require_repo_permission(AdministerRepositoryPermission)
|
||||
|
||||
|
||||
@resource('/v1/repository')
|
||||
class RepositoryList(Resource):
|
||||
schemas = {
|
||||
'NewRepo': {
|
||||
'id': 'NewRepo',
|
||||
'type': 'object',
|
||||
'description': 'Description of a new repository.',
|
||||
'required': [
|
||||
'repository',
|
||||
'visibility',
|
||||
],
|
||||
'properties': {
|
||||
'repository': {
|
||||
'type': 'string',
|
||||
'description': 'Repository name.',
|
||||
},
|
||||
'visibility': {
|
||||
'type': 'string',
|
||||
'description': 'Visibility which the repository will start with.',
|
||||
'enum': [
|
||||
'public',
|
||||
'private',
|
||||
]
|
||||
},
|
||||
'namespace': {
|
||||
'type': 'string',
|
||||
'description': ('Namespace in which the repository should be '
|
||||
'created. If omitted, the username of the caller is'
|
||||
'used.'),
|
||||
},
|
||||
'description': {
|
||||
'type': 'string',
|
||||
'description': 'Markdown encoded description for the repository.',
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@nickname('createRepo')
|
||||
@validate_json_request('NewRepo')
|
||||
def post(self):
|
||||
pass
|
||||
owner = current_user.db_user()
|
||||
req = request.get_json()
|
||||
namespace_name = req['namespace'] if 'namespace' in req else owner.username
|
||||
|
||||
permission = CreateRepositoryPermission(namespace_name)
|
||||
if permission.can():
|
||||
repository_name = req['repository']
|
||||
visibility = req['visibility']
|
||||
|
||||
existing = model.get_repository(namespace_name, repository_name)
|
||||
if existing:
|
||||
return request_error(message='Repository already exists')
|
||||
|
||||
visibility = req['visibility']
|
||||
|
||||
repo = model.create_repository(namespace_name, repository_name, owner,
|
||||
visibility)
|
||||
repo.description = req['description']
|
||||
repo.save()
|
||||
|
||||
log_action('create_repo', namespace_name,
|
||||
{'repo': repository_name, 'namespace': namespace_name},
|
||||
repo=repo)
|
||||
return jsonify({
|
||||
'namespace': namespace_name,
|
||||
'name': repository_name
|
||||
})
|
||||
|
||||
abort(403)
|
||||
|
||||
@nickname('listRepos')
|
||||
def get(self):
|
||||
|
|
Reference in a new issue