Beispiel #1
0
async def read_global(
    request: Request,
    global_var: UUID,
    to_decrypt: str = "false",
    global_col: AsyncIOMotorCollection = Depends(get_mongo_c)):
    """
    Returns the Global Variable for the specified id.
    """
    walkoff_db = get_mongo_d(request)
    curr_user_id = await get_jwt_identity(request)

    global_variable = await mongo_helpers.get_item(global_col, GlobalVariable,
                                                   global_var)

    to_read = await auth_check(global_variable, curr_user_id, "read",
                               walkoff_db)
    if to_read:
        if to_decrypt == "false":
            return global_variable.value
        else:
            key = config.get_from_file(config.ENCRYPTION_KEY_PATH)  #, 'rb')
            # for testing
            try:
                key = key.encode('utf-8')
                key = base64.b64encode(key)
            except:
                key = key
            return fernet_decrypt(key, global_variable.value)
    else:
        raise UnauthorizedException("read data for", "Global Variable",
                                    global_variable.name)
Beispiel #2
0
async def update_personal_user(
        *,
        username: str,
        walkoff_db: AsyncIOMotorDatabase = Depends(get_mongo_d),
        request: Request,
        new_user: EditPersonalUser):
    user_col = walkoff_db.users
    curr_id = await get_jwt_identity(request)
    user_obj = await mongo_helpers.get_item(user_col,
                                            UserModel,
                                            username,
                                            projection=ignore_password)
    if not user_obj:
        raise DoesNotExistException("update personal data", "User", username)

    if str(curr_id) == str(user_obj.id):
        d = dict(new_user)
        d.update({
            "id_": await get_jwt_identity(request),
            "roles": [],
            "hashed": False
        })

        return await update_user(walkoff_db=walkoff_db,
                                 user_id=curr_id,
                                 new_user=EditUser(**d),
                                 request=request)
    else:
        raise UnauthorizedException("edit personal data for", "User",
                                    user_obj.username)
Beispiel #3
0
async def update_global(request: Request, updated_global: GlobalVariable, global_var: UUID,
                        global_col: AsyncIOMotorCollection = Depends(get_mongo_c)):
    """
    Updates a specific Global Variable (fetched by id) and returns it.
    """
    walkoff_db = get_mongo_d(request)
    curr_user_id = await get_jwt_identity(request)

    old_global = await mongo_helpers.get_item(global_col, GlobalVariable, global_var)
    if not old_global:
        raise DoesNotExistException("update", "Global Variable", global_var)
    global_id = old_global.id_

    new_permissions = updated_global.permissions
    access_level = new_permissions.access_level

    to_update = await auth_check(old_global, curr_user_id, "update", walkoff_db)
    if to_update:
        if access_level == AccessLevel.CREATOR_ONLY:
            updated_global.permissions = await creator_only_permissions(curr_user_id)
        elif access_level == AccessLevel.EVERYONE:
            updated_global.permissions = await default_permissions(curr_user_id, walkoff_db, "global_variables")
        elif access_level == AccessLevel.ROLE_BASED:
            await append_super_and_internal(updated_global.permissions)
            updated_global.permissions.creator = curr_user_id

        # try:
        key = config.get_from_file(config.ENCRYPTION_KEY_PATH, mode='rb')
        updated_global.value = fernet_encrypt(key, updated_global.value)
        return await mongo_helpers.update_item(global_col, GlobalVariable, global_id, updated_global)
        # except Exception as e:
        #     logger.info(e)
        #     raise UniquenessException("global_variable", "update", updated_global.name)
    else:
        raise UnauthorizedException("update data for", "Global Variable", old_global.name)
Beispiel #4
0
async def update_workflow(
        *,
        walkoff_db: AsyncIOMotorDatabase = Depends(get_mongo_d),
        workflow_name_id: Union[UUID, str],
        request: Request,
        updated_workflow: WorkflowModel):
    """
    Updates a specific Workflow object (fetched by id or name) and returns it.
    """
    workflow_col = walkoff_db.workflows
    curr_user_id = await get_jwt_identity(request)
    old_workflow = await mongo_helpers.get_item(workflow_col, WorkflowModel,
                                                workflow_name_id)

    to_update = await auth_check(old_workflow,
                                 curr_user_id,
                                 "update",
                                 walkoff_db=walkoff_db)
    if to_update:
        await set_permissions(updated_workflow, curr_user_id, walkoff_db)
        try:
            return await mongo_helpers.update_item(workflow_col, WorkflowModel,
                                                   old_workflow.id_,
                                                   updated_workflow)
        except:
            raise UniquenessException("workflow", "update",
                                      updated_workflow.name)

    else:
        raise UnauthorizedException("update data for", "Workflow",
                                    old_workflow.name)
Beispiel #5
0
async def read_workflow(
        *,
        walkoff_db: AsyncIOMotorDatabase = Depends(get_mongo_d),
        mode: str = None,
        workflow_name_id: Union[UUID, str],
        request: Request):
    """
    Returns the Workflow for the specified id or name.
    """
    workflow_col = walkoff_db.workflows
    curr_user_id = await get_jwt_identity(request)

    workflow = await mongo_helpers.get_item(workflow_col, WorkflowModel,
                                            workflow_name_id)

    to_read = await auth_check(workflow,
                               curr_user_id,
                               "read",
                               walkoff_db=walkoff_db)
    if to_read:
        if mode == "export":
            workflow_str = workflow.json().encode('utf-8')

            workflow_file = BytesIO()
            workflow_file.write(workflow_str)
            workflow_file.seek(0)
            return StreamingResponse(workflow_file,
                                     media_type="application/json")
        else:
            return workflow
    else:
        raise UnauthorizedException("read data for", "Workflow", workflow.name)
Beispiel #6
0
async def read_role(*,
                    role_col: AsyncIOMotorCollection = Depends(get_mongo_c),
                    role_id: Union[int, str]):
    """
    Returns the Role for the specified role name or ID
    """
    role = await mongo_helpers.get_item(role_col, RoleModel, role_id)
    role_string = f"{role.name} ({role.id_})"
    if role.id_ in hidden_roles:
        raise UnauthorizedException("read", "Role", role_string)
    else:
        return role
Beispiel #7
0
async def create_user(*,
                      user_col: AsyncIOMotorCollection = Depends(get_mongo_c),
                      new_user: UserModel):
    """
    Creates a new User and returns it.
    """
    if DefaultRoleUUID.INTERNAL_USER.value in new_user.roles or \
            DefaultRoleUUID.SUPER_ADMIN.value in new_user.roles:
        raise UnauthorizedException("create a user with the roles", "User",
                                    "internal_user or super_user")
    else:
        return await mongo_helpers.create_item(user_col,
                                               UserModel,
                                               new_user,
                                               projection=ignore_password)
Beispiel #8
0
async def read_user(*,
                    user_col: AsyncIOMotorCollection = Depends(get_mongo_c),
                    user_id: Union[UUID, str]):
    """
    Returns the User for the specified username.
    """
    if user_id == "internal_user" or user_id == DefaultUserUUID.INTERNAL_USER.value:
        raise UnauthorizedException("get data for", "User", "internal_user")
    else:
        return await mongo_helpers.get_item(
            user_col,
            UserModel,
            user_id,
            query={"id_": {
                "$nin": hidden_users
            }},
            projection=ignore_password)
Beispiel #9
0
async def read_personal_user(
        *,
        username: str,
        user_col: AsyncIOMotorCollection = Depends(get_mongo_c),
        request: Request):
    curr_id = await get_jwt_identity(request)
    user_obj = await mongo_helpers.get_item(user_col,
                                            UserModel,
                                            username,
                                            projection=ignore_password)
    if not user_obj:
        raise DoesNotExistException("read personal data", "User", username)

    if str(curr_id) == str(user_obj.id_):
        return user_obj
    else:
        raise UnauthorizedException("view personal data for", "User",
                                    user_obj.username)
Beispiel #10
0
async def delete_global(request: Request, global_var: UUID,
                        global_col: AsyncIOMotorCollection = Depends(get_mongo_c)):
    """
    Deletes a specific Global Variable (fetched by id).
    """
    walkoff_db = get_mongo_d(request)
    curr_user_id = await get_jwt_identity(request)

    global_variable = await mongo_helpers.get_item(global_col, GlobalVariable, global_var)
    if not global_variable:
        raise DoesNotExistException("delete", "Global Variable", global_var)
    global_id = global_variable.id_

    to_delete = await auth_check(global_variable, curr_user_id, "delete", walkoff_db)
    if to_delete:
        return await mongo_helpers.delete_item(global_col, GlobalVariable, global_id)
    else:
        raise UnauthorizedException("delete data for", "Global Variable", global_variable.name)
Beispiel #11
0
async def delete_role(*,
                      role_col: AsyncIOMotorCollection = Depends(get_mongo_c),
                      role_id: Union[int, str]):
    """
    Deletes a role.
    """
    role = await mongo_helpers.get_item(role_col,
                                        RoleModel,
                                        role_id,
                                        raise_exc=False)
    if not role:
        raise DoesNotExistException("delete", "Role", role_id)
    role_string = f"{role.name} ({role.id_})"

    if role.id_ in DefaultRoleUUIDS:
        raise UnauthorizedException("delete", "role", role_string)
    else:
        return await mongo_helpers.delete_item(role_col, RoleModel, role_id)
Beispiel #12
0
async def delete_user(*,
                      user_col: AsyncIOMotorCollection = Depends(get_mongo_c),
                      user_id: Union[UUID, str],
                      request: Request):
    user = await mongo_helpers.get_item(user_col,
                                        UserModel,
                                        user_id,
                                        projection=ignore_password,
                                        raise_exc=False)
    if not user:
        raise DoesNotExistException("delete", "User", user_id)
    user_string = f"{user.username} ({user.id_})"

    if user.id_ in (DefaultUserUUID.INTERNAL_USER.value, DefaultUserUUID.SUPER_ADMIN.value) \
            or user.id_ == await get_jwt_identity(request) \
            or DefaultRoleUUID.INTERNAL_USER.value in user.roles \
            or DefaultRoleUUID.SUPER_ADMIN.value in user.roles:
        raise UnauthorizedException("delete", "User", user_string)
    else:
        return await mongo_helpers.delete_item(user_col, UserModel, user_id)
Beispiel #13
0
async def get_workflow_status(
        *,
        walkoff_db: AsyncIOMotorDatabase = Depends(get_mongo_d),
        execution: UUID,
        request: Request):
    """
    Returns status information of a workflow currently executing WALKOFF.
    """
    workflow_col = walkoff_db.workflows
    wfq_col = walkoff_db.workflowqueue
    curr_user_id = await get_jwt_identity(request)
    wf_status: WorkflowStatus = await mongo_helpers.get_item(
        wfq_col, WorkflowStatus, execution, id_key="execution_id")
    wf = await mongo_helpers.get_item(workflow_col, WorkflowModel,
                                      wf_status.workflow_id)
    if await auth_check(wf, curr_user_id, "read", walkoff_db=walkoff_db):
        wf_status.to_response()
        return wf_status
    else:
        raise UnauthorizedException("read", "Workflow Status",
                                    wf_status.workflow_id)
Beispiel #14
0
async def upload_workflow_helper(curr_user_id: UUID, old_workflow,
                                 new_workflow: WorkflowModel, walkoff_db):
    to_update = await auth_check(old_workflow,
                                 curr_user_id,
                                 "update",
                                 walkoff_db=walkoff_db)
    if not to_update:
        raise UnauthorizedException("import", "Workflow", old_workflow['name'])

    to_regenerate = dict(new_workflow)
    try:
        regenerate_workflow_ids(to_regenerate)
    except (KeyError, ValueError, TypeError) as e:
        raise InvalidInputException("import",
                                    "workflow",
                                    new_workflow.id_,
                                    errors={"exception": str(e)})
    new_workflow = WorkflowModel(**to_regenerate)

    new_workflow.name += "." + str(new_workflow.id_)

    return new_workflow
Beispiel #15
0
async def update_role(*,
                      role_col: AsyncIOMotorCollection = Depends(get_mongo_c),
                      role_id: Union[int, str],
                      new_role: RoleModel):
    """
    Updates a role and returns it.
    """
    role: RoleModel = await mongo_helpers.get_item(role_col,
                                                   RoleModel,
                                                   role_id,
                                                   raise_exc=False)
    if not role:
        raise DoesNotExistException("update", "Role", role_id)

    role_string = f"{role.name} ({role.id_})"

    if role.id_ in DefaultRoleUUIDS:
        raise UnauthorizedException("update", "role", role_string)

    if new_role.name:
        existing_user = await mongo_helpers.get_item(role_col,
                                                     RoleModel,
                                                     new_role.name,
                                                     raise_exc=False)
        if existing_user:
            raise UniquenessException(
                "change role for", "Role", f"{role_string} -> "
                f"{new_role.name} ({role.id_})")
        else:
            role.name = new_role.name

    if new_role.description:
        role.description = new_role.description

    if new_role.resources:
        role.resources = new_role.resources

    return await mongo_helpers.update_item(role_col, RoleModel, role_id, role)
Beispiel #16
0
async def copy_workflow_helper(curr_user_id: UUID, old_workflow, new_name: str,
                               walkoff_db: AsyncIOMotorDatabase):
    to_update = await auth_check(old_workflow,
                                 curr_user_id,
                                 "update",
                                 walkoff_db=walkoff_db)
    if not to_update:
        raise UnauthorizedException("copy", "Workflow", old_workflow["name"])

    copied_workflow = deepcopy(old_workflow)
    workflow_dict = dict(copied_workflow)
    regenerate_workflow_ids(workflow_dict)
    copied_workflow = WorkflowModel(**workflow_dict)

    if new_name:
        copied_workflow.name = new_name
    else:
        copied_workflow.name += " (Copy)"

    # TODO: UI element for new permissions for copied workflows
    # copied_workflow.permissions = new_workflow.permissions

    return copied_workflow
Beispiel #17
0
async def delete_workflow(
        *,
        walkoff_db: AsyncIOMotorDatabase = Depends(get_mongo_d),
        request: Request,
        workflow_name_id: Union[UUID, str]):
    """
    Deletes a specific Workflow object (fetched by id or name).
    """
    workflow_col = walkoff_db.workflows
    curr_user_id = await get_jwt_identity(request)

    workflow = await mongo_helpers.get_item(workflow_col, WorkflowModel,
                                            workflow_name_id)
    to_delete = await auth_check(workflow,
                                 curr_user_id,
                                 "delete",
                                 walkoff_db=walkoff_db)
    if to_delete:
        return await mongo_helpers.delete_item(workflow_col, WorkflowModel,
                                               workflow.id_)
    else:
        raise UnauthorizedException("delete data for", "Workflow",
                                    workflow.name)
Beispiel #18
0
async def update_user(*,
                      walkoff_db: AsyncIOMotorDatabase = Depends(get_mongo_d),
                      user_id: Union[UUID, str],
                      new_user: EditUser,
                      request: Request):
    """
    Updates the User for the specified username and returns it.
    """
    user_col = walkoff_db.users
    role_col = walkoff_db.roles

    if user_id == DefaultUserUUID.INTERNAL_USER or user_id == "internal_user":
        raise UnauthorizedException("update", "User", "internal_user")

    user: UserModel = await mongo_helpers.get_item(user_col,
                                                   UserModel,
                                                   user_id,
                                                   raise_exc=False)
    if not user:
        raise DoesNotExistException("update", "User", user_id)

    current_user: UserModel = await mongo_helpers.get_item(
        user_col, UserModel, await get_jwt_identity(request))
    user_string = f"{user.username} ({user.id_})"

    if await user.verify_password(new_user.old_password):
        if user.id_ == DefaultUserUUID.SUPER_ADMIN.value \
                or DefaultRoleUUID.SUPER_ADMIN.value in user.roles:
            if DRoles.SUPER_ADMIN.value not in current_user.roles:
                raise UnauthorizedException("edit values for", "User",
                                            "super_admin")
        else:
            if new_user.roles:
                role_ids = [
                    role.id_ for role in await mongo_helpers.get_all_items(
                        role_col, RoleModel)
                ]
                if set(new_user.roles) <= set(role_ids):
                    user.roles = new_user.roles
                else:
                    invalid_roles = set(role_ids) - set(new_user.roles)
                    raise InvalidInputException(
                        "edit roles for",
                        "User",
                        user_string,
                        errors=
                        f"The following roles do not exist: {invalid_roles}")
            user.active = new_user.active

        if new_user.new_username:
            existing_user = await mongo_helpers.get_item(user_col,
                                                         UserModel,
                                                         new_user.new_username,
                                                         raise_exc=False)
            if existing_user:
                raise UniquenessException(
                    "change username for", "User", f"{user_string} -> "
                    f"{new_user.new_username} ({user_id})")
            else:
                user.username = new_user.new_username

        if new_user.new_password:
            await user.hash_and_set_password(new_user.new_password)

        return await mongo_helpers.update_item(user_col, UserModel, user_id,
                                               user)
    else:
        raise UnauthorizedException("update the data", "User",
                                    f"{new_user.username}")