예제 #1
0
def patch_node(node_id):
    # Parse the request
    node_id = str2id(node_id)
    patch = request.get_json()

    # Find the node type.
    node = mongo.find_one_or_404('nodes', node_id, projection={'node_type': 1})
    try:
        node_type = node['node_type']
    except KeyError:
        msg = 'Node %s has no node_type property' % node_id
        log.warning(msg)
        raise wz_exceptions.InternalServerError(msg)
    log.debug('User %s wants to PATCH %s node %s',
              authentication.current_user_id(), node_type, node_id)

    # Find the PATCH handler for the node type.
    try:
        patch_handler = custom.patch_handlers[node_type]
    except KeyError:
        log.info('No patch handler for node type %r', node_type)
        raise wz_exceptions.MethodNotAllowed(
            'PATCH on node type %r not allowed' % node_type)

    # Let the PATCH handler do its thing.
    return patch_handler(node_id, patch)
예제 #2
0
def urler(project_id):
    """Returns the URL of any project."""

    project_id = str2id(project_id)
    project = mongo.find_one_or_404('projects',
                                    project_id,
                                    projection={'url': 1})
    return jsonify({'_id': project_id, 'url': project['url']})
예제 #3
0
def generate_token(manager_id: str):
    manager_oid = str2id(manager_id)
    manager = mongo.find_one_or_404('flamenco_managers', manager_oid)

    # There are three ways in which a user can get here. One is authenticated via
    # Authorization header (either Bearer token or Basic token:subtoken), and the
    # other is via an already-existing browser session.
    # In the latter case it's a redirect from a Flamenco Manager and we need to
    # check the timeout and HMAC.
    if not request.headers.get('Authorization'):
        hasher = current_flamenco.manager_manager.hasher(manager_oid)
        if hasher is None:
            raise wz_exceptions.InternalServerError(
                'Flamenco Manager not linked to this server')

        expires = request.args.get('expires', '')
        string_to_hash = f'{expires}-{manager_id}'
        hasher.update(string_to_hash.encode('utf8'))
        actual_hmac = hasher.hexdigest()

        query_hmac = request.args.get('hmac', '')
        if not hmac.compare_digest(query_hmac, actual_hmac):
            raise wz_exceptions.Unauthorized('Bad HMAC')

        # Only parse the timestamp after we learned we can trust it.
        expire_timestamp = dateutil.parser.parse(expires)
        validity_seconds_left = (expire_timestamp - utcnow()).total_seconds()
        if validity_seconds_left < 0:
            raise wz_exceptions.Unauthorized('Link expired')
        if validity_seconds_left > 900:
            # Flamenco Manager generates links that are valid for less than a minute, so
            # if it's more than 15 minutes in the future, it's bad.
            raise wz_exceptions.Unauthorized('Link too far in the future')

    user = authentication.current_user()

    if not current_flamenco.manager_manager.user_may_use(mngr_doc=manager):
        log.warning(
            'Account %s called %s for manager %s without access to that manager',
            user.user_id, request.url, manager_oid)
        raise wz_exceptions.Unauthorized()

    jwt = current_flamenco.jwt
    if not jwt.usable:
        raise wz_exceptions.NotImplemented(
            'JWT keystore is not usable at the moment')

    log.info('Generating JWT key for user_id=%s manager_id=%s remote_addr=%s',
             user.user_id, manager_id, request.remote_addr)
    key_for_manager = jwt.generate_key_for_manager(manager_oid, user.user_id)

    return Response(key_for_manager, content_type='text/plain')
예제 #4
0
파일: api.py 프로젝트: armadillica/flamenco
def generate_token(manager_id: str):
    manager_oid = str2id(manager_id)
    manager = mongo.find_one_or_404('flamenco_managers', manager_oid)

    # There are three ways in which a user can get here. One is authenticated via
    # Authorization header (either Bearer token or Basic token:subtoken), and the
    # other is via an already-existing browser session.
    # In the latter case it's a redirect from a Flamenco Manager and we need to
    # check the timeout and HMAC.
    if not request.headers.get('Authorization'):
        hasher = current_flamenco.manager_manager.hasher(manager_oid)
        if hasher is None:
            raise wz_exceptions.InternalServerError('Flamenco Manager not linked to this server')

        expires = request.args.get('expires', '')
        string_to_hash = f'{expires}-{manager_id}'
        hasher.update(string_to_hash.encode('utf8'))
        actual_hmac = hasher.hexdigest()

        query_hmac = request.args.get('hmac', '')
        if not hmac.compare_digest(query_hmac, actual_hmac):
            raise wz_exceptions.Unauthorized('Bad HMAC')

        # Only parse the timestamp after we learned we can trust it.
        expire_timestamp = dateutil.parser.parse(expires)
        validity_seconds_left = (expire_timestamp - utcnow()).total_seconds()
        if validity_seconds_left < 0:
            raise wz_exceptions.Unauthorized('Link expired')
        if validity_seconds_left > 900:
            # Flamenco Manager generates links that are valid for less than a minute, so
            # if it's more than 15 minutes in the future, it's bad.
            raise wz_exceptions.Unauthorized('Link too far in the future')

    user = authentication.current_user()

    if not current_flamenco.manager_manager.user_may_use(mngr_doc=manager):
        log.warning(
            'Account %s called %s for manager %s without access to that manager',
            user.user_id, request.url, manager_oid)
        raise wz_exceptions.Unauthorized()

    jwt = current_flamenco.jwt
    if not jwt.usable:
        raise wz_exceptions.NotImplemented('JWT keystore is not usable at the moment')

    log.info('Generating JWT key for user_id=%s manager_id=%s remote_addr=%s',
             user.user_id, manager_id, request.remote_addr)
    key_for_manager = jwt.generate_key_for_manager(manager_oid, user.user_id)

    return Response(key_for_manager, content_type='text/plain')
예제 #5
0
파일: api.py 프로젝트: WRWolfe66/flamenco
    def wrapper(manager_id, *args, **kwargs):
        from flamenco import current_flamenco
        from pillar.api.utils import str2id, mongo

        manager_id = str2id(manager_id)
        manager = mongo.find_one_or_404('flamenco_managers', manager_id)
        if not current_flamenco.manager_manager.user_manages(mngr_doc=manager):
            user_id = authentication.current_user_id()
            log.warning(
                'Service account %s sent startup notification for manager %s of another '
                'service account', user_id, manager_id)
            raise wz_exceptions.Unauthorized()

        return wrapped(manager_id, request.json, *args, **kwargs)
예제 #6
0
def project_quotas(project_id):
    """Returns information about the project's limits."""

    # Check that the user has GET permissions on the project itself.
    project = mongo.find_one_or_404('projects', project_id)
    check_permissions('projects', project, 'GET')

    file_size_used = utils.project_total_file_size(project_id)

    info = {
        'file_size_quota': None,  # TODO: implement this later.
        'file_size_used': file_size_used,
    }

    return jsonify(info)
예제 #7
0
def get_allowed_methods(project_id=None, node_type=None):
    """Returns allowed methods to create a node of a certain type.

    Either project_id or parent_node_id must be given. If the latter is given,
    the former is deducted from it.
    """

    project = mongo.find_one_or_404('projects', str2id(project_id))
    proj_methods = authorization.compute_allowed_methods('projects', project, node_type)

    resp = make_response()
    resp.headers['Allowed'] = ', '.join(sorted(proj_methods))
    resp.status_code = 204

    return resp
예제 #8
0
파일: api.py 프로젝트: armadillica/flamenco
        def wrapper(manager_id, *args, **kwargs):
            from pillar.api.utils import mongo

            manager_id = str2id(manager_id)
            manager = mongo.find_one_or_404('flamenco_managers', manager_id)
            if not current_flamenco.manager_manager.user_manages(mngr_doc=manager):
                user_id = authentication.current_user_id()
                log.warning(
                    'Service account %s called manager API endpoint for manager %s of another '
                    'service account', user_id, manager_id)
                raise wz_exceptions.Unauthorized()

            return wrapped(manager if pass_manager_doc else manager_id,
                           request.json,
                           *args, **kwargs)