Example #1
0
def create():
    require(request.authz.logged_in)
    data = parse_request(CollectionCreateSchema)
    role = Role.by_id(request.authz.id)
    sync = get_flag('sync')
    collection = create_collection(data, role=role, sync=sync)
    return CollectionSerializer.jsonify(collection)
Example #2
0
def ingest_upload(collection_id):
    require(request.authz.can(collection_id, request.authz.WRITE))
    sync = get_flag('sync')
    meta, foreign_id = _load_metadata()
    parent_id = _load_parent(collection_id, meta)
    upload_dir = mkdtemp(prefix='aleph.upload.')
    try:
        path = None
        content_hash = None
        for storage in request.files.values():
            path = safe_filename(storage.filename, default='upload')
            path = os.path.join(upload_dir, path)
            storage.save(path)
            content_hash = checksum(path)
        document = Document.by_keys(collection_id=collection_id,
                                    parent_id=parent_id,
                                    foreign_id=foreign_id,
                                    content_hash=content_hash)
        document.update(meta)
        document.schema = Document.SCHEMA
        if content_hash is None:
            document.schema = Document.SCHEMA_FOLDER
        ingest_document(document, path,
                        role_id=request.authz.id,
                        content_hash=content_hash)
    finally:
        shutil.rmtree(upload_dir)

    if document.collection.casefile:
        # Make sure collection counts are always accurate.
        update_document(document, sync=sync)
    return jsonify({
        'status': 'ok',
        'id': stringify(document.id)
    }, status=201)
Example #3
0
def triples(collection_id):
    require(request.authz.can_stream())
    log.debug("Stream triples [%r] begins... (coll: %s)",
              request.authz, collection_id)
    collection = get_db_collection(collection_id, request.authz.READ)
    record_audit(Audit.ACT_COLLECTION, id=collection_id)
    return Response(export_collection(collection), mimetype='text/plain')
Example #4
0
def create():
    require(not request.authz.in_maintenance, settings.PASSWORD_LOGIN)
    data = parse_request(RoleCreateSchema)

    try:
        email = Role.SIGNATURE.loads(data.get('code'),
                                     max_age=Role.SIGNATURE_MAX_AGE)
    except BadSignature:
        return jsonify({
            'status': 'error',
            'message': gettext('Invalid code')
        }, status=400)

    role = Role.by_email(email)
    if role is not None:
        return jsonify({
            'status': 'error',
            'message': gettext('Email is already registered')
        }, status=409)

    role = Role.load_or_create(
        foreign_id='password:{}'.format(email),
        type=Role.USER,
        name=data.get('name') or email,
        email=email
    )
    role.set_password(data.get('password'))
    db.session.add(role)
    db.session.commit()
    update_role(role)
    # Let the serializer return more info about this user
    request.authz.id = role.id
    tag_request(role_id=role.id)
    return RoleSerializer.jsonify(role, status=201)
Example #5
0
def create():
    require(request.authz.session_write)
    data = parse_request(AlertSchema)
    alert = Alert.create(data, request.authz.id)
    db.session.commit()
    tag_request(alert_id=alert.id)
    return AlertSerializer.jsonify(alert)
Example #6
0
def index():
    require(request.authz.logged_in)
    role = Role.by_id(request.authz.id)
    query = Notification.by_channels(get_role_channels(role),
                                     since=role.notified_at,
                                     exclude_actor_id=role.id)
    result = DatabaseQueryResult(request, query)
    return NotificationSerializer.jsonify_result(result)
Example #7
0
def update(id):
    role = obj_or_404(Role.by_id(id))
    require(request.authz.session_write)
    require(check_editable(role, request.authz))
    data = parse_request(RoleSchema)
    role.update(data)
    db.session.add(role)
    db.session.commit()
    update_role(role)
    return RoleSerializer.jsonify(role)
Example #8
0
def export(format):
    require(request.authz.logged_in)
    parser = SearchQueryParser(request.args, request.authz)
    parser.limit = EXPORT_MAX
    tag_request(query=parser.text, prefix=parser.prefix)
    result = EntitiesQuery.handle(request, parser=parser)
    stream = export_entities(request, result, format)
    response = Response(stream, mimetype='application/zip')
    disposition = 'attachment; filename={}'.format('Query_export.zip')
    response.headers['Content-Disposition'] = disposition
    return response
Example #9
0
def bulk(collection_id):
    collection = get_db_collection(collection_id, request.authz.WRITE)
    require(request.authz.can_bulk_import())
    merge = get_flag('merge', default=False)

    # This will disable certain security measures in order to allow bulk
    # loading of document data.
    unsafe = get_flag('unsafe', default=False)
    unsafe = unsafe and request.authz.is_admin

    entities = ensure_list(request.get_json(force=True))
    bulk_write(collection, entities, merge=merge, unsafe=unsafe)
    refresh_collection(id)
    return ('', 204)
Example #10
0
def suggest():
    require(request.authz.logged_in)
    parser = QueryParser(request.args, request.authz, limit=10)
    if parser.prefix is None or len(parser.prefix) < 3:
        # Do not return 400 because it's a routine event.
        return jsonify({
            'status': 'error',
            'message': gettext('prefix filter is too short'),
            'results': [],
            'total': 0
        })
    # this only returns users, not groups
    q = Role.by_prefix(parser.prefix, exclude=parser.exclude)
    result = DatabaseQueryResult(request, q, parser=parser)
    return RoleSerializer.jsonify_result(result)
Example #11
0
def update(id):
    """Change user settings.
    ---
    post:
      summary: Change user settings
      description: >
        Update a role to change its display name, or to define a
        new login password. Users can only update roles they have
        write access to, i.e. their own.
      parameters:
      - in: path
        name: id
        required: true
        description: role ID
        schema:
          type: integer
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RoleUpdate'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Role'
      tags:
      - Role
    """
    role = obj_or_404(Role.by_id(id))
    require(request.authz.can_write_role(role.id))
    data = parse_request("RoleUpdate")

    # When changing passwords, check the old password first.
    # cf. https://github.com/alephdata/aleph/issues/718
    if data.get("password"):
        current_password = data.get("current_password")
        if not role.check_password(current_password):
            raise BadRequest(gettext("Incorrect password."))

    role.update(data)
    db.session.add(role)
    db.session.commit()
    update_role(role)
    return RoleSerializer.jsonify(role)
Example #12
0
def update(entity_id):
    """
    ---
    post:
      summary: Update an entity
      description: >
        Update the entity with id `entity_id`. This only applies to
        entities which are backed by a database row, i.e. not any
        entities resulting from a mapping or bulk load.
      parameters:
      - in: path
        name: entity_id
        required: true
        schema:
          type: string
          format: entity_id
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EntityUpdate'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Entity'
      tags:
      - Entity
    """
    data = parse_request("EntityUpdate")
    try:
        entity = get_index_entity(entity_id, request.authz.WRITE)
        require(check_write_entity(entity, request.authz))
        collection = get_db_collection(entity.get("collection_id"),
                                       request.authz.WRITE)
    except NotFound:
        collection = get_nested_collection(data, request.authz.WRITE)
    tag_request(collection_id=collection.id)
    data["id"] = entity_id
    if get_flag("validate", default=False):
        validate_entity(data)
    sync = get_flag("sync", default=True)
    entity_id = upsert_entity(data, collection, authz=request.authz, sync=sync)
    db.session.commit()
    return view(entity_id)
Example #13
0
def update(id):
    role = obj_or_404(Role.by_id(id))
    require(request.authz.can_write_role(role.id))
    data = parse_request(RoleSchema)

    # When changing passwords, check the old password first.
    # cf. https://github.com/alephdata/aleph/issues/718
    if data.get('password'):
        current_password = data.get('current_password')
        if not role.check_password(current_password):
            raise BadRequest(gettext('Incorrect password.'))

    role.update(data)
    db.session.add(role)
    db.session.commit()
    update_role(role)
    return RoleSerializer.jsonify(role)
Example #14
0
def suggest():
    """
    ---
    get:
      summary: Suggest users matching a search prefix
      description: >-
        For a given `prefix`, suggest matching user accounts. For
        security reasons, the prefix must be more than three
        characters long.
      parameters:
      - in: query
        name: prefix
        required: true
        schema:
          type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                allOf:
                - $ref: '#/components/schemas/QueryResponse'
                properties:
                  results:
                    type: array
                    items:
                      $ref: '#/components/schemas/Role'
      tags:
      - Role
    """
    require(request.authz.logged_in)
    parser = QueryParser(request.args, request.authz, limit=10)
    if parser.prefix is None or len(parser.prefix) < 3:
        # Do not return 400 because it's a routine event.
        return jsonify({
            'status': 'error',
            'message': gettext('prefix filter is too short'),
            'results': [],
            'total': 0
        })
    # this only returns users, not groups
    q = Role.by_prefix(parser.prefix, exclude=parser.exclude)
    result = DatabaseQueryResult(request, q, parser=parser)
    return RoleSerializer.jsonify_result(result)
Example #15
0
def mapping_process(collection_id):
    collection = get_db_collection(collection_id, request.authz.WRITE)
    require(request.authz.can_bulk_import())
    # TODO: we need to look into possible abuse of mapping load path for local
    # path access on the machine running the mapping. Until then, this action
    # must be restricted to admins:
    require(request.authz.is_admin)
    if not request.is_json:
        raise BadRequest()
    data = request.get_json().get(collection.foreign_id)
    for query in keys_values(data, 'queries', 'query'):
        try:
            model.make_mapping(query)
            bulk_load_query.apply_async([collection.id, query], priority=6)
        except InvalidMapping as invalid:
            raise BadRequest(invalid)
    return ('', 204)
Example #16
0
def create():
    """Create a user role.
    ---
    post:
      summary: Create a user account
      description: >
        Create a user role by supplying the required account details.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RoleCreate'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Role'
      tags:
      - Role
    """
    require(settings.PASSWORD_LOGIN)
    require(not request.authz.in_maintenance)
    data = parse_request('RoleCreate')
    try:
        email = Role.SIGNATURE.loads(data.get('code'),
                                     max_age=Role.SIGNATURE_MAX_AGE)
    except BadSignature:
        return jsonify({
            'status': 'error',
            'message': gettext('Invalid code')
        }, status=400)

    role = Role.by_email(email)
    if role is not None:
        return jsonify({
            'status': 'error',
            'message': gettext('Email is already registered')
        }, status=409)

    role = create_user(email, data.get('name'), data.get('password'))
    # Let the serializer return more info about this user
    request.authz = Authz.from_role(role)
    tag_request(role_id=role.id)
    return RoleSerializer.jsonify(role, status=201)
Example #17
0
def entities(collection_id=None):
    require(request.authz.can_stream())
    log.debug("Stream entities [%r] begins... (coll: %s)",
              request.authz, collection_id)
    schemata = ensure_list(request.args.getlist('schema'))
    excludes = ['text', 'roles', 'fingerprints']
    includes = ensure_list(request.args.getlist('include'))
    includes = [f for f in includes if f not in excludes]
    if collection_id is not None:
        get_db_collection(collection_id, request.authz.READ)
        record_audit(Audit.ACT_COLLECTION, id=collection_id)
    entities = iter_entities(authz=request.authz,
                             collection_id=collection_id,
                             schemata=schemata,
                             excludes=excludes,
                             includes=includes)
    return stream_ijson(entities)
Example #18
0
def mapping_process(id):
    collection = get_db_collection(id, request.authz.WRITE)
    require(request.authz.can_bulk_import())
    # TODO: we need to look into possible abuse of mapping load path for local
    # path access on the machine running the mapping. Until then, this action
    # must be restricted to admins:
    require(request.authz.is_admin)
    if not request.is_json:
        raise BadRequest()
    data = request.get_json().get(collection.foreign_id)
    for query in keys_values(data, 'queries', 'query'):
        try:
            model.make_mapping(query)
            bulk_load_query.apply_async([collection.id, query], priority=6)
        except InvalidMapping as invalid:
            raise BadRequest(invalid)
    return ('', 204)
Example #19
0
def entities(collection_id=None):
    require(request.authz.can_stream())
    log.debug("Stream entities [%r] begins... (coll: %s)", request.authz,
              collection_id)
    schemata = ensure_list(request.args.getlist('schema'))
    excludes = ['text', 'roles', 'fingerprints']
    includes = ensure_list(request.args.getlist('include'))
    includes = [f for f in includes if f not in excludes]
    if collection_id is not None:
        get_db_collection(collection_id, request.authz.READ)
        record_audit(Audit.ACT_COLLECTION, id=collection_id)
    entities = iter_entities(authz=request.authz,
                             collection_id=collection_id,
                             schemata=schemata,
                             excludes=excludes,
                             includes=includes)
    return stream_ijson(entities)
Example #20
0
def index(collection_id):
    """
    ---
    get:
      summary: Fetch cross-reference results
      description: >-
        Fetch cross-reference matches for entities in the collection
        with id `collection_id`
      parameters:
      - in: path
        name: collection_id
        required: true
        schema:
          type: integer
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                allOf:
                - $ref: '#/components/schemas/QueryResponse'
                properties:
                  results:
                    type: array
                    items:
                      $ref: '#/components/schemas/XrefResponse'
      tags:
      - Xref
      - Collection
    """
    get_index_collection(collection_id)
    result = XrefQuery.handle(request, collection_id=collection_id)
    context_id = result.parser.getint('context_id', request.authz.id)
    if context_id is not None:
        require(request.authz.can_read_role(context_id))
        pairs = []
        for xref in result.results:
            pairs.append((xref.get('entity_id'), xref.get('match_id')))
        decisions = Linkage.decisions(pairs, context_id)
        for xref in result.results:
            key = (xref.get('entity_id'), xref.get('match_id'))
            xref['decision'] = decisions.get(key)
    return XrefSerializer.jsonify_result(result)
Example #21
0
def status():
    require(request.authz.logged_in)
    status = get_active_collection_status()
    active_collections = status.pop('datasets', [])
    active_foreign_ids = set(active_collections.keys())
    collections = request.authz.collections(request.authz.READ)
    serializer = CollectionSerializer(reference=True)
    results = []
    for fid in sorted(active_foreign_ids):
        collection = Collection.by_foreign_id(fid)
        if collection is None:
            continue
        if collection.id in collections:
            result = active_collections[fid]
            result['collection'] = serializer.serialize(collection.to_dict())
            result['id'] = fid
            results.append(result)
    return jsonify({'results': results, 'total': len(results)})
Example #22
0
def status():
    require(request.authz.logged_in)
    status = get_active_collection_status()
    active_collections = status.pop('datasets')
    active_foreign_ids = set(active_collections.keys())
    collections = request.authz.collections(request.authz.READ)
    results = []
    for fid in active_foreign_ids:
        collection = Collection.by_foreign_id(fid)
        if collection is None:
            continue
        if collection.id in collections:
            result = active_collections[fid]
            result['collection'] = collection.to_dict()
            result['id'] = fid
            results.append(result)
    status['results'] = results
    return jsonify(status)
Example #23
0
def retrieve():
    """Downloads a binary blob from the blob storage archive.
    ---
    get:
      summary: Download a blob from the archive
      parameters:
      - description: Authorization token for an archive blob
        in: query
        name: claim
        schema:
          type: string
          description: A signed JWT with the object hash.
      responses:
        '200':
          description: OK
          content:
            '*/*': {}
        '404':
          description: Object does not exist.
      tags:
      - Archive
    """
    claim = request.args.get("claim")
    role_id, content_hash, file_name, mime_type = archive_claim(claim)
    require(request.authz.id == role_id)
    tag_request(content_hash=content_hash, file_name=file_name)
    url = archive.generate_url(content_hash,
                               file_name=file_name,
                               mime_type=mime_type)
    if url is not None:
        return redirect(url)
    try:
        local_path = archive.load_file(content_hash)
        if local_path is None:
            return Response(status=404)
        return send_file(
            str(local_path),
            as_attachment=True,
            conditional=True,
            attachment_filename=file_name,
            mimetype=mime_type,
        )
    finally:
        archive.cleanup_file(content_hash)
Example #24
0
def password_login():
    """Provides email and password authentication.
    ---
    post:
      summary: Log in as a user
      description: Create a session token using a username and password.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Login'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                  token:
                    type: string
      tags:
      - Role
    """
    require(settings.PASSWORD_LOGIN)
    data = parse_request("Login")
    role = Role.by_email(data.get("email"))
    if role is None or not role.has_password:
        raise BadRequest(gettext("Invalid user or password."))

    if not role.check_password(data.get("password")):
        raise BadRequest(gettext("Invalid user or password."))

    if role.is_blocked:
        raise Unauthorized(gettext("Your account is blocked."))

    role.touch()
    db.session.commit()
    update_role(role)
    authz = Authz.from_role(role)
    request.authz = authz
    return jsonify({"status": "ok", "token": authz.to_token(role=role)})
Example #25
0
def entities(collection_id=None):
    """
    ---
    get:
      summary: Stream collection entities.
      description: >
        Stream a JSON form of each entity in the given collection, or
        throughout the entire database.
      parameters:
      - description: The collection ID.
        in: path
        name: collection_id
        required: true
        schema:
          minimum: 1
          type: integer
      responses:
        '200':
          description: OK
          content:
            application/x-ndjson:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Entity'
      tags:
      - Entity
    """
    log.debug("Stream entities [%r] begins... (coll: %s)", request.authz,
              collection_id)
    schemata = ensure_list(request.args.getlist("schema"))
    includes = ensure_list(request.args.getlist("include"))
    includes = includes or PROXY_INCLUDES
    if collection_id is not None:
        get_db_collection(collection_id, request.authz.WRITE)
    else:
        require(request.authz.is_admin)
    entities = iter_entities(
        authz=request.authz,
        collection_id=collection_id,
        schemata=schemata,
        includes=includes,
    )
    return stream_ijson(entities)
Example #26
0
def oauth_init():
    """Init OAuth auth flow.
    ---
    get:
      summary: Start OAuth authentication
      description: Initiate a forward to the OAuth server.
      responses:
        '302':
          description: Redirect
      tags:
      - Role
    """
    require(settings.OAUTH)
    url = url_for(".oauth_callback")
    state = oauth.provider.create_authorization_url(url)
    state["next_url"] = request.args.get("next", request.referrer)
    state["redirect_uri"] = url
    cache.set_complex(_oauth_session(state.get("state")), state, expires=3600)
    return redirect(state["url"])
Example #27
0
def entities(collection_id=None):
    """
    ---
    get:
      summary: Stream collection entities.
      description: >
        Stream a JSON form of each entity in the given collection, or
        throughout the entire database.
      parameters:
      - description: The collection ID.
        in: path
        name: collection_id
        required: true
        schema:
          minimum: 1
          type: integer
      responses:
        '200':
          description: OK
          content:
            application/x-ndjson:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Entity'
      tags:
      - Entity
    """
    require(request.authz.can_stream())
    log.debug("Stream entities [%r] begins... (coll: %s)", request.authz,
              collection_id)
    schemata = ensure_list(request.args.getlist('schema'))
    excludes = ['text', 'fingerprints']
    includes = ensure_list(request.args.getlist('include'))
    includes = [f for f in includes if f not in excludes]
    if collection_id is not None:
        get_db_collection(collection_id, request.authz.READ)
    entities = iter_entities(authz=request.authz,
                             collection_id=collection_id,
                             schemata=schemata,
                             excludes=excludes,
                             includes=includes)
    return stream_ijson(entities)
Example #28
0
def oauth_callback():
    require(settings.OAUTH)
    err = Unauthorized(gettext("Authentication has failed."))
    state = cache.get_complex(_oauth_session(request.args.get("state")))
    if state is None:
        raise err

    try:
        oauth.provider.framework.set_session_data(request, "state", state.get("state"))
        uri = state.get("redirect_uri")
        oauth_token = oauth.provider.authorize_access_token(redirect_uri=uri)
    except AuthlibBaseError as err:
        log.warning("Failed OAuth: %r", err)
        raise err
    if oauth_token is None or isinstance(oauth_token, AuthlibBaseError):
        log.warning("Failed OAuth: %r", oauth_token)
        raise err

    role = handle_oauth(oauth.provider, oauth_token)
    if role is None:
        raise err

    # Determine session duration based on OAuth settings
    expire = oauth_token.get("expires_in", Authz.EXPIRE)
    expire = oauth_token.get("refresh_expires_in", expire)

    db.session.commit()
    update_role(role)
    log.debug("Logged in: %r", role)
    request.authz = Authz.from_role(role, expire=expire)
    token = request.authz.to_token()

    # Store id_token to generate logout URL later
    id_token = oauth_token.get("id_token")
    if id_token is not None:
        cache.set(_token_session(token), id_token, expires=expire)

    next_path = get_url_path(state.get("next_url"))
    next_url = ui_url("oauth", next=next_path)
    next_url = "%s#token=%s" % (next_url, token)
    session.clear()
    return redirect(next_url)
Example #29
0
def oauth_callback():
    require(settings.OAUTH)
    token = oauth.provider.authorize_access_token()
    if token is None or isinstance(token, AuthlibBaseError):
        log.warning("Failed OAuth: %r", token)
        raise Unauthorized(gettext("Authentication has failed."))

    role = handle_oauth(oauth.provider, token)
    if role is None:
        log.error("No OAuth handler was installed.")
        raise Unauthorized(gettext("Authentication has failed."))
    db.session.commit()
    update_role(role)
    log.info("Logged in: %r", role)
    request.authz = Authz.from_role(role)
    token = request.authz.to_token(role=role)
    token = token.decode('utf-8')
    next_path = get_url_path(request.args.get('state'))
    next_url = ui_url(settings.OAUTH_UI_CALLBACK, next=next_path)
    next_url = '%s#token=%s' % (next_url, token)
    return redirect(next_url)
Example #30
0
def retrieve():
    claim = request.args.get('claim')
    role_id, content_hash, file_name, mime_type = archive_claim(claim)
    require(request.authz.id == role_id)
    tag_request(content_hash=content_hash, file_name=file_name)
    url = archive.generate_url(content_hash,
                               file_name=file_name,
                               mime_type=mime_type)
    if url is not None:
        return redirect(url)
    try:
        local_path = archive.load_file(content_hash)
        if local_path is None:
            return Response(status=404)
        return send_file(str(local_path),
                         as_attachment=True,
                         conditional=True,
                         attachment_filename=file_name,
                         mimetype=mime_type)
    finally:
        archive.cleanup_file(content_hash)
Example #31
0
def view(profile_id):
    """
    ---
    get:
      summary: Retrieve a profile
      description: >-
        Get a profile with constituent items and the merged pseudo entity.
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Profile'
      tags:
      - Profile
    """
    profile = obj_or_404(get_profile(profile_id, authz=request.authz))
    require(request.authz.can(profile.get("collection_id"),
                              request.authz.READ))
    return ProfileSerializer.jsonify(profile)
Example #32
0
def export():
    """
    ---
    post:
      summary: Download the results of a search
      description: >-
        Downloads all the results of a search as a zip archive; upto a max of
        10,000 results. The returned file will contain an Excel document with
        structured data as well as the binary files from all matching
        documents.

        Supports the same query parameters as the search API.
      responses:
        '202':
          description: Accepted
      tags:
      - Entity
    """
    require(request.authz.logged_in)
    parser = SearchQueryParser(request.args, request.authz)
    parser.limit = MAX_PAGE
    tag_request(query=parser.text, prefix=parser.prefix)
    result = EntitiesQuery.handle(request, parser=parser)
    label = "Search results for query: %s" % parser.text
    export = create_export(
        operation=OP_EXPORT_SEARCH_RESULTS,
        role_id=request.authz.id,
        label=label,
        file_path=None,
        expires_after=Export.DEFAULT_EXPIRATION,
        collection=None,
        mime_type=ZIP,
    )
    job_id = get_session_id()
    payload = {
        "export_id": export.id,
        "result": result.to_dict(),
    }
    queue_task(None, OP_EXPORT_SEARCH_RESULTS, job_id=job_id, payload=payload)
    return ("", 202)
Example #33
0
def retrieve():
    claim = request.args.get('claim')
    role_id, content_hash, file_name, mime_type = archive_claim(claim)
    require(request.authz.id == role_id)
    record_audit(Audit.ACT_ARCHIVE, content_hash=content_hash)
    tag_request(content_hash=content_hash, file_name=file_name)
    url = archive.generate_url(content_hash,
                               file_name=file_name,
                               mime_type=mime_type)
    if url is not None:
        return redirect(url)
    try:
        local_path = archive.load_file(content_hash)
        if local_path is None:
            return Response(status=404)
        return send_file(local_path,
                         as_attachment=True,
                         conditional=True,
                         attachment_filename=file_name,
                         mimetype=mime_type)
    finally:
        archive.cleanup_file(content_hash)
Example #34
0
def status():
    """
    ---
    get:
      summary: Get an overview of collections being processed
      description: >
        List collections being processed currently and pending task counts
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SystemStatusResponse'
      tags:
      - System
    """
    require(request.authz.logged_in)
    request.rate_limit = None
    status = get_active_collection_status()
    active_collections = status.pop('datasets', [])
    active_foreign_ids = set(active_collections.keys())
    collections = request.authz.collections(request.authz.READ)
    serializer = CollectionSerializer(reference=True)
    results = []
    for fid in sorted(active_foreign_ids):
        collection = Collection.by_foreign_id(fid)
        if collection is None:
            continue
        if collection.id in collections:
            result = active_collections[fid]
            result['collection'] = serializer.serialize(collection.to_dict())
            result['id'] = fid
            results.append(result)
    return jsonify({
        'results': results,
        'total': len(results)
    })
Example #35
0
def create_code():
    """Send a account creation token to an email address.
    ---
    post:
      summary: Begin account registration
      description: >
        Begin validating a user email by sending a token to the address
        which can then be used to create an account.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RoleCodeCreate'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                  token:
                    type: string
      tags:
      - Role
    """
    require(settings.PASSWORD_LOGIN)
    require(not request.authz.in_maintenance)
    data = parse_request("RoleCodeCreate")
    challenge_role(data)
    return jsonify({
        "status": "ok",
        "message": gettext("To proceed, please check your email.")
    })
Example #36
0
def tags(profile_id):
    """
    ---
    get:
      summary: Get profile tags
      description: >-
        Get tags for the profile with id `profile_id`.
      parameters:
      - in: path
        name: profile_id
        required: true
        schema:
          type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                allOf:
                - $ref: '#/components/schemas/QueryResponse'
                properties:
                  results:
                    type: array
                    items:
                      $ref: '#/components/schemas/EntityTag'
      tags:
      - Profile
    """
    profile = obj_or_404(get_profile(profile_id, authz=request.authz))
    require(request.authz.can(profile.get("collection_id"),
                              request.authz.READ))
    tag_request(collection_id=profile.get("collection_id"))
    results = entity_tags(profile["merged"], request.authz)
    return jsonify({"status": "ok", "total": len(results), "results": results})
Example #37
0
def status():
    """
    ---
    get:
      summary: Get an overview of collections and exports being processed
      description: >
        List collections being processed currently and pending task counts
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SystemStatusResponse'
      tags:
      - System
    """
    require(request.authz.logged_in)
    request.rate_limit = None
    status = get_active_dataset_status()
    datasets = status.pop("datasets", {})
    collections = (get_dataset_collection_id(d) for d in datasets.keys())
    collections = (c for c in collections if c is not None)
    collections = Collection.all_by_ids(collections, deleted=True).all()
    collections = {c.id: c for c in collections}
    serializer = CollectionSerializer(reference=True)
    results = []
    for dataset, status in sorted(datasets.items()):
        collection_id = get_dataset_collection_id(dataset)
        if not request.authz.can(collection_id, request.authz.READ):
            continue
        collection = collections.get(collection_id)
        if collection is not None:
            status["collection"] = serializer.serialize(collection.to_dict())
        results.append(status)
    return jsonify({"results": results, "total": len(results)})
Example #38
0
def delete():
    """Delete the query logs for a particular search term.
    ---
    delete:
      summary: Clear query log
      description: Delete the query logs for a particular search term
      parameters:
      - in: query
        name: query
        schema:
          type: string
      responses:
        '204':
          description: No Content
      tags:
      - Query Log
    """
    require(request.authz.logged_in)
    query = request.args.get('query')
    if not query:
        return ('', 404)
    QueryLog.delete_query(request.authz.id, query)
    db.session.commit()
    return ('', 204)
Example #39
0
def index():
    require(request.authz.logged_in)
    parser = QueryParser(request.args, request.authz)
    q = QueryLog.query_log(role_id=request.authz.id)
    result = DatabaseQueryResult(request, q, parser=parser)
    return QueryLogSerializer.jsonify_result(result)
Example #40
0
def view(alert_id):
    require(request.authz.logged_in)
    alert = obj_or_404(Alert.by_id(alert_id, role_id=request.authz.id))
    return AlertSerializer.jsonify(alert)
Example #41
0
def delete(alert_id):
    require(request.authz.session_write)
    alert = obj_or_404(Alert.by_id(alert_id, role_id=request.authz.id))
    alert.delete()
    db.session.commit()
    return ('', 204)
Example #42
0
def view(id):
    role = obj_or_404(Role.by_id(id))
    require(check_editable(role, request.authz))
    return RoleSerializer.jsonify(role)
Example #43
0
def mark_read():
    require(request.authz.logged_in)
    role = Role.by_id(request.authz.id)
    role.notified_at = datetime.utcnow()
    db.session.commit()
    return jsonify({'status': 'ok'}, status=202)
Example #44
0
def index():
    require(request.authz.logged_in)
    query = Alert.by_role(request.authz.role)
    result = DatabaseQueryResult(request, query, schema=AlertSchema)
    return jsonify(result)
Example #45
0
def create():
    require(request.authz.session_write)
    data = parse_request(schema=AlertSchema)
    alert = Alert.create(data, request.authz.role)
    db.session.commit()
    return view(alert.id)
Example #46
0
def view(id):
    require(request.authz.logged_in)
    alert = obj_or_404(Alert.by_id(id, role=request.authz.role))
    return jsonify(alert, schema=AlertSchema)
Example #47
0
def delete(id):
    require(request.authz.session_write)
    alert = obj_or_404(Alert.by_id(id, role=request.authz.role))
    alert.delete()
    db.session.commit()
    return jsonify({'status': 'ok'})
Example #48
0
def index():
    require(request.authz.logged_in)
    query = Alert.by_role_id(request.authz.id)
    result = DatabaseQueryResult(request, query)
    return AlertSerializer.jsonify_result(result)