Beispiel #1
0
        def wrapped(*args, **kwargs):

            auth_header = request.headers.get('Authorization', '')
            m = re.match(r'Key (\S+)', auth_header)
            param = m.group(1) if m else request.args.get('api-key', None)

            if param:
                key = ApiKey.verify_key(param)
                if not key:
                    raise ApiError("API key parameter '%s' is invalid" % param, 401)
                g.user = key.user
                g.customer = key.customer
                g.scopes = key.scopes

                if not Permission.is_in_scope(scope, g.scopes):
                    raise ApiError('Missing required scope: %s' % scope, 403)
                else:
                    return f(*args, **kwargs)

            auth_header = request.headers.get('Authorization', '')
            m = re.match(r'Bearer (\S+)', auth_header)
            token = m.group(1) if m else None

            if token:
                try:
                    jwt = Jwt.parse(token)
                except DecodeError:
                    raise ApiError('Token is invalid', 401)
                except ExpiredSignature:
                    raise ApiError('Token has expired', 401)
                except InvalidAudience:
                    raise ApiError('Invalid audience', 401)
                g.user = jwt.preferred_username
                g.customer = jwt.customer
                g.scopes = jwt.scopes

                if not Permission.is_in_scope(scope, g.scopes):
                    raise ApiError("Missing required scope: %s" % scope, 403)
                else:
                    return f(*args, **kwargs)

            if not current_app.config['AUTH_REQUIRED']:
                g.user = None
                g.customer = None
                g.scopes = []
                return f(*args, **kwargs)

            # Google App Engine Cron Service
            if request.headers.get('X-Appengine-Cron', False) and request.headers.get('X-Forwarded-For', '') == '0.1.0.1':
                return f(*args, **kwargs)

            raise ApiError('Missing authorization API Key or Bearer Token', 401)
Beispiel #2
0
def create_key():
    try:
        key = ApiKey.parse(request.json)
    except ValueError as e:
        raise ApiError(str(e), 400)

    if 'admin' in g.scopes or 'admin:keys' in g.scopes:
        key.user = key.user or g.user
        key.customer = key.customer or g.get('customer', None)
    else:
        key.user = g.user
        key.customer = g.get('customer', None)

    if not key.user:
        raise ApiError("Must set 'user' to create API key", 400)

    for want_scope in key.scopes:
        if not Permission.is_in_scope(want_scope, g.scopes):
            raise ApiError("Requested scope '%s' not in existing scopes: %s" % (want_scope, ','.join(g.scopes)), 403)

    try:
        key = key.create()
    except Exception as e:
        raise ApiError(str(e), 500)

    if key:
        return jsonify(status="ok", key=key.key, data=key.serialize), 201
    else:
        raise ApiError("create API key failed", 500)
Beispiel #3
0
def create_key():
    try:
        key = ApiKey.parse(request.json)
    except ValueError as e:
        raise ApiError(str(e), 400)

    if 'admin' in g.scopes or 'admin:keys' in g.scopes:
        key.user = key.user or g.user
        key.customer = key.customer or g.get('customer', None)
    else:
        key.user = g.user
        key.customer = g.get('customer', None)

    if not key.user:
        raise ApiError(
            "An API key must be associated with a 'user'. Retry with user credentials.",
            400)

    for want_scope in key.scopes:
        if not Permission.is_in_scope(want_scope, g.scopes):
            raise ApiError(
                "Requested scope '%s' not in existing scopes: %s" %
                (want_scope, ','.join(g.scopes)), 403)

    try:
        key = key.create()
    except Exception as e:
        raise ApiError(str(e), 500)

    if key:
        return jsonify(status="ok", key=key.key, data=key.serialize), 201
    else:
        raise ApiError("create API key failed", 500)
Beispiel #4
0
def update_key(key):
    if not request.json:
        raise ApiError('nothing to change', 400)

    if not current_app.config['AUTH_REQUIRED']:
        key = ApiKey.find_by_id(key)
    elif Scope.admin in g.scopes or Scope.admin_keys in g.scopes:
        key = ApiKey.find_by_id(key)
    else:
        key = ApiKey.find_by_id(key, user=g.login)

    if not key:
        raise ApiError('not found', 404)

    update = request.json
    update['customer'] = assign_customer(wanted=update.get('customer'), permission=Scope.admin_keys)

    for want_scope in update.get('scopes', []):
        if not Permission.is_in_scope(want_scope, have_scopes=g.scopes):
            raise ApiError("Requested scope '{}' not in existing scopes: {}".format(
                want_scope, ','.join(g.scopes)), 403)

    admin_audit_trail.send(current_app._get_current_object(), event='apikey-updated', message='', user=g.login,
                           customers=g.customers, scopes=g.scopes, resource_id=key.id, type='apikey', request=request)

    if key.update(**request.json):
        return jsonify(status='ok')
    else:
        raise ApiError('failed to update API key', 500)
Beispiel #5
0
def create_perm():
    try:
        perm = Permission.parse(request.json)
    except ValueError as e:
        raise ApiError(str(e), 400)

    if perm.match in ['admin', 'user']:
        raise ApiError('{} role already exists'.format(perm.match), 409)

    for want_scope in perm.scopes:
        if not Permission.is_in_scope(want_scope, have_scopes=g.scopes):
            raise ApiError("Requested scope '{}' not in existing scopes: {}".format(
                want_scope, ','.join(g.scopes)), 403)

    try:
        perm = perm.create()
    except Exception as e:
        raise ApiError(str(e), 500)

    admin_audit_trail.send(current_app._get_current_object(), event='permission-created', message='', user=g.user,
                           customers=g.customers, scopes=g.scopes, resource_id=perm.id, type='permission', request=request)

    if perm:
        return jsonify(status='ok', id=perm.id, permission=perm.serialize), 201
    else:
        raise ApiError('create API key failed', 500)
Beispiel #6
0
def update_user(user_id):
    if not request.json:
        raise ApiError('nothing to change', 400)

    user = User.find_by_id(user_id)

    if not user:
        raise ApiError('not found', 404)

    if request.json.get('email'):
        user_by_email = User.find_by_email(request.json['email'])
        if user_by_email and user_by_email.id != user.id:
            raise ApiError('user with that email already exists', 409)

    if request.json.get('roles'):
        want_scopes = Permission.lookup(login='', roles=request.json['roles'])
        for want_scope in want_scopes:
            if not Permission.is_in_scope(want_scope, have_scopes=g.scopes):
                raise ApiError("Requested scope '{}' not in existing scopes: {}".format(
                    want_scope, ','.join(g.scopes)), 403)

    admin_audit_trail.send(current_app._get_current_object(), event='user-updated', message='', user=g.login,
                           customers=g.customers, scopes=g.scopes, resource_id=user.id, type='user', request=request)

    if user.update(**request.json):
        return jsonify(status='ok')
    else:
        raise ApiError('failed to update user', 500)
Beispiel #7
0
def update_user(user_id):
    if not request.json:
        raise ApiError('nothing to change', 400)

    user = User.find_by_id(user_id)

    if not user:
        raise ApiError('not found', 404)

    if request.json.get('email'):
        user_by_email = User.find_by_email(request.json['email'])
        if user_by_email and user_by_email.id != user.id:
            raise ApiError('user with that email already exists', 409)

    if request.json.get('roles'):
        want_scopes = Permission.lookup(login='', roles=request.json['roles'])
        for want_scope in want_scopes:
            if not Permission.is_in_scope(want_scope, have_scopes=g.scopes):
                raise ApiError("Requested scope '{}' not in existing scopes: {}".format(
                    want_scope, ','.join(g.scopes)), 403)

    updated = user.update(**request.json)

    admin_audit_trail.send(current_app._get_current_object(), event='user-updated', message='', user=g.login,
                           customers=g.customers, scopes=g.scopes, resource_id=user.id, type='user', request=request)

    if updated:
        return jsonify(status='ok', user=updated.serialize)
    else:
        raise ApiError('failed to update user', 500)
Beispiel #8
0
def create_key():
    try:
        key = ApiKey.parse(request.json)
    except ValueError as e:
        raise ApiError(str(e), 400)

    if Scope.admin in g.scopes or Scope.admin_keys in g.scopes:
        key.user = key.user or g.login
    else:
        key.user = g.login

    key.customer = assign_customer(wanted=key.customer, permission=Scope.admin_keys)

    if not key.user:
        raise ApiError("An API key must be associated with a 'user'. Retry with user credentials.", 400)

    for want_scope in key.scopes:
        if not Permission.is_in_scope(want_scope, have_scopes=g.scopes):
            raise ApiError("Requested scope '{}' not in existing scopes: {}".format(
                want_scope, ','.join(g.scopes)), 403)

    try:
        key = key.create()
    except Exception as e:
        raise ApiError(str(e), 500)

    write_audit_trail.send(current_app._get_current_object(), event='apikey-created', message='', user=g.login,
                           customers=g.customers, scopes=g.scopes, resource_id=key.id, type='apikey', request=request)

    if key:
        return jsonify(status='ok', key=key.key, data=key.serialize), 201
    else:
        raise ApiError('create API key failed', 500)
Beispiel #9
0
def create_perm():
    try:
        perm = Permission.parse(request.json)
    except ValueError as e:
        raise ApiError(str(e), 400)

    if perm.match in ['admin', 'user']:
        raise ApiError('{} role already exists'.format(perm.match), 409)

    for want_scope in perm.scopes:
        if not Permission.is_in_scope(want_scope, have_scopes=g.scopes):
            raise ApiError("Requested scope '{}' not in existing scopes: {}".format(
                want_scope, ','.join(g.scopes)), 403)

    try:
        perm = perm.create()
    except Exception as e:
        raise ApiError(str(e), 500)

    admin_audit_trail.send(current_app._get_current_object(), event='permission-created', message='', user=g.login,
                           customers=g.customers, scopes=g.scopes, resource_id=perm.id, type='permission', request=request)

    if perm:
        return jsonify(status='ok', id=perm.id, permission=perm.serialize), 201
    else:
        raise ApiError('create API key failed', 500)
Beispiel #10
0
def create_user():
    if current_app.config['AUTH_PROVIDER'] != 'basic':
        raise ApiError(
            'must use {} login flow to create new user'.format(
                current_app.config['AUTH_PROVIDER']), 400)

    try:
        user = User.parse(request.json)
    except Exception as e:
        raise ApiError(str(e), 400)

    # check allowed domain
    if not_authorized('ALLOWED_EMAIL_DOMAINS', groups=[user.domain]):
        raise ApiError('unauthorized domain', 403)

    if User.find_by_username(username=user.email):
        raise ApiError('user with that email already exists', 409)

    want_scopes = Permission.lookup(login=user.email, roles=user.roles)
    for want_scope in want_scopes:
        if not Permission.is_in_scope(want_scope, have_scopes=g.scopes):
            raise ApiError(
                "Requested scope '{}' not in existing scopes: {}".format(
                    want_scope, ','.join(g.scopes)), 403)

    try:
        user = user.create()
    except Exception as e:
        ApiError(str(e), 500)

    # if email verification is enforced, send confirmation email
    if current_app.config['EMAIL_VERIFICATION'] and not user.email_verified:
        user.send_confirmation()

    admin_audit_trail.send(current_app._get_current_object(),
                           event='user-created',
                           message='',
                           user=g.login,
                           customers=g.customers,
                           scopes=g.scopes,
                           resource_id=user.id,
                           type='user',
                           request=request)

    if user:
        return jsonify(status='ok', id=user.id, user=user.serialize), 201
    else:
        raise ApiError('create user failed', 500)
Beispiel #11
0
def create_key():
    try:
        key = ApiKey.parse(request.json)
    except ValueError as e:
        raise ApiError(str(e), 400)

    if Scope.admin in g.scopes or Scope.admin_keys in g.scopes:
        key.user = key.user or g.login
    else:
        key.user = g.login

    key.customer = assign_customer(wanted=key.customer,
                                   permission=Scope.admin_keys)

    if not key.user:
        raise ApiError(
            "An API key must be associated with a 'user'. Retry with user credentials.",
            400)

    for want_scope in key.scopes:
        if not Permission.is_in_scope(want_scope, have_scopes=g.scopes):
            raise ApiError(
                "Requested scope '{}' not in existing scopes: {}".format(
                    want_scope, ','.join(g.scopes)), 403)

    try:
        key = key.create()
    except Exception as e:
        raise ApiError(str(e), 500)

    write_audit_trail.send(current_app._get_current_object(),
                           event='apikey-created',
                           message='',
                           user=g.login,
                           customers=g.customers,
                           scopes=g.scopes,
                           resource_id=key.id,
                           type='apikey',
                           request=request)

    if key:
        return jsonify(status='ok', key=key.key, data=key.serialize), 201
    else:
        raise ApiError('create API key failed', 500)
Beispiel #12
0
def create_perm():
    try:
        perm = Permission.parse(request.json)
    except ValueError as e:
        raise ApiError(str(e), 400)

    for want_scope in perm.scopes:
        if not Permission.is_in_scope(want_scope, g.scopes):
            raise ApiError("Requested scope '%s' not in existing scopes: %s" % (want_scope, ','.join(g.scopes)), 403)

    try:
        perm = perm.create()
    except Exception as e:
        raise ApiError(str(e), 500)

    if perm:
        return jsonify(status="ok", id=perm.id, permission=perm.serialize), 201
    else:
        raise ApiError("create API key failed", 500)
Beispiel #13
0
def create_perm():
    try:
        perm = Permission.parse(request.json)
    except ValueError as e:
        raise ApiError(str(e), 400)

    for want_scope in perm.scopes:
        if not Permission.is_in_scope(want_scope, g.scopes):
            raise ApiError("Requested scope '%s' not in existing scopes: %s" % (want_scope, ','.join(g.scopes)), 403)

    try:
        perm = perm.create()
    except Exception as e:
        raise ApiError(str(e), 500)

    if perm:
        return jsonify(status="ok", id=perm.id, permission=perm.serialize), 201
    else:
        raise ApiError("create API key failed", 500)
Beispiel #14
0
def create_user():
    if current_app.config['AUTH_PROVIDER'] != 'basic':
        raise ApiError(
            'must use {} login flow to create new user'.format(current_app.config['AUTH_PROVIDER']), 400)

    try:
        user = User.parse(request.json)
    except Exception as e:
        raise ApiError(str(e), 400)

    # check allowed domain
    if not_authorized('ALLOWED_EMAIL_DOMAINS', groups=[user.domain]):
        raise ApiError('unauthorized domain', 403)

    if User.find_by_username(username=user.email):
        raise ApiError('user with that email already exists', 409)

    want_scopes = Permission.lookup(login=user.email, roles=user.roles)
    for want_scope in want_scopes:
        if not Permission.is_in_scope(want_scope, have_scopes=g.scopes):
            raise ApiError("Requested scope '{}' not in existing scopes: {}".format(
                want_scope, ','.join(g.scopes)), 403)

    try:
        user = user.create()
    except Exception as e:
        ApiError(str(e), 500)

    # if email verification is enforced, send confirmation email
    if current_app.config['EMAIL_VERIFICATION'] and not user.email_verified:
        user.send_confirmation()

    admin_audit_trail.send(current_app._get_current_object(), event='user-created', message='', user=g.login,
                           customers=g.customers, scopes=g.scopes, resource_id=user.id, type='user', request=request)

    if user:
        return jsonify(status='ok', id=user.id, user=user.serialize), 201
    else:
        raise ApiError('create user failed', 500)
Beispiel #15
0
def update_key(key):
    if not request.json:
        raise ApiError('nothing to change', 400)

    if not current_app.config['AUTH_REQUIRED']:
        key = ApiKey.find_by_id(key)
    elif Scope.admin in g.scopes or Scope.admin_keys in g.scopes:
        key = ApiKey.find_by_id(key)
    else:
        key = ApiKey.find_by_id(key, user=g.login)

    if not key:
        raise ApiError('not found', 404)

    update = request.json
    update['customer'] = assign_customer(wanted=update.get('customer'),
                                         permission=Scope.admin_keys)

    for want_scope in update.get('scopes', []):
        if not Permission.is_in_scope(want_scope, have_scopes=g.scopes):
            raise ApiError(
                "Requested scope '{}' not in existing scopes: {}".format(
                    want_scope, ','.join(g.scopes)), 403)

    admin_audit_trail.send(current_app._get_current_object(),
                           event='apikey-updated',
                           message='',
                           user=g.login,
                           customers=g.customers,
                           scopes=g.scopes,
                           resource_id=key.id,
                           type='apikey',
                           request=request)

    updated = key.update(**request.json)
    if updated:
        return jsonify(status='ok', key=updated.serialize)
    else:
        raise ApiError('failed to update API key', 500)
Beispiel #16
0
        def wrapped(*args, **kwargs):

            # API Key (Authorization: Key <key>)
            if 'Authorization' in request.headers:
                auth_header = request.headers['Authorization']
                m = re.match(r'Key (\S+)', auth_header)
                key = m.group(1) if m else None
            # API Key (X-API-Key: <key>)
            elif 'X-API-Key' in request.headers:
                key = request.headers['X-API-Key']
            # API Key (/foo?api-key=<key>)
            else:
                key = request.args.get('api-key', None)

            if key:
                key_info = ApiKey.verify_key(key)
                if not key_info:
                    raise ApiError("API key parameter '%s' is invalid" % key,
                                   401)
                g.user = key_info.user
                g.customers = [key_info.customer] if key_info.customer else []
                g.scopes = key_info.scopes

                if not Permission.is_in_scope(scope, g.scopes):
                    raise ApiError('Missing required scope: %s' % scope, 403)
                else:
                    return f(*args, **kwargs)

            # Bearer Token
            auth_header = request.headers.get('Authorization', '')
            m = re.match(r'Bearer (\S+)', auth_header)
            token = m.group(1) if m else None

            if token:
                try:
                    jwt = Jwt.parse(token)
                except DecodeError:
                    raise ApiError('Token is invalid', 401)
                except ExpiredSignature:
                    raise ApiError('Token has expired', 401)
                except InvalidAudience:
                    raise ApiError('Invalid audience', 401)
                g.user = jwt.preferred_username
                g.customers = jwt.customers
                g.scopes = jwt.scopes

                if not Permission.is_in_scope(scope, g.scopes):
                    raise ApiError('Missing required scope: %s' % scope, 403)
                else:
                    return f(*args, **kwargs)

            # Basic Auth
            auth_header = request.headers.get('Authorization', '')
            m = re.match(r'Basic (\S+)', auth_header)
            credentials = m.group(1) if m else None

            if credentials:
                try:
                    username, password = base64.b64decode(credentials).decode(
                        'utf-8').split(':')
                except Exception as e:
                    raise BasicAuthError('Invalid credentials',
                                         400,
                                         errors=[str(e)])

                user = User.check_credentials(username, password)
                if not user:
                    raise BasicAuthError('Authorization required', 401)

                if current_app.config[
                        'EMAIL_VERIFICATION'] and not user.email_verified:
                    raise BasicAuthError('email not verified', 401)

                if not_authorized('ALLOWED_EMAIL_DOMAINS',
                                  groups=[user.domain]):
                    raise BasicAuthError('Unauthorized domain', 403)

                g.user = user.email
                g.customers = get_customers(user.email, groups=[user.domain])
                g.scopes = Permission.lookup(user.email, groups=user.roles)

                if not Permission.is_in_scope(scope, g.scopes):
                    raise BasicAuthError('Missing required scope: %s' % scope,
                                         403)
                else:
                    return f(*args, **kwargs)

            if not current_app.config['AUTH_REQUIRED']:
                g.user = None
                g.customers = []
                g.scopes = []
                return f(*args, **kwargs)

            # Google App Engine Cron Service
            if request.headers.get('X-Appengine-Cron',
                                   False) and request.headers.get(
                                       'X-Forwarded-For', '') == '0.1.0.1':
                return f(*args, **kwargs)

            raise ApiError('Missing authorization API Key or Bearer Token',
                           401)
Beispiel #17
0
        def wrapped(*args, **kwargs):

            # API Key (Authorization: Key <key>)
            if 'Authorization' in request.headers and request.headers[
                    'Authorization'].startswith('Key '):
                auth_header = request.headers['Authorization']
                m = re.match(r'Key (\S+)', auth_header)
                key = m.group(1) if m else None
            # API Key (X-API-Key: <key>)
            elif 'X-API-Key' in request.headers:
                key = request.headers['X-API-Key']
            # API Key (/foo?api-key=<key>)
            else:
                key = request.args.get('api-key', None)

            if key:
                key_info = ApiKey.verify_key(key)
                if not key_info:
                    raise ApiError("API key parameter '%s' is invalid" % key,
                                   401)
                g.user_id = None
                g.login = key_info.user
                g.customers = [key_info.customer] if key_info.customer else []
                g.scopes = key_info.scopes  # type: List[Scope]

                if not Permission.is_in_scope(scope, have_scopes=g.scopes):
                    raise ApiError('Missing required scope: %s' % scope, 403)
                else:
                    return f(*args, **kwargs)

            # Hawk HMAC Signature (Authorization: Hawk mac=...)
            if request.headers.get('Authorization', '').startswith('Hawk'):
                try:
                    receiver = HmacAuth.authenticate(request)
                except mohawk.exc.HawkFail as e:
                    raise ApiError(str(e), 401)

                g.user_id = None
                g.login = receiver.parsed_header.get('id')
                g.customers = []
                g.scopes = ADMIN_SCOPES
                return f(*args, **kwargs)

            # Bearer Token
            auth_header = request.headers.get('Authorization', '')
            m = re.match(r'Bearer (\S+)', auth_header)
            token = m.group(1) if m else None

            if token:
                try:
                    jwt = Jwt.parse(token)
                except DecodeError:
                    raise ApiError('Token is invalid', 401)
                except ExpiredSignatureError:
                    raise ApiError('Token has expired', 401)
                except InvalidAudienceError:
                    raise ApiError('Invalid audience', 401)
                g.user_id = jwt.oid or jwt.subject
                g.login = jwt.preferred_username
                g.customers = jwt.customers
                g.scopes = jwt.scopes  # type: List[Scope]

                if not Permission.is_in_scope(scope, have_scopes=g.scopes):
                    raise ApiError('Missing required scope: %s' % scope, 403)
                else:
                    return f(*args, **kwargs)

            # Basic Auth
            auth_header = request.headers.get('Authorization', '')
            m = re.match(r'Basic (\S+)', auth_header)
            credentials = m.group(1) if m else None

            if credentials:
                try:
                    username, password = base64.b64decode(credentials).decode(
                        'utf-8').split(':')
                except Exception as e:
                    raise BasicAuthError('Invalid credentials',
                                         400,
                                         errors=[str(e)])

                user = User.check_credentials(username, password)
                if not user:
                    raise BasicAuthError('Authorization required', 401)

                if current_app.config[
                        'EMAIL_VERIFICATION'] and not user.email_verified:
                    raise BasicAuthError('email not verified', 401)

                if not_authorized('ALLOWED_EMAIL_DOMAINS',
                                  groups=[user.domain]):
                    raise BasicAuthError('Unauthorized domain', 403)

                g.user_id = user.id
                g.login = user.email
                g.customers = get_customers(user.email, groups=[user.domain])
                g.scopes = Permission.lookup(
                    user.email, roles=user.roles)  # type: List[Scope]

                if not Permission.is_in_scope(scope, have_scopes=g.scopes):
                    raise BasicAuthError('Missing required scope: %s' % scope,
                                         403)
                else:
                    return f(*args, **kwargs)

            # auth not required
            if not current_app.config['AUTH_REQUIRED']:
                g.user_id = None
                g.login = None
                g.customers = []
                g.scopes = []  # type: List[Scope]
                return f(*args, **kwargs)

            # auth required for admin/write, but readonly is allowed
            if current_app.config['AUTH_REQUIRED'] and current_app.config[
                    'ALLOW_READONLY']:
                g.user_id = None
                g.login = None
                g.customers = []
                g.scopes = current_app.config['READONLY_SCOPES']
                return f(*args, **kwargs)

            # Google App Engine Cron Service
            if request.headers.get('X-Appengine-Cron',
                                   False) and request.headers.get(
                                       'X-Forwarded-For', '') == '0.1.0.1':
                return f(*args, **kwargs)

            raise ApiError('Missing authorization API Key or Bearer Token',
                           401)
Beispiel #18
0
        def wrapped(*args, **kwargs):

            # API Key (Authorization: Key <key>)
            if 'Authorization' in request.headers:
                auth_header = request.headers['Authorization']
                m = re.match(r'Key (\S+)', auth_header)
                key = m.group(1) if m else None
            # API Key (X-API-Key: <key>)
            elif 'X-API-Key' in request.headers:
                key = request.headers['X-API-Key']
            # API Key (/foo?api-key=<key>)
            else:
                key = request.args.get('api-key', None)

            if key:
                key_info = ApiKey.verify_key(key)
                if not key_info:
                    raise ApiError("API key parameter '%s' is invalid" % key, 401)
                g.user_id = None
                g.login = key_info.user
                g.customers = [key_info.customer] if key_info.customer else []
                g.scopes = key_info.scopes  # type: List[Scope]

                if not Permission.is_in_scope(scope, have_scopes=g.scopes):
                    raise ApiError('Missing required scope: %s' % scope.value, 403)
                else:
                    return f(*args, **kwargs)

            # Bearer Token
            auth_header = request.headers.get('Authorization', '')
            m = re.match(r'Bearer (\S+)', auth_header)
            token = m.group(1) if m else None

            if token:
                try:
                    jwt = Jwt.parse(token)
                except DecodeError:
                    raise ApiError('Token is invalid', 401)
                except ExpiredSignature:
                    raise ApiError('Token has expired', 401)
                except InvalidAudience:
                    raise ApiError('Invalid audience', 401)
                g.user_id = jwt.subject
                g.login = jwt.preferred_username
                g.customers = jwt.customers
                g.scopes = jwt.scopes  # type: List[Scope]

                if not Permission.is_in_scope(scope, have_scopes=g.scopes):
                    raise ApiError('Missing required scope: %s' % scope.value, 403)
                else:
                    return f(*args, **kwargs)

            # Basic Auth
            auth_header = request.headers.get('Authorization', '')
            m = re.match(r'Basic (\S+)', auth_header)
            credentials = m.group(1) if m else None

            if credentials:
                try:
                    username, password = base64.b64decode(credentials).decode('utf-8').split(':')
                except Exception as e:
                    raise BasicAuthError('Invalid credentials', 400, errors=[str(e)])

                user = User.check_credentials(username, password)
                if not user:
                    raise BasicAuthError('Authorization required', 401)

                if current_app.config['EMAIL_VERIFICATION'] and not user.email_verified:
                    raise BasicAuthError('email not verified', 401)

                if not_authorized('ALLOWED_EMAIL_DOMAINS', groups=[user.domain]):
                    raise BasicAuthError('Unauthorized domain', 403)

                g.user_id = user.id
                g.login = user.email
                g.customers = get_customers(user.email, groups=[user.domain])
                g.scopes = Permission.lookup(user.email, roles=user.roles)  # type: List[Scope]

                if not Permission.is_in_scope(scope, have_scopes=g.scopes):
                    raise BasicAuthError('Missing required scope: %s' % scope.value, 403)
                else:
                    return f(*args, **kwargs)

            if not current_app.config['AUTH_REQUIRED']:
                g.user_id = None
                g.login = None
                g.customers = []
                g.scopes = []  # type: List[Scope]
                return f(*args, **kwargs)

            # Google App Engine Cron Service
            if request.headers.get('X-Appengine-Cron', False) and request.headers.get('X-Forwarded-For', '') == '0.1.0.1':
                return f(*args, **kwargs)

            raise ApiError('Missing authorization API Key or Bearer Token', 401)
Beispiel #19
0
    def test_is_in_scope(self):

        self.assertEqual(
            Permission.is_in_scope(Scope.read_customers, [Scope.read]), True)
        self.assertEqual(
            Permission.is_in_scope(Scope.read_customers, [Scope.write]), True)
        self.assertEqual(
            Permission.is_in_scope(Scope.read_customers, [Scope.admin]), True)

        self.assertEqual(
            Permission.is_in_scope(Scope.read_heartbeats, [Scope.read_alerts]),
            False)
        self.assertEqual(
            Permission.is_in_scope(Scope.read_heartbeats,
                                   [Scope.write_alerts]), False)
        self.assertEqual(
            Permission.is_in_scope(Scope.read_heartbeats,
                                   [Scope.admin_alerts]), False)

        self.assertEqual(
            Permission.is_in_scope(Scope.write_blackouts, [Scope.read]), False)
        self.assertEqual(
            Permission.is_in_scope(Scope.write_blackouts,
                                   [Scope.read_blackouts, Scope.read]), False)
        self.assertEqual(
            Permission.is_in_scope(
                Scope.write_blackouts,
                [Scope.read_blackouts, Scope.write_blackouts]), True)
        self.assertEqual(
            Permission.is_in_scope(Scope.write_blackouts,
                                   [Scope.write_blackouts]), True)
        self.assertEqual(
            Permission.is_in_scope(Scope.write_blackouts,
                                   [Scope.read_blackouts, Scope.write]), True)
        self.assertEqual(
            Permission.is_in_scope(Scope.write_blackouts,
                                   [Scope.read_blackouts, Scope.admin]), True)
        self.assertEqual(
            Permission.is_in_scope(Scope.write_blackouts,
                                   [Scope.read, Scope.write_keys]), False)
        self.assertEqual(
            Permission.is_in_scope(Scope.write_blackouts,
                                   [Scope.read, Scope.admin_keys]), False)

        self.assertEqual(Permission.is_in_scope(Scope.admin, [Scope.write]),
                         False)
        self.assertEqual(
            Permission.is_in_scope(Scope.admin,
                                   [Scope.read, Scope.write, Scope.admin]),
            True)
        self.assertEqual(
            Permission.is_in_scope(Scope.read_heartbeats, [Scope.write]), True)