Esempio n. 1
0
def update_current_user_info():
    """
    Update the information about the current user.

    Returns:
        flask.Response: Response code.
    """
    user_data = flask.g.current_user

    jsondata = flask.request.json
    if not jsondata.get("user") or not isinstance(jsondata["user"], dict):
        flask.abort(status=400)
    indata = jsondata["user"]
    validation = utils.basic_check_indata(
        indata,
        user_data,
        ("_id", "api_key", "api_salt", "auth_ids", "email", "permissions"),
    )
    if not validation.result:
        flask.abort(status=validation.status)

    is_different = False
    for field in indata:
        if indata[field] != user_data[field]:
            is_different = True
            break
    user_data.update(indata)

    if is_different:
        result = utils.req_commit_to_db("users", "edit", user_data)
        if not result.log or not result.data:
            flask.abort(status=500)

    return flask.Response(status=200)
Esempio n. 2
0
def update_current_user_info():
    """
    Update the information about the current user.

    Returns:
        flask.Response: Response code.
    """
    user_data = flask.g.current_user

    try:
        indata = flask.json.loads(flask.request.data)
    except json.decoder.JSONDecodeError:
        flask.abort(status=400)
    validation = utils.basic_check_indata(
        indata, user_data,
        ('_id', 'api_key', 'api_salt', 'auth_ids', 'email', 'permissions'))
    if not validation[0]:
        flask.abort(status=validation[1])

    user_data.update(indata)

    result = flask.g.db['users'].update_one({'_id': user_data['_id']},
                                            {'$set': user_data})
    if not result.acknowledged:
        flask.current_app.logger.error('User self-update failed: %s', indata)
        flask.Response(status=500)
    else:
        utils.make_log('user', 'edit', 'User self-updated', user_data)

    return flask.Response(status=200)
Esempio n. 3
0
def add_dataset(identifier: str):  # pylint: disable=too-many-branches
    """
    Add a dataset to the given order.

    Args:
        identifier (str): The order to add the dataset to.
    """
    order = utils.req_get_entry("orders", identifier)
    if not order:
        flask.abort(status=404)

    if (not utils.req_has_permission("DATA_MANAGEMENT")
            and flask.g.current_user["_id"] not in order["editors"]):
        flask.abort(status=403)

    new_dataset = structure.dataset()

    jsondata = flask.request.json
    if not jsondata or "dataset" not in jsondata or not isinstance(
            jsondata["dataset"], dict):
        flask.abort(status=400)
    indata = jsondata["dataset"]

    validation = utils.basic_check_indata(indata, new_dataset, ["_id"])
    if not validation.result:
        flask.abort(status=validation.status)

    indata = utils.prepare_for_db(indata)

    new_dataset.update(indata)

    ds_result = utils.req_commit_to_db("datasets", "add", new_dataset)
    if not ds_result.log or not ds_result.data:
        flask.abort(status=500)

    order_result = flask.g.db["orders"].update_one(
        {"_id": order["_id"]}, {"$push": {
            "datasets": new_dataset["_id"]
        }})
    if not order_result.acknowledged:
        flask.current_app.logger.error("Failed to add dataset %s to order %s",
                                       new_dataset["_id"], order["_id"])
        flask.abort(status=500)
    order["datasets"].append(new_dataset["_id"])
    utils.req_make_log_new(
        data_type="order",
        action="edit",
        comment="Dataset added",
        data=order,
    )

    return utils.response_json({"_id": ds_result.ins_id})
Esempio n. 4
0
def update_order(identifier: str):  # pylint: disable=too-many-branches
    """
    Update an existing order.

    Args:
        identifier (str): Order uuid.

    Returns:
        flask.Response: Status code of the request.
    """
    order = utils.req_get_entry("orders", identifier)
    if not order:
        flask.abort(status=404)

    # permission check
    if (not utils.req_has_permission("DATA_MANAGEMENT")
            and flask.g.current_user["_id"] not in order["editors"]):
        flask.abort(status=403)

    jsondata = flask.request.json
    if not jsondata or "order" not in jsondata or not isinstance(
            jsondata["order"], dict):
        flask.abort(status=400)
    indata = jsondata["order"]

    validation = utils.basic_check_indata(indata, order, ["_id", "datasets"])
    if not validation.result:
        flask.abort(status=validation.status)

    # DATA_EDIT may not delete itself from editors
    if (not utils.req_has_permission("DATA_MANAGEMENT")
            and indata.get("editors")
            and str(flask.g.current_user["_id"]) not in indata["editors"]):
        flask.abort(status=400)

    # convert all incoming uuids to uuid.UUID
    indata = utils.prepare_for_db(indata)

    is_different = False
    for field in indata:
        if indata[field] != order[field]:
            is_different = True
            break

    order.update(indata)

    if indata and is_different:
        result = utils.req_commit_to_db("orders", "edit", order)
        if not result.log or not result.data:
            flask.abort(status=500)

    return flask.Response(status=200)
Esempio n. 5
0
def update_dataset(identifier):
    """
    Update a dataset with new values.

    Args:
        identifier (str): uuid for the wanted dataset

    Returns:
        flask.Response: success: 200, failure: 400
    """
    perm_status = utils.req_check_permissions(["DATA_EDIT"])
    if perm_status != 200:
        flask.abort(status=perm_status)

    dataset = utils.req_get_entry("datasets", identifier)
    if not dataset:
        flask.abort(status=404)
    # permissions
    order = flask.g.db["orders"].find_one({"datasets": dataset["_id"]})
    if (
        not utils.req_has_permission("DATA_MANAGEMENT")
        and flask.g.current_user["_id"] not in order["editors"]
    ):
        flask.abort(status=403)

    jsondata = flask.request.json
    if not jsondata or "dataset" not in jsondata or not isinstance(jsondata["dataset"], dict):
        flask.abort(status=400)
    indata = jsondata["dataset"]

    validation = utils.basic_check_indata(indata, dataset, prohibited=("_id"))
    if not validation.result:
        flask.abort(status=validation.status)

    indata = utils.prepare_for_db(indata)

    is_different = False
    for field in indata:
        if indata[field] != dataset[field]:
            is_different = True
            break

    dataset.update(indata)

    if indata and is_different:
        result = utils.req_commit_to_db("datasets", "edit", dataset)
        if not result.log or not result.data:
            flask.abort(status=500)

    return flask.Response(status=200)
Esempio n. 6
0
def update_user_info(identifier: str):
    """
    Update the information about a user.

    Requires USER_MANAGEMENT.

    Args:
        identifier (str): The uuid of the user to modify.

    Returns:
        flask.Response: Response code.
    """
    perm_status = utils.req_check_permissions(["USER_MANAGEMENT"])
    if perm_status != 200:
        flask.abort(status=perm_status)

    user_data = utils.req_get_entry("users", identifier)
    if not user_data:
        flask.abort(status=404)

    jsondata = flask.request.json
    if not jsondata.get("user") or not isinstance(jsondata["user"], dict):
        flask.abort(status=400)
    indata = jsondata["user"]

    validation = utils.basic_check_indata(
        indata, user_data, ("_id", "api_key", "api_salt", "auth_ids"))
    if not validation.result:
        flask.abort(status=validation.status)

    if "email" in indata:
        old_user = flask.g.db["users"].find_one({"email": indata["email"]})
        if old_user and old_user.get("_id") != user_data["_id"]:
            flask.current_app.logger.debug("User already exists")
            flask.abort(status=409)

    # Avoid "updating" and making log if there are no changes
    is_different = False
    for field in indata:
        if indata[field] != user_data[field]:
            is_different = True
            break
    user_data.update(indata)

    if is_different:
        result = utils.req_commit_to_db("users", "edit", user_data)
        if not result.log or not result.data:
            flask.abort(status=500)

    return flask.Response(status=200)
Esempio n. 7
0
def add_user():
    """
    Add a user.

    Returns:
        flask.Response: Information about the user as json.
    """
    perm_status = utils.req_check_permissions(["USER_ADD"])
    if perm_status != 200:
        flask.abort(status=perm_status)

    new_user = structure.user()
    jsondata = flask.request.json
    if not jsondata.get("user") or not isinstance(jsondata["user"], dict):
        flask.abort(status=400)
    indata = jsondata["user"]

    validation = utils.basic_check_indata(
        indata, new_user, ("_id", "api_key", "api_salt", "auth_ids"))
    if not validation.result:
        flask.abort(status=validation.status)

    indata = utils.prepare_for_db(indata)
    if not indata:
        flask.abort(status=400)

    if "email" not in indata:
        flask.current_app.logger.debug("Email must be set")
        flask.abort(status=400)

    old_user = flask.g.db["users"].find_one({"email": indata["email"]})
    if old_user:
        flask.current_app.logger.debug("User already exists")
        flask.abort(status=400)

    if not utils.req_has_permission(
            "USER_MANAGEMENT") and "permissions" in indata:
        flask.current_app.logger.debug(
            "USER_MANAGEMENT required for permissions")
        flask.abort(403)

    new_user.update(indata)

    new_user["auth_ids"] = [new_user["email"]]

    result = utils.req_commit_to_db("users", "add", new_user)
    if not result.log or not result.data:
        flask.abort(status=500)

    return utils.response_json({"_id": result.ins_id})
Esempio n. 8
0
def add_user():
    """
    Add a user.

    Returns:
        flask.Response: Information about the user as json.
    """
    if not has_permission('USER_ADD'):
        flask.abort(403)

    new_user = structure.user()
    try:
        indata = flask.json.loads(flask.request.data)
    except json.decoder.JSONDecodeError:
        flask.abort(status=400)
    validation = utils.basic_check_indata(
        indata, new_user, ('_id', 'api_key', 'api_salt', 'auth_ids'))
    if not validation.result:
        flask.abort(status=validation.status)

    if 'email' not in indata:
        flask.current_app.logger.debug('Email must be set')
        flask.abort(status=400)

    old_user = flask.g.db['users'].find_one({'email': indata['email']})
    if old_user:
        flask.current_app.logger.debug('User already exists')
        flask.abort(status=400)

    if not has_permission('USER_MANAGEMENT') and 'permissions' in indata:
        flask.current_app.logger.debug(
            'USER_MANAGEMENT required for permissions')
        flask.abort(403)

    new_user.update(indata)

    new_user['auth_ids'] = [f'{new_user["_id"]}::local']

    result = flask.g.db['users'].insert_one(new_user)
    if not result.acknowledged:
        flask.current_app.logger.error('User Addition failed: %s',
                                       new_user['email'])
        flask.Response(status=500)
    else:
        utils.make_log('user', 'add', 'User added by admin', new_user)

    return utils.response_json({'_id': result.inserted_id})
Esempio n. 9
0
def add_collection():
    """
    Add a collection.

    Returns:
        flask.Response: Json structure with the ``_id`` of the collection.
    """
    perm_status = utils.req_check_permissions(["DATA_EDIT"])
    if perm_status != 200:
        flask.abort(status=perm_status)

    # create new collection
    collection = structure.collection()

    jsondata = flask.request.json
    if not jsondata or "collection" not in jsondata or not isinstance(
            jsondata["collection"], dict):
        flask.abort(status=400)
    indata = jsondata["collection"]

    # indata validation
    validation = utils.basic_check_indata(indata,
                                          collection,
                                          prohibited=["_id"])
    if not validation.result:
        flask.abort(status=validation.status)

    if not indata.get("editors"):
        indata["editors"] = [flask.g.current_user["_id"]]
    # add current user if missing and only DATA_EDIT
    elif (not utils.req_has_permission("DATA_MANAGEMENT")
          and str(flask.g.current_user["_id"]) not in indata["editors"]):
        indata["editors"].append(flask.g.current_user["_id"])

    indata = utils.prepare_for_db(indata)

    collection.update(indata)

    # add to db
    result = utils.req_commit_to_db("collections", "add", collection)
    if not result.log or not result.data:
        flask.abort(status=500)

    return utils.response_json({"_id": result.ins_id})
Esempio n. 10
0
def add_order():
    """
    Add an order.

    Returns:
        flask.Response: Json structure with ``_id`` of the added order.
    """
    # create new order
    new_order = structure.order()

    jsondata = flask.request.json
    if not jsondata or "order" not in jsondata or not isinstance(
            jsondata["order"], dict):
        flask.abort(status=400)
    indata = jsondata["order"]

    validation = utils.basic_check_indata(indata, new_order,
                                          ["_id", "datasets"])
    if not validation.result:
        flask.abort(status=validation.status)

    # add current user to editors if no editors are defined
    if not indata.get("editors"):
        indata["editors"] = [flask.g.current_user["_id"]]
    # add current user if missing and only DATA_EDIT
    elif (not utils.req_has_permission("DATA_MANAGEMENT")
          and str(flask.g.current_user["_id"]) not in indata["editors"]):
        indata["editors"].append(flask.g.current_user["_id"])

    # convert all incoming uuids to uuid.UUID
    indata = utils.prepare_for_db(indata)

    new_order.update(indata)

    result = utils.req_commit_to_db("orders", "add", new_order)
    if not result.log or not result.data:
        flask.abort(status=500)

    return utils.response_json({"_id": result.ins_id})
Esempio n. 11
0
    if not has_permission('USER_MANAGEMENT'):
        flask.abort(403)

    try:
        user_uuid = utils.str_to_uuid(identifier)
    except ValueError:
        flask.abort(status=404)

    if not (user_data := flask.g.db['users'].find_one({'_id': user_uuid})):  # pylint: disable=superfluous-parens
        flask.abort(status=404)

    try:
        indata = flask.json.loads(flask.request.data)
    except json.decoder.JSONDecodeError:
        flask.abort(status=400)
    validation = utils.basic_check_indata(
        indata, user_data, ('_id', 'api_key', 'api_salt', 'auth_ids'))

    if not validation.result:
        flask.abort(status=validation.status)

    if 'email' in indata:
        old_user = flask.g.db['users'].find_one({'email': indata['email']})
        if old_user and old_user['_id'] != user_data['_id']:
            flask.current_app.logger.debug('User already exists')
            flask.abort(status=400)

    # Avoid "updating" and making log if there are no changes
    is_different = False
    for field in indata:
        if indata[field] != user_data[field]:
            is_different = True
Esempio n. 12
0
def update_collection(identifier):
    """
    Update a collection.

    Args:
        identifier (str): The collection uuid.

    Returns:
        flask.Response: Status code.
    """
    perm_status = utils.req_check_permissions(["DATA_EDIT"])
    if perm_status != 200:
        flask.abort(status=perm_status)

    collection = utils.req_get_entry("collections", identifier)
    if not collection:
        flask.abort(status=404)

    jsondata = flask.request.json
    if not jsondata or "collection" not in jsondata or not isinstance(
            jsondata["collection"], dict):
        flask.abort(status=400)
    indata = jsondata["collection"]

    # permission check
    if (not utils.req_has_permission("DATA_MANAGEMENT")
            and flask.g.current_user["_id"] not in collection["editors"]):
        flask.current_app.logger.debug(
            "Unauthorized update attempt (collection %s, user %s)",
            collection["_id"],
            flask.g.current_user["_id"],
        )
        flask.abort(status=403)

    # indata validation
    validation = utils.basic_check_indata(indata,
                                          collection,
                                          prohibited=["_id"])
    if not validation.result:
        flask.abort(status=validation.status)

    # DATA_EDIT may not delete itself from editors
    if (not utils.req_has_permission("DATA_MANAGEMENT")
            and indata.get("editors")
            and str(flask.g.current_user["_id"]) not in indata["editors"]):
        flask.abort(status=400)

    indata = utils.prepare_for_db(indata)

    is_different = False
    for field in indata:
        if indata[field] != collection[field]:
            is_different = True
            break

    if indata and is_different:
        collection.update(indata)
        result = utils.req_commit_to_db("collections", "edit", collection)
        if not result.log or not result.data:
            flask.abort(status=500)

    return flask.Response(status=200)