Holy black magic batman, move the query parameters to decorators and expose them through discovery.
This commit is contained in:
parent
b3e0dfae48
commit
978d68f0e0
5 changed files with 209 additions and 135 deletions
|
@ -9,7 +9,7 @@ application.config['LOGGING_CONFIG']()
|
||||||
# Turn off debug logging for boto
|
# Turn off debug logging for boto
|
||||||
logging.getLogger('boto').setLevel(logging.CRITICAL)
|
logging.getLogger('boto').setLevel(logging.CRITICAL)
|
||||||
|
|
||||||
from endpoints.api import api
|
from endpoints.api import api_bp
|
||||||
from endpoints.index import index
|
from endpoints.index import index
|
||||||
from endpoints.web import web
|
from endpoints.web import web
|
||||||
from endpoints.tags import tags
|
from endpoints.tags import tags
|
||||||
|
@ -26,7 +26,7 @@ application.register_blueprint(callback, url_prefix='/oauth2')
|
||||||
application.register_blueprint(index, url_prefix='/v1')
|
application.register_blueprint(index, url_prefix='/v1')
|
||||||
application.register_blueprint(tags, url_prefix='/v1')
|
application.register_blueprint(tags, url_prefix='/v1')
|
||||||
application.register_blueprint(registry, url_prefix='/v1')
|
application.register_blueprint(registry, url_prefix='/v1')
|
||||||
application.register_blueprint(api, url_prefix='/api')
|
application.register_blueprint(api_bp, url_prefix='/api')
|
||||||
application.register_blueprint(webhooks, url_prefix='/webhooks')
|
application.register_blueprint(webhooks, url_prefix='/webhooks')
|
||||||
application.register_blueprint(realtime, url_prefix='/realtime')
|
application.register_blueprint(realtime, url_prefix='/realtime')
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
|
import logging
|
||||||
|
|
||||||
from flask import Blueprint, request
|
from flask import Blueprint, request
|
||||||
from flask.ext.restful import Resource, abort
|
from flask.ext.restful import Resource, abort, Api, reqparse
|
||||||
|
from flask.ext.restful.utils.cors import crossdomain
|
||||||
from flask.ext.login import current_user
|
from flask.ext.login import current_user
|
||||||
from calendar import timegm
|
from calendar import timegm
|
||||||
from email.utils import formatdate
|
from email.utils import formatdate
|
||||||
|
@ -13,8 +16,17 @@ from auth.permissions import (ReadRepositoryPermission,
|
||||||
AdministerRepositoryPermission)
|
AdministerRepositoryPermission)
|
||||||
|
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
api_bp = Blueprint('api', __name__)
|
||||||
|
api = Api(api_bp)
|
||||||
|
api.decorators = [crossdomain(origin='*')]
|
||||||
|
|
||||||
api = Blueprint('api', __name__)
|
|
||||||
|
def resource(*urls, **kwargs):
|
||||||
|
def wrapper(api_resource):
|
||||||
|
api.add_resource(api_resource, *urls, **kwargs)
|
||||||
|
return api_resource
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
def truthy_bool(param):
|
def truthy_bool(param):
|
||||||
|
@ -44,6 +56,41 @@ def method_metadata(func, name):
|
||||||
nickname = partial(add_method_metadata, 'nickname')
|
nickname = partial(add_method_metadata, 'nickname')
|
||||||
|
|
||||||
|
|
||||||
|
def query_parameter(name, help_str, type=reqparse.text_type,
|
||||||
|
default=None, choices=(), required=False):
|
||||||
|
def add_param(func):
|
||||||
|
logger.debug('%s', func)
|
||||||
|
if '__api_query_params' not in dir(func):
|
||||||
|
func.__api_query_params = []
|
||||||
|
func.__api_query_params.append({
|
||||||
|
'name': name,
|
||||||
|
'type': type,
|
||||||
|
'help': help_str,
|
||||||
|
'default': default,
|
||||||
|
'choices': choices,
|
||||||
|
'required': required,
|
||||||
|
})
|
||||||
|
return func
|
||||||
|
return add_param
|
||||||
|
|
||||||
|
|
||||||
|
def parse_args(func):
|
||||||
|
@wraps(func)
|
||||||
|
def wrapper(self, *args, **kwargs):
|
||||||
|
if '__api_query_params' not in dir(func):
|
||||||
|
logger.debug('No query params defined.')
|
||||||
|
logger.debug('%s', func)
|
||||||
|
abort(400)
|
||||||
|
|
||||||
|
parser = reqparse.RequestParser()
|
||||||
|
for arg_spec in func.__api_query_params:
|
||||||
|
parser.add_argument(**arg_spec)
|
||||||
|
parsed_args = parser.parse_args()
|
||||||
|
|
||||||
|
return func(self, parsed_args, *args, **kwargs)
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
def parse_repository_name(func):
|
def parse_repository_name(func):
|
||||||
@wraps(func)
|
@wraps(func)
|
||||||
def wrapper(repository, *args, **kwargs):
|
def wrapper(repository, *args, **kwargs):
|
||||||
|
|
|
@ -1,17 +1,26 @@
|
||||||
import re
|
import re
|
||||||
|
import logging
|
||||||
|
|
||||||
from flask.ext.restful import Api, Resource
|
from flask.ext.restful import Resource, reqparse
|
||||||
from flask.ext.restful.utils.cors import crossdomain
|
|
||||||
|
|
||||||
from endpoints.api import api, method_metadata, nickname
|
from endpoints.api import resource, method_metadata, nickname, truthy_bool
|
||||||
from endpoints.common import get_route_data
|
|
||||||
from app import app
|
from app import app
|
||||||
|
|
||||||
|
|
||||||
discovery_api = Api(api)
|
logger = logging.getLogger(__name__)
|
||||||
discovery_api.decorators = [crossdomain(origin='*')]
|
|
||||||
|
|
||||||
|
PARAM_REGEX = re.compile(r'<([\w]+:)?([\w]+)>')
|
||||||
|
|
||||||
|
|
||||||
|
TYPE_CONVERTER = {
|
||||||
|
truthy_bool: 'boolean',
|
||||||
|
str: 'string',
|
||||||
|
basestring: 'string',
|
||||||
|
reqparse.text_type: 'string',
|
||||||
|
int: 'integer',
|
||||||
|
}
|
||||||
|
|
||||||
param_regex = re.compile(r'<([\w]+:)?([\w]+)>')
|
|
||||||
|
|
||||||
def swagger_route_data():
|
def swagger_route_data():
|
||||||
apis = []
|
apis = []
|
||||||
|
@ -49,6 +58,22 @@ def swagger_route_data():
|
||||||
schema = endpoint_method.view_class.schemas[req_schema_name]
|
schema = endpoint_method.view_class.schemas[req_schema_name]
|
||||||
models[req_schema_name] = schema
|
models[req_schema_name] = schema
|
||||||
|
|
||||||
|
logger.debug('method dir: %s', dir(method))
|
||||||
|
if '__api_query_params' in dir(method):
|
||||||
|
for param_spec in method.__api_query_params:
|
||||||
|
new_param = {
|
||||||
|
'paramType': 'query',
|
||||||
|
'name': param_spec['name'],
|
||||||
|
'description': param_spec['help'],
|
||||||
|
'dataType': TYPE_CONVERTER[param_spec['type']],
|
||||||
|
'required': param_spec['required'],
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(param_spec['choices']) > 0:
|
||||||
|
new_param['enum'] = list(param_spec['choices'])
|
||||||
|
|
||||||
|
parameters.append(new_param)
|
||||||
|
|
||||||
if method is not None:
|
if method is not None:
|
||||||
operations.append({
|
operations.append({
|
||||||
'method': method_name,
|
'method': method_name,
|
||||||
|
@ -57,7 +82,7 @@ def swagger_route_data():
|
||||||
'parameters': parameters,
|
'parameters': parameters,
|
||||||
})
|
})
|
||||||
|
|
||||||
swagger_path = param_regex.sub(r'{\2}', rule.rule)
|
swagger_path = PARAM_REGEX.sub(r'{\2}', rule.rule)
|
||||||
apis.append({
|
apis.append({
|
||||||
'path': swagger_path,
|
'path': swagger_path,
|
||||||
'description': 'Resource description.',
|
'description': 'Resource description.',
|
||||||
|
@ -67,18 +92,24 @@ def swagger_route_data():
|
||||||
swagger_data = {
|
swagger_data = {
|
||||||
'apiVersion': 'v1',
|
'apiVersion': 'v1',
|
||||||
'swaggerVersion': '1.2',
|
'swaggerVersion': '1.2',
|
||||||
'basePath': 'https://quay.io/',
|
'basePath': 'http://ci.devtable.com:5000',
|
||||||
'resourcePath': '/',
|
'resourcePath': '/',
|
||||||
|
'info': {
|
||||||
|
'title': 'Quay.io API',
|
||||||
|
'description': ('This API allows you to perform many of the operations '
|
||||||
|
'required to work with Quay.io repositories, users, and '
|
||||||
|
'organizations. You can find out more at '
|
||||||
|
'<a href="https://quay.io">Quay.io</a>.'),
|
||||||
|
'termsOfServiceUrl': 'https://quay.io/tos',
|
||||||
|
'contact': 'support@quay.io',
|
||||||
|
},
|
||||||
'apis': apis,
|
'apis': apis,
|
||||||
'models': models,
|
'models': models,
|
||||||
}
|
}
|
||||||
return swagger_data
|
return swagger_data
|
||||||
|
|
||||||
|
@resource('/v1/discovery')
|
||||||
class DiscoveryResource(Resource):
|
class DiscoveryResource(Resource):
|
||||||
@nickname('discovery')
|
@nickname('discovery')
|
||||||
def get(self):
|
def get(self):
|
||||||
return swagger_route_data()
|
return swagger_route_data()
|
||||||
|
|
||||||
|
|
||||||
discovery_api.add_resource(DiscoveryResource, '/v1/discovery')
|
|
|
@ -11,7 +11,7 @@ from functools import wraps
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from urllib import quote
|
from urllib import quote
|
||||||
|
|
||||||
from endpoints.api import api
|
from endpoints.api import api_bp
|
||||||
from data import model
|
from data import model
|
||||||
from data.plans import PLANS, get_plan
|
from data.plans import PLANS, get_plan
|
||||||
from app import app
|
from app import app
|
||||||
|
@ -43,7 +43,7 @@ build_logs = app.config['BUILDLOGS']
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@api.before_request
|
@api_bp.before_request
|
||||||
def csrf_protect():
|
def csrf_protect():
|
||||||
if request.method != "GET" and request.method != "HEAD":
|
if request.method != "GET" and request.method != "HEAD":
|
||||||
token = session.get('_csrf_token', None)
|
token = session.get('_csrf_token', None)
|
||||||
|
@ -111,18 +111,18 @@ def org_api_call(user_call_name):
|
||||||
return internal_decorator
|
return internal_decorator
|
||||||
|
|
||||||
|
|
||||||
@api.route('/discovery')
|
@api_bp.route('/discovery')
|
||||||
def discovery():
|
def discovery():
|
||||||
return jsonify(get_route_data())
|
return jsonify(get_route_data())
|
||||||
|
|
||||||
|
|
||||||
@api.route('/')
|
@api_bp.route('/')
|
||||||
@internal_api_call
|
@internal_api_call
|
||||||
def welcome():
|
def welcome():
|
||||||
return jsonify({'version': '0.5'})
|
return jsonify({'version': '0.5'})
|
||||||
|
|
||||||
|
|
||||||
@api.route('/plans/')
|
@api_bp.route('/plans/')
|
||||||
def list_plans():
|
def list_plans():
|
||||||
return jsonify({
|
return jsonify({
|
||||||
'plans': PLANS,
|
'plans': PLANS,
|
||||||
|
@ -165,7 +165,7 @@ def user_view(user):
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@api.route('/user/', methods=['GET'])
|
@api_bp.route('/user/', methods=['GET'])
|
||||||
@internal_api_call
|
@internal_api_call
|
||||||
def get_logged_in_user():
|
def get_logged_in_user():
|
||||||
if current_user.is_anonymous():
|
if current_user.is_anonymous():
|
||||||
|
@ -178,7 +178,7 @@ def get_logged_in_user():
|
||||||
return jsonify(user_view(user))
|
return jsonify(user_view(user))
|
||||||
|
|
||||||
|
|
||||||
@api.route('/user/private', methods=['GET'])
|
@api_bp.route('/user/private', methods=['GET'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@internal_api_call
|
@internal_api_call
|
||||||
def get_user_private_allowed():
|
def get_user_private_allowed():
|
||||||
|
@ -199,7 +199,7 @@ def get_user_private_allowed():
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@api.route('/user/convert', methods=['POST'])
|
@api_bp.route('/user/convert', methods=['POST'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@internal_api_call
|
@internal_api_call
|
||||||
def convert_user_to_organization():
|
def convert_user_to_organization():
|
||||||
|
@ -230,7 +230,7 @@ def convert_user_to_organization():
|
||||||
return conduct_signin(admin_username, admin_password)
|
return conduct_signin(admin_username, admin_password)
|
||||||
|
|
||||||
|
|
||||||
@api.route('/user/', methods=['PUT'])
|
@api_bp.route('/user/', methods=['PUT'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@internal_api_call
|
@internal_api_call
|
||||||
def change_user_details():
|
def change_user_details():
|
||||||
|
@ -264,7 +264,7 @@ def change_user_details():
|
||||||
return jsonify(user_view(user))
|
return jsonify(user_view(user))
|
||||||
|
|
||||||
|
|
||||||
@api.route('/user/', methods=['POST'])
|
@api_bp.route('/user/', methods=['POST'])
|
||||||
@internal_api_call
|
@internal_api_call
|
||||||
def create_new_user():
|
def create_new_user():
|
||||||
user_data = request.get_json()
|
user_data = request.get_json()
|
||||||
|
@ -283,7 +283,7 @@ def create_new_user():
|
||||||
return request_error(exception=ex)
|
return request_error(exception=ex)
|
||||||
|
|
||||||
|
|
||||||
@api.route('/signin', methods=['POST'])
|
@api_bp.route('/signin', methods=['POST'])
|
||||||
@internal_api_call
|
@internal_api_call
|
||||||
def signin_user():
|
def signin_user():
|
||||||
signin_data = request.get_json()
|
signin_data = request.get_json()
|
||||||
|
@ -318,7 +318,7 @@ def conduct_signin(username_or_email, password):
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
@api.route("/signout", methods=['POST'])
|
@api_bp.route("/signout", methods=['POST'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@internal_api_call
|
@internal_api_call
|
||||||
def logout():
|
def logout():
|
||||||
|
@ -327,7 +327,7 @@ def logout():
|
||||||
return jsonify({'success': True})
|
return jsonify({'success': True})
|
||||||
|
|
||||||
|
|
||||||
@api.route("/recovery", methods=['POST'])
|
@api_bp.route("/recovery", methods=['POST'])
|
||||||
@internal_api_call
|
@internal_api_call
|
||||||
def request_recovery_email():
|
def request_recovery_email():
|
||||||
email = request.get_json()['email']
|
email = request.get_json()['email']
|
||||||
|
@ -336,7 +336,7 @@ def request_recovery_email():
|
||||||
return make_response('Created', 201)
|
return make_response('Created', 201)
|
||||||
|
|
||||||
|
|
||||||
@api.route('/users/<prefix>', methods=['GET'])
|
@api_bp.route('/users/<prefix>', methods=['GET'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
def get_matching_users(prefix):
|
def get_matching_users(prefix):
|
||||||
users = model.get_matching_users(prefix)
|
users = model.get_matching_users(prefix)
|
||||||
|
@ -346,7 +346,7 @@ def get_matching_users(prefix):
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@api.route('/entities/<prefix>', methods=['GET'])
|
@api_bp.route('/entities/<prefix>', methods=['GET'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
def get_matching_entities(prefix):
|
def get_matching_entities(prefix):
|
||||||
teams = []
|
teams = []
|
||||||
|
@ -413,7 +413,7 @@ def team_view(orgname, team):
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@api.route('/organization/', methods=['POST'])
|
@api_bp.route('/organization/', methods=['POST'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@internal_api_call
|
@internal_api_call
|
||||||
def create_organization():
|
def create_organization():
|
||||||
|
@ -460,7 +460,7 @@ def org_view(o, teams):
|
||||||
return view
|
return view
|
||||||
|
|
||||||
|
|
||||||
@api.route('/organization/<orgname>', methods=['GET'])
|
@api_bp.route('/organization/<orgname>', methods=['GET'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
def get_organization(orgname):
|
def get_organization(orgname):
|
||||||
permission = OrganizationMemberPermission(orgname)
|
permission = OrganizationMemberPermission(orgname)
|
||||||
|
@ -476,7 +476,7 @@ def get_organization(orgname):
|
||||||
abort(403)
|
abort(403)
|
||||||
|
|
||||||
|
|
||||||
@api.route('/organization/<orgname>', methods=['PUT'])
|
@api_bp.route('/organization/<orgname>', methods=['PUT'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@org_api_call('change_user_details')
|
@org_api_call('change_user_details')
|
||||||
def change_organization_details(orgname):
|
def change_organization_details(orgname):
|
||||||
|
@ -529,7 +529,7 @@ def prototype_view(proto, org_members):
|
||||||
'id': proto.uuid,
|
'id': proto.uuid,
|
||||||
}
|
}
|
||||||
|
|
||||||
@api.route('/organization/<orgname>/prototypes', methods=['GET'])
|
@api_bp.route('/organization/<orgname>/prototypes', methods=['GET'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
def get_organization_prototype_permissions(orgname):
|
def get_organization_prototype_permissions(orgname):
|
||||||
permission = AdministerOrganizationPermission(orgname)
|
permission = AdministerOrganizationPermission(orgname)
|
||||||
|
@ -567,7 +567,7 @@ def log_prototype_action(action_kind, orgname, prototype, **kwargs):
|
||||||
log_action(action_kind, orgname, log_params)
|
log_action(action_kind, orgname, log_params)
|
||||||
|
|
||||||
|
|
||||||
@api.route('/organization/<orgname>/prototypes', methods=['POST'])
|
@api_bp.route('/organization/<orgname>/prototypes', methods=['POST'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
def create_organization_prototype_permission(orgname):
|
def create_organization_prototype_permission(orgname):
|
||||||
permission = AdministerOrganizationPermission(orgname)
|
permission = AdministerOrganizationPermission(orgname)
|
||||||
|
@ -615,7 +615,7 @@ def create_organization_prototype_permission(orgname):
|
||||||
abort(403)
|
abort(403)
|
||||||
|
|
||||||
|
|
||||||
@api.route('/organization/<orgname>/prototypes/<prototypeid>',
|
@api_bp.route('/organization/<orgname>/prototypes/<prototypeid>',
|
||||||
methods=['DELETE'])
|
methods=['DELETE'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
def delete_organization_prototype_permission(orgname, prototypeid):
|
def delete_organization_prototype_permission(orgname, prototypeid):
|
||||||
|
@ -637,7 +637,7 @@ def delete_organization_prototype_permission(orgname, prototypeid):
|
||||||
abort(403)
|
abort(403)
|
||||||
|
|
||||||
|
|
||||||
@api.route('/organization/<orgname>/prototypes/<prototypeid>',
|
@api_bp.route('/organization/<orgname>/prototypes/<prototypeid>',
|
||||||
methods=['PUT'])
|
methods=['PUT'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
def update_organization_prototype_permission(orgname, prototypeid):
|
def update_organization_prototype_permission(orgname, prototypeid):
|
||||||
|
@ -666,7 +666,7 @@ def update_organization_prototype_permission(orgname, prototypeid):
|
||||||
abort(403)
|
abort(403)
|
||||||
|
|
||||||
|
|
||||||
@api.route('/organization/<orgname>/members', methods=['GET'])
|
@api_bp.route('/organization/<orgname>/members', methods=['GET'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
def get_organization_members(orgname):
|
def get_organization_members(orgname):
|
||||||
permission = AdministerOrganizationPermission(orgname)
|
permission = AdministerOrganizationPermission(orgname)
|
||||||
|
@ -695,7 +695,7 @@ def get_organization_members(orgname):
|
||||||
abort(403)
|
abort(403)
|
||||||
|
|
||||||
|
|
||||||
@api.route('/organization/<orgname>/members/<membername>', methods=['GET'])
|
@api_bp.route('/organization/<orgname>/members/<membername>', methods=['GET'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
def get_organization_member(orgname, membername):
|
def get_organization_member(orgname, membername):
|
||||||
permission = AdministerOrganizationPermission(orgname)
|
permission = AdministerOrganizationPermission(orgname)
|
||||||
|
@ -724,7 +724,7 @@ def get_organization_member(orgname, membername):
|
||||||
abort(403)
|
abort(403)
|
||||||
|
|
||||||
|
|
||||||
@api.route('/organization/<orgname>/private', methods=['GET'])
|
@api_bp.route('/organization/<orgname>/private', methods=['GET'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@internal_api_call
|
@internal_api_call
|
||||||
@org_api_call('get_user_private_allowed')
|
@org_api_call('get_user_private_allowed')
|
||||||
|
@ -764,7 +764,7 @@ def member_view(member):
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@api.route('/organization/<orgname>/team/<teamname>',
|
@api_bp.route('/organization/<orgname>/team/<teamname>',
|
||||||
methods=['PUT', 'POST'])
|
methods=['PUT', 'POST'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
def update_organization_team(orgname, teamname):
|
def update_organization_team(orgname, teamname):
|
||||||
|
@ -810,7 +810,7 @@ def update_organization_team(orgname, teamname):
|
||||||
abort(403)
|
abort(403)
|
||||||
|
|
||||||
|
|
||||||
@api.route('/organization/<orgname>/team/<teamname>',
|
@api_bp.route('/organization/<orgname>/team/<teamname>',
|
||||||
methods=['DELETE'])
|
methods=['DELETE'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
def delete_organization_team(orgname, teamname):
|
def delete_organization_team(orgname, teamname):
|
||||||
|
@ -823,7 +823,7 @@ def delete_organization_team(orgname, teamname):
|
||||||
abort(403)
|
abort(403)
|
||||||
|
|
||||||
|
|
||||||
@api.route('/organization/<orgname>/team/<teamname>/members',
|
@api_bp.route('/organization/<orgname>/team/<teamname>/members',
|
||||||
methods=['GET'])
|
methods=['GET'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
def get_organization_team_members(orgname, teamname):
|
def get_organization_team_members(orgname, teamname):
|
||||||
|
@ -846,7 +846,7 @@ def get_organization_team_members(orgname, teamname):
|
||||||
abort(403)
|
abort(403)
|
||||||
|
|
||||||
|
|
||||||
@api.route('/organization/<orgname>/team/<teamname>/members/<membername>',
|
@api_bp.route('/organization/<orgname>/team/<teamname>/members/<membername>',
|
||||||
methods=['PUT', 'POST'])
|
methods=['PUT', 'POST'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
def update_organization_team_member(orgname, teamname, membername):
|
def update_organization_team_member(orgname, teamname, membername):
|
||||||
|
@ -875,7 +875,7 @@ def update_organization_team_member(orgname, teamname, membername):
|
||||||
abort(403)
|
abort(403)
|
||||||
|
|
||||||
|
|
||||||
@api.route('/organization/<orgname>/team/<teamname>/members/<membername>',
|
@api_bp.route('/organization/<orgname>/team/<teamname>/members/<membername>',
|
||||||
methods=['DELETE'])
|
methods=['DELETE'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
def delete_organization_team_member(orgname, teamname, membername):
|
def delete_organization_team_member(orgname, teamname, membername):
|
||||||
|
@ -891,7 +891,7 @@ def delete_organization_team_member(orgname, teamname, membername):
|
||||||
abort(403)
|
abort(403)
|
||||||
|
|
||||||
|
|
||||||
@api.route('/repository', methods=['POST'])
|
@api_bp.route('/repository', methods=['POST'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
def create_repo():
|
def create_repo():
|
||||||
owner = current_user.db_user()
|
owner = current_user.db_user()
|
||||||
|
@ -925,7 +925,7 @@ def create_repo():
|
||||||
abort(403)
|
abort(403)
|
||||||
|
|
||||||
|
|
||||||
@api.route('/find/repository', methods=['GET'])
|
@api_bp.route('/find/repository', methods=['GET'])
|
||||||
def find_repos():
|
def find_repos():
|
||||||
prefix = request.args.get('query', '')
|
prefix = request.args.get('query', '')
|
||||||
|
|
||||||
|
@ -948,7 +948,7 @@ def find_repos():
|
||||||
return jsonify(response)
|
return jsonify(response)
|
||||||
|
|
||||||
|
|
||||||
@api.route('/repository/', methods=['GET'])
|
@api_bp.route('/repository/', methods=['GET'])
|
||||||
def list_repos():
|
def list_repos():
|
||||||
def repo_view(repo_obj):
|
def repo_view(repo_obj):
|
||||||
return {
|
return {
|
||||||
|
@ -1003,7 +1003,7 @@ def list_repos():
|
||||||
return jsonify(response)
|
return jsonify(response)
|
||||||
|
|
||||||
|
|
||||||
@api.route('/repository/<path:repository>', methods=['PUT'])
|
@api_bp.route('/repository/<path:repository>', methods=['PUT'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@parse_repository_name
|
@parse_repository_name
|
||||||
def update_repo(namespace, repository):
|
def update_repo(namespace, repository):
|
||||||
|
@ -1025,7 +1025,7 @@ def update_repo(namespace, repository):
|
||||||
abort(403)
|
abort(403)
|
||||||
|
|
||||||
|
|
||||||
@api.route('/repository/<path:repository>/changevisibility',
|
@api_bp.route('/repository/<path:repository>/changevisibility',
|
||||||
methods=['POST'])
|
methods=['POST'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@parse_repository_name
|
@parse_repository_name
|
||||||
|
@ -1046,7 +1046,7 @@ def change_repo_visibility(namespace, repository):
|
||||||
abort(403)
|
abort(403)
|
||||||
|
|
||||||
|
|
||||||
@api.route('/repository/<path:repository>', methods=['DELETE'])
|
@api_bp.route('/repository/<path:repository>', methods=['DELETE'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@parse_repository_name
|
@parse_repository_name
|
||||||
def delete_repository(namespace, repository):
|
def delete_repository(namespace, repository):
|
||||||
|
@ -1077,7 +1077,7 @@ def image_view(image):
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@api.route('/repository/<path:repository>', methods=['GET'])
|
@api_bp.route('/repository/<path:repository>', methods=['GET'])
|
||||||
@parse_repository_name
|
@parse_repository_name
|
||||||
def get_repo(namespace, repository):
|
def get_repo(namespace, repository):
|
||||||
logger.debug('Get repo: %s/%s' % (namespace, repository))
|
logger.debug('Get repo: %s/%s' % (namespace, repository))
|
||||||
|
@ -1159,7 +1159,7 @@ def build_status_view(build_obj, can_write=False):
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@api.route('/repository/<path:repository>/build/', methods=['GET'])
|
@api_bp.route('/repository/<path:repository>/build/', methods=['GET'])
|
||||||
@parse_repository_name
|
@parse_repository_name
|
||||||
def get_repo_builds(namespace, repository):
|
def get_repo_builds(namespace, repository):
|
||||||
permission = ReadRepositoryPermission(namespace, repository)
|
permission = ReadRepositoryPermission(namespace, repository)
|
||||||
|
@ -1176,7 +1176,7 @@ def get_repo_builds(namespace, repository):
|
||||||
abort(403) # Permission denied
|
abort(403) # Permission denied
|
||||||
|
|
||||||
|
|
||||||
@api.route('/repository/<path:repository>/build/<build_uuid>/status',
|
@api_bp.route('/repository/<path:repository>/build/<build_uuid>/status',
|
||||||
methods=['GET'])
|
methods=['GET'])
|
||||||
@parse_repository_name
|
@parse_repository_name
|
||||||
def get_repo_build_status(namespace, repository, build_uuid):
|
def get_repo_build_status(namespace, repository, build_uuid):
|
||||||
|
@ -1193,7 +1193,7 @@ def get_repo_build_status(namespace, repository, build_uuid):
|
||||||
abort(403) # Permission denied
|
abort(403) # Permission denied
|
||||||
|
|
||||||
|
|
||||||
@api.route('/repository/<path:repository>/build/<build_uuid>/archiveurl',
|
@api_bp.route('/repository/<path:repository>/build/<build_uuid>/archiveurl',
|
||||||
methods=['GET'])
|
methods=['GET'])
|
||||||
@parse_repository_name
|
@parse_repository_name
|
||||||
def get_repo_build_archive_url(namespace, repository, build_uuid):
|
def get_repo_build_archive_url(namespace, repository, build_uuid):
|
||||||
|
@ -1211,7 +1211,7 @@ def get_repo_build_archive_url(namespace, repository, build_uuid):
|
||||||
abort(403) # Permission denied
|
abort(403) # Permission denied
|
||||||
|
|
||||||
|
|
||||||
@api.route('/repository/<path:repository>/build/<build_uuid>/logs',
|
@api_bp.route('/repository/<path:repository>/build/<build_uuid>/logs',
|
||||||
methods=['GET'])
|
methods=['GET'])
|
||||||
@parse_repository_name
|
@parse_repository_name
|
||||||
def get_repo_build_logs(namespace, repository, build_uuid):
|
def get_repo_build_logs(namespace, repository, build_uuid):
|
||||||
|
@ -1236,7 +1236,7 @@ def get_repo_build_logs(namespace, repository, build_uuid):
|
||||||
abort(403) # Permission denied
|
abort(403) # Permission denied
|
||||||
|
|
||||||
|
|
||||||
@api.route('/repository/<path:repository>/build/', methods=['POST'])
|
@api_bp.route('/repository/<path:repository>/build/', methods=['POST'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@parse_repository_name
|
@parse_repository_name
|
||||||
def request_repo_build(namespace, repository):
|
def request_repo_build(namespace, repository):
|
||||||
|
@ -1266,7 +1266,7 @@ def request_repo_build(namespace, repository):
|
||||||
|
|
||||||
resp = jsonify(build_status_view(build_request, True))
|
resp = jsonify(build_status_view(build_request, True))
|
||||||
repo_string = '%s/%s' % (namespace, repository)
|
repo_string = '%s/%s' % (namespace, repository)
|
||||||
resp.headers['Location'] = url_for('api.get_repo_build_status',
|
resp.headers['Location'] = url_for('api_bp.get_repo_build_status',
|
||||||
repository=repo_string,
|
repository=repo_string,
|
||||||
build_uuid=build_request.uuid)
|
build_uuid=build_request.uuid)
|
||||||
resp.status_code = 201
|
resp.status_code = 201
|
||||||
|
@ -1282,7 +1282,7 @@ def webhook_view(webhook):
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@api.route('/repository/<path:repository>/webhook/', methods=['POST'])
|
@api_bp.route('/repository/<path:repository>/webhook/', methods=['POST'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@parse_repository_name
|
@parse_repository_name
|
||||||
def create_webhook(namespace, repository):
|
def create_webhook(namespace, repository):
|
||||||
|
@ -1292,7 +1292,7 @@ def create_webhook(namespace, repository):
|
||||||
webhook = model.create_webhook(repo, request.get_json())
|
webhook = model.create_webhook(repo, request.get_json())
|
||||||
resp = jsonify(webhook_view(webhook))
|
resp = jsonify(webhook_view(webhook))
|
||||||
repo_string = '%s/%s' % (namespace, repository)
|
repo_string = '%s/%s' % (namespace, repository)
|
||||||
resp.headers['Location'] = url_for('api.get_webhook',
|
resp.headers['Location'] = url_for('api_bp.get_webhook',
|
||||||
repository=repo_string,
|
repository=repo_string,
|
||||||
public_id=webhook.public_id)
|
public_id=webhook.public_id)
|
||||||
log_action('add_repo_webhook', namespace,
|
log_action('add_repo_webhook', namespace,
|
||||||
|
@ -1303,7 +1303,7 @@ def create_webhook(namespace, repository):
|
||||||
abort(403) # Permissions denied
|
abort(403) # Permissions denied
|
||||||
|
|
||||||
|
|
||||||
@api.route('/repository/<path:repository>/webhook/<public_id>',
|
@api_bp.route('/repository/<path:repository>/webhook/<public_id>',
|
||||||
methods=['GET'])
|
methods=['GET'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@parse_repository_name
|
@parse_repository_name
|
||||||
|
@ -1320,7 +1320,7 @@ def get_webhook(namespace, repository, public_id):
|
||||||
abort(403) # Permission denied
|
abort(403) # Permission denied
|
||||||
|
|
||||||
|
|
||||||
@api.route('/repository/<path:repository>/webhook/', methods=['GET'])
|
@api_bp.route('/repository/<path:repository>/webhook/', methods=['GET'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@parse_repository_name
|
@parse_repository_name
|
||||||
def list_webhooks(namespace, repository):
|
def list_webhooks(namespace, repository):
|
||||||
|
@ -1334,7 +1334,7 @@ def list_webhooks(namespace, repository):
|
||||||
abort(403) # Permission denied
|
abort(403) # Permission denied
|
||||||
|
|
||||||
|
|
||||||
@api.route('/repository/<path:repository>/webhook/<public_id>',
|
@api_bp.route('/repository/<path:repository>/webhook/<public_id>',
|
||||||
methods=['DELETE'])
|
methods=['DELETE'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@parse_repository_name
|
@parse_repository_name
|
||||||
|
@ -1350,7 +1350,7 @@ def delete_webhook(namespace, repository, public_id):
|
||||||
abort(403) # Permission denied
|
abort(403) # Permission denied
|
||||||
|
|
||||||
|
|
||||||
@api.route('/repository/<path:repository>/trigger/<trigger_uuid>',
|
@api_bp.route('/repository/<path:repository>/trigger/<trigger_uuid>',
|
||||||
methods=['GET'])
|
methods=['GET'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@parse_repository_name
|
@parse_repository_name
|
||||||
|
@ -1372,7 +1372,7 @@ def _prepare_webhook_url(scheme, username, password, hostname, path):
|
||||||
return urlparse.urlunparse((scheme, auth_hostname, path, '', '', ''))
|
return urlparse.urlunparse((scheme, auth_hostname, path, '', '', ''))
|
||||||
|
|
||||||
|
|
||||||
@api.route('/repository/<path:repository>/trigger/<trigger_uuid>/subdir',
|
@api_bp.route('/repository/<path:repository>/trigger/<trigger_uuid>/subdir',
|
||||||
methods=['POST'])
|
methods=['POST'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@parse_repository_name
|
@parse_repository_name
|
||||||
|
@ -1405,7 +1405,7 @@ def list_build_trigger_subdirs(namespace, repository, trigger_uuid):
|
||||||
abort(403) # Permission denied
|
abort(403) # Permission denied
|
||||||
|
|
||||||
|
|
||||||
@api.route('/repository/<path:repository>/trigger/<trigger_uuid>/activate',
|
@api_bp.route('/repository/<path:repository>/trigger/<trigger_uuid>/activate',
|
||||||
methods=['POST'])
|
methods=['POST'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@parse_repository_name
|
@parse_repository_name
|
||||||
|
@ -1464,7 +1464,7 @@ def activate_build_trigger(namespace, repository, trigger_uuid):
|
||||||
abort(403) # Permission denied
|
abort(403) # Permission denied
|
||||||
|
|
||||||
|
|
||||||
@api.route('/repository/<path:repository>/trigger/<trigger_uuid>/start',
|
@api_bp.route('/repository/<path:repository>/trigger/<trigger_uuid>/start',
|
||||||
methods=['POST'])
|
methods=['POST'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@parse_repository_name
|
@parse_repository_name
|
||||||
|
@ -1493,7 +1493,7 @@ def manually_start_build_trigger(namespace, repository, trigger_uuid):
|
||||||
|
|
||||||
resp = jsonify(build_status_view(build_request, True))
|
resp = jsonify(build_status_view(build_request, True))
|
||||||
repo_string = '%s/%s' % (namespace, repository)
|
repo_string = '%s/%s' % (namespace, repository)
|
||||||
resp.headers['Location'] = url_for('api.get_repo_build_status',
|
resp.headers['Location'] = url_for('api_bp.get_repo_build_status',
|
||||||
repository=repo_string,
|
repository=repo_string,
|
||||||
build_uuid=build_request.uuid)
|
build_uuid=build_request.uuid)
|
||||||
resp.status_code = 201
|
resp.status_code = 201
|
||||||
|
@ -1502,7 +1502,7 @@ def manually_start_build_trigger(namespace, repository, trigger_uuid):
|
||||||
abort(403) # Permission denied
|
abort(403) # Permission denied
|
||||||
|
|
||||||
|
|
||||||
@api.route('/repository/<path:repository>/trigger/<trigger_uuid>/builds',
|
@api_bp.route('/repository/<path:repository>/trigger/<trigger_uuid>/builds',
|
||||||
methods=['GET'])
|
methods=['GET'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@parse_repository_name
|
@parse_repository_name
|
||||||
|
@ -1519,7 +1519,7 @@ def list_trigger_recent_builds(namespace, repository, trigger_uuid):
|
||||||
abort(403) # Permission denied
|
abort(403) # Permission denied
|
||||||
|
|
||||||
|
|
||||||
@api.route('/repository/<path:repository>/trigger/<trigger_uuid>/sources',
|
@api_bp.route('/repository/<path:repository>/trigger/<trigger_uuid>/sources',
|
||||||
methods=['GET'])
|
methods=['GET'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@parse_repository_name
|
@parse_repository_name
|
||||||
|
@ -1543,7 +1543,7 @@ def list_trigger_build_sources(namespace, repository, trigger_uuid):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@api.route('/repository/<path:repository>/trigger/', methods=['GET'])
|
@api_bp.route('/repository/<path:repository>/trigger/', methods=['GET'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@parse_repository_name
|
@parse_repository_name
|
||||||
def list_build_triggers(namespace, repository):
|
def list_build_triggers(namespace, repository):
|
||||||
|
@ -1557,7 +1557,7 @@ def list_build_triggers(namespace, repository):
|
||||||
abort(403) # Permission denied
|
abort(403) # Permission denied
|
||||||
|
|
||||||
|
|
||||||
@api.route('/repository/<path:repository>/trigger/<trigger_uuid>',
|
@api_bp.route('/repository/<path:repository>/trigger/<trigger_uuid>',
|
||||||
methods=['DELETE'])
|
methods=['DELETE'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@parse_repository_name
|
@parse_repository_name
|
||||||
|
@ -1590,7 +1590,7 @@ def delete_build_trigger(namespace, repository, trigger_uuid):
|
||||||
abort(403) # Permission denied
|
abort(403) # Permission denied
|
||||||
|
|
||||||
|
|
||||||
@api.route('/filedrop/', methods=['POST'])
|
@api_bp.route('/filedrop/', methods=['POST'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@internal_api_call
|
@internal_api_call
|
||||||
def get_filedrop_url():
|
def get_filedrop_url():
|
||||||
|
@ -1617,7 +1617,7 @@ def wrap_role_view_org(role_json, user, org_members):
|
||||||
return role_json
|
return role_json
|
||||||
|
|
||||||
|
|
||||||
@api.route('/repository/<path:repository>/image/', methods=['GET'])
|
@api_bp.route('/repository/<path:repository>/image/', methods=['GET'])
|
||||||
@parse_repository_name
|
@parse_repository_name
|
||||||
def list_repository_images(namespace, repository):
|
def list_repository_images(namespace, repository):
|
||||||
permission = ReadRepositoryPermission(namespace, repository)
|
permission = ReadRepositoryPermission(namespace, repository)
|
||||||
|
@ -1642,7 +1642,7 @@ def list_repository_images(namespace, repository):
|
||||||
abort(403)
|
abort(403)
|
||||||
|
|
||||||
|
|
||||||
@api.route('/repository/<path:repository>/image/<image_id>',
|
@api_bp.route('/repository/<path:repository>/image/<image_id>',
|
||||||
methods=['GET'])
|
methods=['GET'])
|
||||||
@parse_repository_name
|
@parse_repository_name
|
||||||
def get_image(namespace, repository, image_id):
|
def get_image(namespace, repository, image_id):
|
||||||
|
@ -1656,7 +1656,7 @@ def get_image(namespace, repository, image_id):
|
||||||
abort(403)
|
abort(403)
|
||||||
|
|
||||||
|
|
||||||
@api.route('/repository/<path:repository>/image/<image_id>/changes',
|
@api_bp.route('/repository/<path:repository>/image/<image_id>/changes',
|
||||||
methods=['GET'])
|
methods=['GET'])
|
||||||
@cache_control(max_age=60*60) # Cache for one hour
|
@cache_control(max_age=60*60) # Cache for one hour
|
||||||
@parse_repository_name
|
@parse_repository_name
|
||||||
|
@ -1681,7 +1681,7 @@ def get_image_changes(namespace, repository, image_id):
|
||||||
abort(403)
|
abort(403)
|
||||||
|
|
||||||
|
|
||||||
@api.route('/repository/<path:repository>/tag/<tag>',
|
@api_bp.route('/repository/<path:repository>/tag/<tag>',
|
||||||
methods=['DELETE'])
|
methods=['DELETE'])
|
||||||
@parse_repository_name
|
@parse_repository_name
|
||||||
def delete_full_tag(namespace, repository, tag):
|
def delete_full_tag(namespace, repository, tag):
|
||||||
|
@ -1700,7 +1700,7 @@ def delete_full_tag(namespace, repository, tag):
|
||||||
abort(403) # Permission denied
|
abort(403) # Permission denied
|
||||||
|
|
||||||
|
|
||||||
@api.route('/repository/<path:repository>/tag/<tag>/images',
|
@api_bp.route('/repository/<path:repository>/tag/<tag>/images',
|
||||||
methods=['GET'])
|
methods=['GET'])
|
||||||
@parse_repository_name
|
@parse_repository_name
|
||||||
def list_tag_images(namespace, repository, tag):
|
def list_tag_images(namespace, repository, tag):
|
||||||
|
@ -1724,7 +1724,7 @@ def list_tag_images(namespace, repository, tag):
|
||||||
abort(403) # Permission denied
|
abort(403) # Permission denied
|
||||||
|
|
||||||
|
|
||||||
@api.route('/repository/<path:repository>/permissions/team/',
|
@api_bp.route('/repository/<path:repository>/permissions/team/',
|
||||||
methods=['GET'])
|
methods=['GET'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@parse_repository_name
|
@parse_repository_name
|
||||||
|
@ -1741,7 +1741,7 @@ def list_repo_team_permissions(namespace, repository):
|
||||||
abort(403) # Permission denied
|
abort(403) # Permission denied
|
||||||
|
|
||||||
|
|
||||||
@api.route('/repository/<path:repository>/permissions/user/',
|
@api_bp.route('/repository/<path:repository>/permissions/user/',
|
||||||
methods=['GET'])
|
methods=['GET'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@parse_repository_name
|
@parse_repository_name
|
||||||
|
@ -1782,7 +1782,7 @@ def list_repo_user_permissions(namespace, repository):
|
||||||
abort(403) # Permission denied
|
abort(403) # Permission denied
|
||||||
|
|
||||||
|
|
||||||
@api.route('/repository/<path:repository>/permissions/user/<username>',
|
@api_bp.route('/repository/<path:repository>/permissions/user/<username>',
|
||||||
methods=['GET'])
|
methods=['GET'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@parse_repository_name
|
@parse_repository_name
|
||||||
|
@ -1807,7 +1807,7 @@ def get_user_permissions(namespace, repository, username):
|
||||||
abort(403) # Permission denied
|
abort(403) # Permission denied
|
||||||
|
|
||||||
|
|
||||||
@api.route('/repository/<path:repository>/permissions/team/<teamname>',
|
@api_bp.route('/repository/<path:repository>/permissions/team/<teamname>',
|
||||||
methods=['GET'])
|
methods=['GET'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@parse_repository_name
|
@parse_repository_name
|
||||||
|
@ -1822,7 +1822,7 @@ def get_team_permissions(namespace, repository, teamname):
|
||||||
abort(403) # Permission denied
|
abort(403) # Permission denied
|
||||||
|
|
||||||
|
|
||||||
@api.route('/repository/<path:repository>/permissions/user/<username>',
|
@api_bp.route('/repository/<path:repository>/permissions/user/<username>',
|
||||||
methods=['PUT', 'POST'])
|
methods=['PUT', 'POST'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@parse_repository_name
|
@parse_repository_name
|
||||||
|
@ -1861,7 +1861,7 @@ def change_user_permissions(namespace, repository, username):
|
||||||
abort(403) # Permission denied
|
abort(403) # Permission denied
|
||||||
|
|
||||||
|
|
||||||
@api.route('/repository/<path:repository>/permissions/team/<teamname>',
|
@api_bp.route('/repository/<path:repository>/permissions/team/<teamname>',
|
||||||
methods=['PUT', 'POST'])
|
methods=['PUT', 'POST'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@parse_repository_name
|
@parse_repository_name
|
||||||
|
@ -1889,7 +1889,7 @@ def change_team_permissions(namespace, repository, teamname):
|
||||||
abort(403) # Permission denied
|
abort(403) # Permission denied
|
||||||
|
|
||||||
|
|
||||||
@api.route('/repository/<path:repository>/permissions/user/<username>',
|
@api_bp.route('/repository/<path:repository>/permissions/user/<username>',
|
||||||
methods=['DELETE'])
|
methods=['DELETE'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@parse_repository_name
|
@parse_repository_name
|
||||||
|
@ -1910,7 +1910,7 @@ def delete_user_permissions(namespace, repository, username):
|
||||||
abort(403) # Permission denied
|
abort(403) # Permission denied
|
||||||
|
|
||||||
|
|
||||||
@api.route('/repository/<path:repository>/permissions/team/<teamname>',
|
@api_bp.route('/repository/<path:repository>/permissions/team/<teamname>',
|
||||||
methods=['DELETE'])
|
methods=['DELETE'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@parse_repository_name
|
@parse_repository_name
|
||||||
|
@ -1936,7 +1936,7 @@ def token_view(token_obj):
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@api.route('/repository/<path:repository>/tokens/', methods=['GET'])
|
@api_bp.route('/repository/<path:repository>/tokens/', methods=['GET'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@parse_repository_name
|
@parse_repository_name
|
||||||
def list_repo_tokens(namespace, repository):
|
def list_repo_tokens(namespace, repository):
|
||||||
|
@ -1951,7 +1951,7 @@ def list_repo_tokens(namespace, repository):
|
||||||
abort(403) # Permission denied
|
abort(403) # Permission denied
|
||||||
|
|
||||||
|
|
||||||
@api.route('/repository/<path:repository>/tokens/<code>', methods=['GET'])
|
@api_bp.route('/repository/<path:repository>/tokens/<code>', methods=['GET'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@parse_repository_name
|
@parse_repository_name
|
||||||
def get_tokens(namespace, repository, code):
|
def get_tokens(namespace, repository, code):
|
||||||
|
@ -1967,7 +1967,7 @@ def get_tokens(namespace, repository, code):
|
||||||
abort(403) # Permission denied
|
abort(403) # Permission denied
|
||||||
|
|
||||||
|
|
||||||
@api.route('/repository/<path:repository>/tokens/', methods=['POST'])
|
@api_bp.route('/repository/<path:repository>/tokens/', methods=['POST'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@parse_repository_name
|
@parse_repository_name
|
||||||
def create_token(namespace, repository):
|
def create_token(namespace, repository):
|
||||||
|
@ -1989,7 +1989,7 @@ def create_token(namespace, repository):
|
||||||
abort(403) # Permission denied
|
abort(403) # Permission denied
|
||||||
|
|
||||||
|
|
||||||
@api.route('/repository/<path:repository>/tokens/<code>', methods=['PUT'])
|
@api_bp.route('/repository/<path:repository>/tokens/<code>', methods=['PUT'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@parse_repository_name
|
@parse_repository_name
|
||||||
def change_token(namespace, repository, code):
|
def change_token(namespace, repository, code):
|
||||||
|
@ -2014,7 +2014,7 @@ def change_token(namespace, repository, code):
|
||||||
abort(403) # Permission denied
|
abort(403) # Permission denied
|
||||||
|
|
||||||
|
|
||||||
@api.route('/repository/<path:repository>/tokens/<code>',
|
@api_bp.route('/repository/<path:repository>/tokens/<code>',
|
||||||
methods=['DELETE'])
|
methods=['DELETE'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@parse_repository_name
|
@parse_repository_name
|
||||||
|
@ -2042,7 +2042,7 @@ def subscription_view(stripe_subscription, used_repos):
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@api.route('/user/card', methods=['GET'])
|
@api_bp.route('/user/card', methods=['GET'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@internal_api_call
|
@internal_api_call
|
||||||
def get_user_card():
|
def get_user_card():
|
||||||
|
@ -2050,7 +2050,7 @@ def get_user_card():
|
||||||
return get_card(user)
|
return get_card(user)
|
||||||
|
|
||||||
|
|
||||||
@api.route('/organization/<orgname>/card', methods=['GET'])
|
@api_bp.route('/organization/<orgname>/card', methods=['GET'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@internal_api_call
|
@internal_api_call
|
||||||
@org_api_call('get_user_card')
|
@org_api_call('get_user_card')
|
||||||
|
@ -2063,7 +2063,7 @@ def get_org_card(orgname):
|
||||||
abort(403)
|
abort(403)
|
||||||
|
|
||||||
|
|
||||||
@api.route('/user/card', methods=['POST'])
|
@api_bp.route('/user/card', methods=['POST'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@internal_api_call
|
@internal_api_call
|
||||||
def set_user_card():
|
def set_user_card():
|
||||||
|
@ -2074,7 +2074,7 @@ def set_user_card():
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
@api.route('/organization/<orgname>/card', methods=['POST'])
|
@api_bp.route('/organization/<orgname>/card', methods=['POST'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@org_api_call('set_user_card')
|
@org_api_call('set_user_card')
|
||||||
def set_org_card(orgname):
|
def set_org_card(orgname):
|
||||||
|
@ -2128,7 +2128,7 @@ def get_card(user):
|
||||||
|
|
||||||
return jsonify({'card': card_info})
|
return jsonify({'card': card_info})
|
||||||
|
|
||||||
@api.route('/user/plan', methods=['PUT'])
|
@api_bp.route('/user/plan', methods=['PUT'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@internal_api_call
|
@internal_api_call
|
||||||
def update_user_subscription():
|
def update_user_subscription():
|
||||||
|
@ -2221,7 +2221,7 @@ def subscribe(user, plan, token, require_business_plan):
|
||||||
return resp
|
return resp
|
||||||
|
|
||||||
|
|
||||||
@api.route('/user/invoices', methods=['GET'])
|
@api_bp.route('/user/invoices', methods=['GET'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
def list_user_invoices():
|
def list_user_invoices():
|
||||||
user = current_user.db_user()
|
user = current_user.db_user()
|
||||||
|
@ -2231,7 +2231,7 @@ def list_user_invoices():
|
||||||
return get_invoices(user.stripe_id)
|
return get_invoices(user.stripe_id)
|
||||||
|
|
||||||
|
|
||||||
@api.route('/organization/<orgname>/invoices', methods=['GET'])
|
@api_bp.route('/organization/<orgname>/invoices', methods=['GET'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@org_api_call('list_user_invoices')
|
@org_api_call('list_user_invoices')
|
||||||
def list_org_invoices(orgname):
|
def list_org_invoices(orgname):
|
||||||
|
@ -2268,7 +2268,7 @@ def get_invoices(customer_id):
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@api.route('/organization/<orgname>/plan', methods=['PUT'])
|
@api_bp.route('/organization/<orgname>/plan', methods=['PUT'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@internal_api_call
|
@internal_api_call
|
||||||
@org_api_call('update_user_subscription')
|
@org_api_call('update_user_subscription')
|
||||||
|
@ -2284,7 +2284,7 @@ def update_org_subscription(orgname):
|
||||||
abort(403)
|
abort(403)
|
||||||
|
|
||||||
|
|
||||||
@api.route('/user/plan', methods=['GET'])
|
@api_bp.route('/user/plan', methods=['GET'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@internal_api_call
|
@internal_api_call
|
||||||
def get_user_subscription():
|
def get_user_subscription():
|
||||||
|
@ -2303,7 +2303,7 @@ def get_user_subscription():
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@api.route('/organization/<orgname>/plan', methods=['GET'])
|
@api_bp.route('/organization/<orgname>/plan', methods=['GET'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@internal_api_call
|
@internal_api_call
|
||||||
@org_api_call('get_user_subscription')
|
@org_api_call('get_user_subscription')
|
||||||
|
@ -2333,7 +2333,7 @@ def robot_view(name, token):
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@api.route('/user/robots', methods=['GET'])
|
@api_bp.route('/user/robots', methods=['GET'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
def get_user_robots():
|
def get_user_robots():
|
||||||
user = current_user.db_user()
|
user = current_user.db_user()
|
||||||
|
@ -2343,7 +2343,7 @@ def get_user_robots():
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@api.route('/organization/<orgname>/robots', methods=['GET'])
|
@api_bp.route('/organization/<orgname>/robots', methods=['GET'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@org_api_call('get_user_robots')
|
@org_api_call('get_user_robots')
|
||||||
def get_org_robots(orgname):
|
def get_org_robots(orgname):
|
||||||
|
@ -2357,7 +2357,7 @@ def get_org_robots(orgname):
|
||||||
abort(403)
|
abort(403)
|
||||||
|
|
||||||
|
|
||||||
@api.route('/user/robots/<robot_shortname>', methods=['PUT'])
|
@api_bp.route('/user/robots/<robot_shortname>', methods=['PUT'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
def create_user_robot(robot_shortname):
|
def create_user_robot(robot_shortname):
|
||||||
parent = current_user.db_user()
|
parent = current_user.db_user()
|
||||||
|
@ -2368,7 +2368,7 @@ def create_user_robot(robot_shortname):
|
||||||
return resp
|
return resp
|
||||||
|
|
||||||
|
|
||||||
@api.route('/organization/<orgname>/robots/<robot_shortname>',
|
@api_bp.route('/organization/<orgname>/robots/<robot_shortname>',
|
||||||
methods=['PUT'])
|
methods=['PUT'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@org_api_call('create_user_robot')
|
@org_api_call('create_user_robot')
|
||||||
|
@ -2385,7 +2385,7 @@ def create_org_robot(orgname, robot_shortname):
|
||||||
abort(403)
|
abort(403)
|
||||||
|
|
||||||
|
|
||||||
@api.route('/user/robots/<robot_shortname>', methods=['DELETE'])
|
@api_bp.route('/user/robots/<robot_shortname>', methods=['DELETE'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
def delete_user_robot(robot_shortname):
|
def delete_user_robot(robot_shortname):
|
||||||
parent = current_user.db_user()
|
parent = current_user.db_user()
|
||||||
|
@ -2394,7 +2394,7 @@ def delete_user_robot(robot_shortname):
|
||||||
return make_response('Deleted', 204)
|
return make_response('Deleted', 204)
|
||||||
|
|
||||||
|
|
||||||
@api.route('/organization/<orgname>/robots/<robot_shortname>',
|
@api_bp.route('/organization/<orgname>/robots/<robot_shortname>',
|
||||||
methods=['DELETE'])
|
methods=['DELETE'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@org_api_call('delete_user_robot')
|
@org_api_call('delete_user_robot')
|
||||||
|
@ -2427,7 +2427,7 @@ def log_view(log):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@api.route('/repository/<path:repository>/logs', methods=['GET'])
|
@api_bp.route('/repository/<path:repository>/logs', methods=['GET'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@parse_repository_name
|
@parse_repository_name
|
||||||
def list_repo_logs(namespace, repository):
|
def list_repo_logs(namespace, repository):
|
||||||
|
@ -2444,7 +2444,7 @@ def list_repo_logs(namespace, repository):
|
||||||
abort(403)
|
abort(403)
|
||||||
|
|
||||||
|
|
||||||
@api.route('/organization/<orgname>/logs', methods=['GET'])
|
@api_bp.route('/organization/<orgname>/logs', methods=['GET'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
@org_api_call('list_user_logs')
|
@org_api_call('list_user_logs')
|
||||||
def list_org_logs(orgname):
|
def list_org_logs(orgname):
|
||||||
|
@ -2460,7 +2460,7 @@ def list_org_logs(orgname):
|
||||||
abort(403)
|
abort(403)
|
||||||
|
|
||||||
|
|
||||||
@api.route('/user/logs', methods=['GET'])
|
@api_bp.route('/user/logs', methods=['GET'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
def list_user_logs():
|
def list_user_logs():
|
||||||
performer_name = request.args.get('performer', None)
|
performer_name = request.args.get('performer', None)
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
import logging
|
import logging
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from flask.ext.restful import Resource, Api, reqparse, abort
|
from flask.ext.restful import Resource, reqparse, abort
|
||||||
from flask.ext.login import current_user
|
from flask.ext.login import current_user
|
||||||
|
|
||||||
from data import model
|
from data import model
|
||||||
from endpoints.api import (api, truthy_bool, format_date, nickname, log_action,
|
from endpoints.api import (truthy_bool, format_date, nickname, log_action,
|
||||||
validate_json_request, require_repo_read,
|
validate_json_request, require_repo_read,
|
||||||
RepositoryParamResource)
|
RepositoryParamResource, resource, query_parameter,
|
||||||
|
parse_args)
|
||||||
from auth.permissions import (ReadRepositoryPermission,
|
from auth.permissions import (ReadRepositoryPermission,
|
||||||
ModifyRepositoryPermission,
|
ModifyRepositoryPermission,
|
||||||
AdministerRepositoryPermission)
|
AdministerRepositoryPermission)
|
||||||
|
@ -15,15 +16,6 @@ from auth.permissions import (ReadRepositoryPermission,
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
repo_api = Api(api)
|
|
||||||
|
|
||||||
|
|
||||||
def resource(*urls, **kwargs):
|
|
||||||
def wrapper(api_resource):
|
|
||||||
repo_api.add_resource(api_resource, *urls, **kwargs)
|
|
||||||
return api_resource
|
|
||||||
return wrapper
|
|
||||||
|
|
||||||
|
|
||||||
@resource('/v1/repository')
|
@resource('/v1/repository')
|
||||||
class RepositoryList(Resource):
|
class RepositoryList(Resource):
|
||||||
|
@ -97,17 +89,21 @@ class RepositoryList(Resource):
|
||||||
abort(403)
|
abort(403)
|
||||||
|
|
||||||
@nickname('listRepos')
|
@nickname('listRepos')
|
||||||
def get(self):
|
@parse_args
|
||||||
parser = reqparse.RequestParser()
|
@query_parameter('page', 'Offset page number. (int)', type=int)
|
||||||
parser.add_argument('page', type=int, help='Page number must be an int.')
|
@query_parameter('limit', 'Limit on the number of results (int)', type=int)
|
||||||
parser.add_argument('limit', type=int, help='Limit must be an int.')
|
@query_parameter('namespace', ('Namespace to use when querying for org '
|
||||||
parser.add_argument('namespace', type=str)
|
'repositories.'), type=str)
|
||||||
parser.add_argument('public', type=truthy_bool, default=True)
|
@query_parameter('public', 'Whether to include public repositories.',
|
||||||
parser.add_argument('private', type=truthy_bool, default=True)
|
type=truthy_bool, default=True)
|
||||||
parser.add_argument('sort', type=truthy_bool, default=False)
|
@query_parameter('private', 'Whether to inlcude private repositories.',
|
||||||
parser.add_argument('count', type=truthy_bool, default=False)
|
type=truthy_bool, default=True)
|
||||||
args = parser.parse_args()
|
@query_parameter('sort', 'Whether to sort the results.', type=truthy_bool,
|
||||||
|
default=False)
|
||||||
|
@query_parameter('count', ('Whether to include a count of the total number '
|
||||||
|
'of results available.'), type=truthy_bool,
|
||||||
|
default=False)
|
||||||
|
def get(self, args):
|
||||||
def repo_view(repo_obj):
|
def repo_view(repo_obj):
|
||||||
return {
|
return {
|
||||||
'namespace': repo_obj.namespace,
|
'namespace': repo_obj.namespace,
|
||||||
|
|
Reference in a new issue