More fully replicate the swagger API.

This commit is contained in:
jakedt 2014-03-10 23:54:55 -04:00
parent de1a44f853
commit b3e0dfae48
3 changed files with 157 additions and 43 deletions

View file

@ -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):