Add some sort of oauth.
This commit is contained in:
parent
220649e579
commit
25ceb90fc6
13 changed files with 290 additions and 46 deletions
|
@ -14,6 +14,7 @@ from util.names import parse_namespace_repository
|
|||
from auth.permissions import (ReadRepositoryPermission,
|
||||
ModifyRepositoryPermission,
|
||||
AdministerRepositoryPermission)
|
||||
from auth import scopes
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
@ -100,8 +101,9 @@ class RepositoryParamResource(Resource):
|
|||
method_decorators = [parse_repository_name]
|
||||
|
||||
|
||||
def require_repo_permission(permission_class, allow_public=False):
|
||||
def require_repo_permission(permission_class, scope, allow_public=False):
|
||||
def wrapper(func):
|
||||
@add_method_metadata('oauth2_scope', scope)
|
||||
@wraps(func)
|
||||
def wrapped(self, namespace, repository, *args, **kwargs):
|
||||
permission = permission_class(namespace, repository)
|
||||
|
@ -114,9 +116,9 @@ def require_repo_permission(permission_class, allow_public=False):
|
|||
return wrapper
|
||||
|
||||
|
||||
require_repo_read = require_repo_permission(ReadRepositoryPermission, True)
|
||||
require_repo_write = require_repo_permission(ModifyRepositoryPermission)
|
||||
require_repo_admin = require_repo_permission(AdministerRepositoryPermission)
|
||||
require_repo_read = require_repo_permission(ReadRepositoryPermission, scopes.READ_REPO, True)
|
||||
require_repo_write = require_repo_permission(ModifyRepositoryPermission, scopes.WRITE_REPO)
|
||||
require_repo_admin = require_repo_permission(AdministerRepositoryPermission, scopes.ADMIN_REPO)
|
||||
|
||||
|
||||
def validate_json_request(schema_name):
|
||||
|
|
|
@ -5,6 +5,7 @@ from flask.ext.restful import Resource, reqparse
|
|||
|
||||
from endpoints.api import resource, method_metadata, nickname, truthy_bool
|
||||
from app import app
|
||||
from auth import scopes
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
@ -46,42 +47,50 @@ def swagger_route_data():
|
|||
'required': True,
|
||||
})
|
||||
|
||||
req_schema_name = method_metadata(method, 'request_schema')
|
||||
if req_schema_name:
|
||||
parameters.append({
|
||||
'paramType': 'body',
|
||||
'name': 'body',
|
||||
'description': 'Request body contents.',
|
||||
'dataType': req_schema_name,
|
||||
'required': True,
|
||||
})
|
||||
|
||||
schema = view_class.schemas[req_schema_name]
|
||||
models[req_schema_name] = schema
|
||||
|
||||
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:
|
||||
operations.append({
|
||||
req_schema_name = method_metadata(method, 'request_schema')
|
||||
if req_schema_name:
|
||||
parameters.append({
|
||||
'paramType': 'body',
|
||||
'name': 'body',
|
||||
'description': 'Request body contents.',
|
||||
'dataType': req_schema_name,
|
||||
'required': True,
|
||||
})
|
||||
|
||||
schema = view_class.schemas[req_schema_name]
|
||||
models[req_schema_name] = schema
|
||||
|
||||
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)
|
||||
|
||||
new_operation = {
|
||||
'method': method_name,
|
||||
'nickname': method_metadata(method, 'nickname'),
|
||||
'type': 'void',
|
||||
'summary': method.__doc__ if method.__doc__ else '',
|
||||
'parameters': parameters,
|
||||
})
|
||||
}
|
||||
|
||||
scope = method_metadata(method, 'oauth2_scope')
|
||||
if scope:
|
||||
new_operation['authorizations'] = {
|
||||
'oauth2': [scope]
|
||||
}
|
||||
|
||||
operations.append(new_operation)
|
||||
|
||||
swagger_path = PARAM_REGEX.sub(r'{\2}', rule.rule)
|
||||
apis.append({
|
||||
|
@ -103,6 +112,19 @@ def swagger_route_data():
|
|||
'termsOfServiceUrl': 'https://quay.io/tos',
|
||||
'contact': 'support@quay.io',
|
||||
},
|
||||
'authorizations': {
|
||||
'oauth2': {
|
||||
'scopes': list(scopes.ALL_SCOPES.values()),
|
||||
'grantTypes': {
|
||||
"implicit": {
|
||||
"tokenName": "access_token",
|
||||
"loginEndpoint": {
|
||||
"url": "http://ci.devtable.com:5000/oauth/authorize",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'apis': apis,
|
||||
'models': models,
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@ client = app.config['HTTPCLIENT']
|
|||
callback = Blueprint('callback', __name__)
|
||||
|
||||
|
||||
|
||||
def exchange_github_code_for_token(code):
|
||||
code = request.args.get('code')
|
||||
payload = {
|
||||
|
|
|
@ -8,6 +8,7 @@ from flask.ext.login import current_user
|
|||
from urlparse import urlparse
|
||||
|
||||
from data import model
|
||||
from data.model.oauth import DatabaseAuthorizationProvider
|
||||
from app import app
|
||||
from auth.permissions import AdministerOrganizationPermission
|
||||
from util.invoice import renderInvoiceToPdf
|
||||
|
@ -228,3 +229,26 @@ def build_status_badge(namespace, repository):
|
|||
response = make_response(STATUS_TAGS[status_name])
|
||||
response.content_type = 'image/svg+xml'
|
||||
return response
|
||||
|
||||
|
||||
class FlaskAuthorizationProvider(DatabaseAuthorizationProvider):
|
||||
def get_authorized_user(self):
|
||||
return current_user.db_user()
|
||||
|
||||
def _make_response(self, body='', headers=None, status_code=200):
|
||||
return make_response(body, status_code, headers)
|
||||
|
||||
|
||||
@web.route('/oauth/authorize', methods=['GET'])
|
||||
@no_cache
|
||||
def request_authorization_code():
|
||||
provider = FlaskAuthorizationProvider()
|
||||
response_type = request.args.get('response_type', 'code')
|
||||
client_id = request.args.get('client_id', None)
|
||||
redirect_uri = request.args.get('redirect_uri', None)
|
||||
scope = request.args.get('scope', None)
|
||||
|
||||
if response_type == 'token':
|
||||
return provider.get_token_response(response_type, client_id, redirect_uri, scope=scope)
|
||||
else:
|
||||
return provider.get_authorization_code(response_type, client_id, redirect_uri, scope=scope)
|
||||
|
|
Reference in a new issue