Exemple #1
0
async def migrate_database(resources_repo=Depends(get_repository(ResourceRepository)),
                           shared_services_migration=Depends(get_repository(SharedServiceMigration)),
                           workspace_migration=Depends(get_repository(WorkspaceMigration))):
    try:
        migrations = list()
        logging.info("PR 1030.")
        resources_repo.rename_field_name('resourceTemplateName', 'templateName')
        resources_repo.rename_field_name('resourceTemplateVersion', 'templateVersion')
        resources_repo.rename_field_name('resourceTemplateParameters', 'properties')
        migrations.append(Migration(issueNumber="PR 1030", status="Executed"))

        logging.info("PR 1031.")
        resources_repo.rename_field_name('workspaceType', 'templateName')
        resources_repo.rename_field_name('workspaceServiceType', 'templateName')
        resources_repo.rename_field_name('userResourceType', 'templateName')
        migrations.append(Migration(issueNumber="PR 1031", status="Executed"))

        logging.info("PR 1717. - Shared services")
        migration_status = "Executed" if shared_services_migration.deleteDuplicatedSharedServices() else "Skipped"
        migrations.append(Migration(issueNumber="PR 1717", status=migration_status))

        logging.info("PR 1726. - Authentication needs to be in properties so we can update them")
        migration_status = "Executed" if workspace_migration.moveAuthInformationToProperties() else "Skipped"
        migrations.append(Migration(issueNumber="PR 1726", status=migration_status))

        return MigrationOutList(migrations=migrations)
    except Exception as e:
        logging.error(f"Failed to migrate database: {e}")
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))
Exemple #2
0
async def create_workspace(
    workspace_create: WorkspaceInCreate,
    response: Response,
    user=Depends(get_current_admin_user),
    workspace_repo=Depends(get_repository(WorkspaceRepository)),
    resource_template_repo=Depends(get_repository(ResourceTemplateRepository)),
    operations_repo=Depends(get_repository(OperationRepository))
) -> OperationInResponse:
    try:
        # TODO: This requires Directory.ReadAll ( Application.Read.All ) to be enabled in the Azure AD application to enable a users workspaces to be listed. This should be made optional.
        auth_info = extract_auth_information(workspace_create.properties)
        workspace, resource_template = workspace_repo.create_workspace_item(
            workspace_create, auth_info, user.id)
    except (ValidationError, ValueError) as e:
        logging.error(f"Failed to create workspace model instance: {e}")
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST,
                            detail=str(e))

    operation = await save_and_deploy_resource(
        resource=workspace,
        resource_repo=workspace_repo,
        operations_repo=operations_repo,
        resource_template_repo=resource_template_repo,
        user=user,
        resource_template=resource_template)
    response.headers["Location"] = construct_location_header(operation)

    return OperationInResponse(operation=operation)
Exemple #3
0
async def create_user_resource(
    response: Response,
    user_resource_create: UserResourceInCreate,
    user_resource_repo=Depends(get_repository(UserResourceRepository)),
    resource_template_repo=Depends(get_repository(ResourceTemplateRepository)),
    operations_repo=Depends(get_repository(OperationRepository)),
    user=Depends(get_current_workspace_owner_or_researcher_user),
    workspace=Depends(get_deployed_workspace_by_id_from_path),
    workspace_service=Depends(get_deployed_workspace_service_by_id_from_path)
) -> OperationInResponse:

    try:
        user_resource, resource_template = user_resource_repo.create_user_resource_item(
            user_resource_create, workspace.id, workspace_service.id,
            workspace_service.templateName, user.id)
    except (ValidationError, ValueError) as e:
        logging.error(f"Failed create user resource model instance: {e}")
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST,
                            detail=str(e))

    operation = await save_and_deploy_resource(
        resource=user_resource,
        resource_repo=user_resource_repo,
        operations_repo=operations_repo,
        resource_template_repo=resource_template_repo,
        user=user,
        resource_template=resource_template)
    response.headers["Location"] = construct_location_header(operation)

    return OperationInResponse(operation=operation)
Exemple #4
0
async def delete_shared_service(
    response: Response,
    user=Depends(get_current_admin_user),
    shared_service=Depends(get_shared_service_by_id_from_path),
    operations_repo=Depends(get_repository(OperationRepository)),
    shared_service_repo=Depends(get_repository(SharedServiceRepository)),
    resource_template_repo=Depends(get_repository(ResourceTemplateRepository))
) -> OperationInResponse:
    if shared_service.isEnabled:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=strings.SHARED_SERVICE_NEEDS_TO_BE_DISABLED_BEFORE_DELETION)

    resource_template = resource_template_repo.get_template_by_name_and_version(
        shared_service.templateName, shared_service.templateVersion,
        ResourceType.SharedService)

    operation = await send_uninstall_message(
        resource=shared_service,
        resource_repo=shared_service_repo,
        operations_repo=operations_repo,
        resource_type=ResourceType.SharedService,
        resource_template_repo=resource_template_repo,
        user=user,
        resource_template=resource_template)

    response.headers["Location"] = construct_location_header(operation)

    return OperationInResponse(operation=operation)
Exemple #5
0
async def create_shared_service(
    response: Response,
    shared_service_input: SharedServiceInCreate,
    user=Depends(get_current_admin_user),
    shared_services_repo=Depends(get_repository(SharedServiceRepository)),
    resource_template_repo=Depends(get_repository(ResourceTemplateRepository)),
    operations_repo=Depends(get_repository(OperationRepository))
) -> OperationInResponse:
    try:
        shared_service, resource_template = shared_services_repo.create_shared_service_item(
            shared_service_input)
    except (ValidationError, ValueError) as e:
        logging.error(f"Failed create shared service model instance: {e}")
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST,
                            detail=str(e))
    except DuplicateEntity as e:
        logging.error(f"Shared service already exists: {e}")
        raise HTTPException(status_code=status.HTTP_409_CONFLICT,
                            detail=str(e))

    operation = await save_and_deploy_resource(
        resource=shared_service,
        resource_repo=shared_services_repo,
        operations_repo=operations_repo,
        resource_template_repo=resource_template_repo,
        user=user,
        resource_template=resource_template)
    response.headers["Location"] = construct_location_header(operation)

    return OperationInResponse(operation=operation)
Exemple #6
0
async def delete_user_resource(
    response: Response,
    user=Depends(get_current_workspace_owner_or_researcher_user),
    user_resource=Depends(get_user_resource_by_id_from_path),
    workspace_service=Depends(get_workspace_service_by_id_from_path),
    user_resource_repo=Depends(get_repository(UserResourceRepository)),
    operations_repo=Depends(get_repository(OperationRepository)),
    resource_template_repo=Depends(get_repository(ResourceTemplateRepository))
) -> OperationInResponse:
    validate_user_is_workspace_owner_or_resource_owner(user, user_resource)

    if user_resource.isEnabled:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=strings.USER_RESOURCE_NEEDS_TO_BE_DISABLED_BEFORE_DELETION)

    resource_template = resource_template_repo.get_template_by_name_and_version(
        user_resource.templateName, user_resource.templateVersion,
        ResourceType.UserResource, workspace_service.templateName)

    operation = await send_uninstall_message(
        resource=user_resource,
        resource_repo=user_resource_repo,
        operations_repo=operations_repo,
        resource_type=ResourceType.UserResource,
        resource_template_repo=resource_template_repo,
        user=user,
        resource_template=resource_template)

    response.headers["Location"] = construct_location_header(operation)

    return OperationInResponse(operation=operation)
Exemple #7
0
async def patch_user_resource(
    user_resource_patch: ResourcePatch,
    response: Response,
    user=Depends(get_current_workspace_owner_or_researcher_user),
    user_resource=Depends(get_user_resource_by_id_from_path),
    workspace_service=Depends(get_workspace_service_by_id_from_path),
    user_resource_repo=Depends(get_repository(UserResourceRepository)),
    resource_template_repo=Depends(get_repository(ResourceTemplateRepository)),
    operations_repo=Depends(get_repository(OperationRepository)),
    etag: str = Header(...)
) -> OperationInResponse:
    validate_user_is_workspace_owner_or_resource_owner(user, user_resource)

    try:
        patched_user_resource, resource_template = user_resource_repo.patch_user_resource(
            user_resource, user_resource_patch, etag, resource_template_repo,
            workspace_service.templateName, user)
        operation = await send_resource_request_message(
            resource=patched_user_resource,
            operations_repo=operations_repo,
            resource_repo=user_resource_repo,
            user=user,
            resource_template=resource_template,
            resource_template_repo=resource_template_repo,
            action=RequestAction.Upgrade)

        response.headers["Location"] = construct_location_header(operation)
        return OperationInResponse(operation=operation)
    except CosmosAccessConditionFailedError:
        raise HTTPException(status_code=status.HTTP_409_CONFLICT,
                            detail=strings.ETAG_CONFLICT)
    except ValidationError as v:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST,
                            detail=v.message)
Exemple #8
0
async def get_deployed_workspace_by_id_from_path(
        workspace_id: UUID4 = Path(...),
        workspaces_repo=Depends(get_repository(WorkspaceRepository)),
        operations_repo=Depends(get_repository(OperationRepository))
) -> Workspace:
    try:
        return workspaces_repo.get_deployed_workspace_by_id(
            workspace_id, operations_repo)
    except EntityDoesNotExist:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND,
                            detail=strings.WORKSPACE_DOES_NOT_EXIST)
    except ResourceIsNotDeployed:
        raise HTTPException(status_code=status.HTTP_409_CONFLICT,
                            detail=strings.WORKSPACE_IS_NOT_DEPLOYED)
Exemple #9
0
async def get_openapi_json(workspace_id: str,
                           request: Request,
                           workspace_repo=Depends(
                               get_repository(WorkspaceRepository))):
    global openapi_definitions

    if openapi_definitions[workspace_id] is None:

        openapi_definitions[workspace_id] = get_openapi(
            title=f"{config.PROJECT_NAME} - Workspace {workspace_id}",
            description=config.API_DESCRIPTION,
            version=config.VERSION,
            routes=workspace_router.routes,
            tags=workspace_tags_metadata)

        workspace = workspace_repo.get_workspace_by_id(workspace_id)
        scope = {get_scope(workspace): "List and Get TRE Workspaces"}

        openapi_definitions[workspace_id]['components']['securitySchemes'][
            'oauth2']['flows']['authorizationCode']['scopes'] = scope

        # Add an example into every workspace_id path parameter so users don't have to cut and paste them in.
        for route in openapi_definitions[workspace_id]['paths'].values():
            for verb in route.values():
                # We now have a list of parameters for each route
                for parameter in verb['parameters']:
                    if (parameter['name'] == 'workspace_id'):
                        parameter['schema']['example'] = workspace_id

    return openapi_definitions[workspace_id]
Exemple #10
0
async def retrieve_workspace_service_operations_by_workspace_service_id(
        workspace_service=Depends(get_workspace_service_by_id_from_path),
        operations_repo=Depends(get_repository(OperationRepository))
) -> OperationInList:
    return OperationInList(
        operations=operations_repo.get_operations_by_resource_id(
            resource_id=workspace_service.id))
async def get_user_resource_templates_for_service_template(
    service_template_name: str,
    template_repo=Depends(get_repository(ResourceTemplateRepository))
) -> ResourceTemplateInformationInList:
    template_infos = template_repo.get_templates_information(
        ResourceType.UserResource, service_template_name)
    return ResourceTemplateInformationInList(templates=template_infos)
Exemple #12
0
async def retrieve_users_active_workspace_services(
        workspace=Depends(get_workspace_by_id_from_path),
        workspace_services_repo=Depends(
            get_repository(WorkspaceServiceRepository))
) -> WorkspaceServicesInList:
    workspace_services = workspace_services_repo.get_active_workspace_services_for_workspace(
        workspace.id)
    return WorkspaceServicesInList(workspaceServices=workspace_services)
async def retrieve_term(
    terms_to_retrieve: TermRetrieve = Body(..., embed=True),
    ontology_repo: OntologyRepository = Depends(
        get_repository(OntologyRepository)),
) -> dict:
    result = await ontology_repo.retrieve_terms(
        terms_to_retrieve=terms_to_retrieve)
    return {'message': 'Retrieval task completed successfully'}
async def create_new_cleaning(
    new_cleaning: CleaningCreate = Body(..., embed=True),
    cleanings_repo: CleaningsRepository = Depends(
        get_repository(CleaningsRepository)),
) -> CleaningPublic:
    created_cleaning = await cleanings_repo.create_cleaning(
        new_cleaning=new_cleaning)

    return created_cleaning
Exemple #15
0
async def retrieve_user_resource_operations_by_user_resource_id(
        user_resource=Depends(get_user_resource_by_id_from_path),
        user=Depends(get_current_workspace_owner_or_researcher_user),
        operations_repo=Depends(get_repository(OperationRepository))
) -> OperationInList:
    validate_user_is_workspace_owner_or_resource_owner(user, user_resource)
    return OperationInList(
        operations=operations_repo.get_operations_by_resource_id(
            resource_id=user_resource.id))
Exemple #16
0
async def get_operation_by_id_from_path(
        operation_id: UUID4 = Path(...),
        operations_repo=Depends(get_repository(OperationRepository))
) -> Operation:
    try:
        return operations_repo.get_operation_by_id(operation_id=operation_id)
    except EntityDoesNotExist:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND,
                            detail=strings.OPERATION_DOES_NOT_EXIST)
async def get_current_workspace_service_template_by_name(
    service_template_name: str,
    is_update: bool = False,
    template_repo=Depends(get_repository(ResourceTemplateRepository))
) -> WorkspaceServiceTemplateInResponse:
    template = get_current_template_by_name(service_template_name,
                                            template_repo,
                                            ResourceType.WorkspaceService,
                                            is_update=is_update)
    return parse_obj_as(WorkspaceServiceTemplateInResponse, template)
async def register_workspace_service_template(
    template_input: WorkspaceServiceTemplateInCreate,
    template_repo=Depends(get_repository(ResourceTemplateRepository))
) -> ResourceTemplateInResponse:
    try:
        return template_repo.create_and_validate_template(
            template_input, ResourceType.WorkspaceService)
    except EntityVersionExist:
        raise HTTPException(status_code=status.HTTP_409_CONFLICT,
                            detail=strings.WORKSPACE_TEMPLATE_VERSION_EXISTS)
Exemple #19
0
async def register_new_user(new_user: UserCreate = Body(..., embed=True),
                            user_repo: UsersRepository = Depends(
                                get_repository(
                                    UsersRepository))) -> UserPublic:
    created_user = await user_repo.register_new_user(new_user=new_user)

    access_token = AccessToken(
        access_token=auth_service.create_access_token_for_user(
            user=created_user),
        token_type='bearer')
    return UserPublic(**created_user.dict(), access_token=access_token)
Exemple #20
0
async def get_workspace_service_template_by_name_from_path(
        service_template_name: str = Path(...),
        template_repo=Depends(get_repository(ResourceTemplateRepository))
) -> ResourceTemplate:
    try:
        return template_repo.get_current_template(
            service_template_name, ResourceType.WorkspaceService)
    except EntityDoesNotExist:
        raise HTTPException(
            status_code=HTTP_404_NOT_FOUND,
            detail=strings.WORKSPACE_SERVICE_TEMPLATE_DOES_NOT_EXIST)
Exemple #21
0
async def get_workspace_service_by_id_from_path(
        workspace_id: UUID4 = Path(...),
        service_id: UUID4 = Path(...),
        workspace_services_repo=Depends(
            get_repository(WorkspaceServiceRepository))) -> WorkspaceService:
    try:
        return workspace_services_repo.get_workspace_service_by_id(
            workspace_id, service_id)
    except EntityDoesNotExist:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND,
                            detail=strings.WORKSPACE_SERVICE_DOES_NOT_EXIST)
Exemple #22
0
async def get_user_resource_by_id_from_path(
        workspace_id: UUID4 = Path(...),
        service_id: UUID4 = Path(...),
        resource_id: UUID4 = Path(...),
        user_resource_repo=Depends(get_repository(UserResourceRepository))
) -> UserResource:
    try:
        return user_resource_repo.get_user_resource_by_id(
            workspace_id, service_id, resource_id)
    except EntityDoesNotExist:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND,
                            detail=strings.USER_RESOURCE_DOES_NOT_EXIST)
async def get_current_user_resource_template_by_name(
    service_template_name: str,
    user_resource_template_name: str,
    is_update: bool = False,
    template_repo=Depends(get_repository(ResourceTemplateRepository))
) -> UserResourceTemplateInResponse:
    template = get_current_template_by_name(user_resource_template_name,
                                            template_repo,
                                            ResourceType.UserResource,
                                            service_template_name,
                                            is_update=is_update)
    return parse_obj_as(UserResourceTemplateInResponse, template)
async def get_cleaning_by_id(
    id: int,
    cleanings_repo: CleaningsRepository = Depends(
        get_repository(CleaningsRepository))
) -> CleaningPublic:
    cleaning = await cleanings_repo.get_cleaning_by_id(id=id)

    if not cleaning:
        raise HTTPException(status_code=HTTP_404_NOT_FOUND,
                            detail="No cleaning found with that id.")

    return cleaning
Exemple #25
0
async def invoke_action_on_workspace_service(
    response: Response,
    action: str,
    user=Depends(get_current_workspace_owner_user),
    workspace_service=Depends(get_workspace_service_by_id_from_path),
    resource_template_repo=Depends(get_repository(ResourceTemplateRepository)),
    operations_repo=Depends(get_repository(OperationRepository)),
    workspace_service_repo=Depends(get_repository(WorkspaceServiceRepository))
) -> OperationInResponse:
    operation = await send_custom_action_message(
        resource=workspace_service,
        resource_repo=workspace_service_repo,
        custom_action=action,
        resource_type=ResourceType.WorkspaceService,
        operations_repo=operations_repo,
        resource_template_repo=resource_template_repo,
        user=user)

    response.headers["Location"] = construct_location_header(operation)

    return OperationInResponse(operation=operation)
async def update_cleaning_by_id(
    id: int = Path(..., ge=1, title="The ID of the cleaning to update."),
    cleaning_update: CleaningUpdate = Body(..., embed=True),
    cleanings_repo: CleaningsRepository = Depends(
        get_repository(CleaningsRepository)),
) -> CleaningPublic:
    updated_cleaning = await cleanings_repo.update_cleaning(
        id=id, cleaning_update=cleaning_update)
    if not updated_cleaning:
        raise HTTPException(status_code=HTTP_404_NOT_FOUND,
                            detail="No cleaning found with that id.")
    return updated_cleaning
async def delete_cleaning_by_id(
    id: int = Path(..., ge=1, title="The ID of the cleaning to delete."),
    cleanings_repo: CleaningsRepository = Depends(
        get_repository(CleaningsRepository)),
) -> int:
    deleted_id = await cleanings_repo.delete_cleaning_by_id(id=id)

    if not deleted_id:
        raise HTTPException(status_code=HTTP_404_NOT_FOUND,
                            detail="No cleaning found with that id.")

    return deleted_id
Exemple #28
0
async def get_current_shared_service_template_by_name(
    shared_service_template_name: str,
    template_repo=Depends(get_repository(ResourceTemplateRepository))
) -> SharedServiceTemplateInResponse:
    try:
        template = get_current_template_by_name(shared_service_template_name,
                                                template_repo,
                                                ResourceType.SharedService)
        return parse_obj_as(SharedServiceTemplateInResponse, template)
    except EntityDoesNotExist:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=strings.SHARED_SERVICE_TEMPLATE_DOES_NOT_EXIST)
Exemple #29
0
async def get_user_from_token(
    *,
    token: str = Depends(oauth2_scheme),
    user_repo: UsersRepository = Depends(get_repository(UsersRepository)),
) -> Optional[UserInDB]:
    try:
        username = auth_service.get_username_from_token(
            token=token, secret_key=str(SECRET_KEY))
        user = await user_repo.get_user_by_username(username=username)
    except Exception as e:
        raise e

    return user
Exemple #30
0
async def invoke_action_on_user_resource(
    response: Response,
    action: str,
    user_resource=Depends(get_user_resource_by_id_from_path),
    workspace_service=Depends(get_workspace_service_by_id_from_path),
    resource_template_repo=Depends(get_repository(ResourceTemplateRepository)),
    user_resource_repo=Depends(get_repository(UserResourceRepository)),
    operations_repo=Depends(get_repository(OperationRepository)),
    user=Depends(get_current_workspace_owner_or_researcher_user)
) -> OperationInResponse:
    validate_user_is_workspace_owner_or_resource_owner(user, user_resource)
    operation = await send_custom_action_message(
        resource=user_resource,
        resource_repo=user_resource_repo,
        custom_action=action,
        resource_type=ResourceType.UserResource,
        operations_repo=operations_repo,
        resource_template_repo=resource_template_repo,
        user=user,
        parent_service_name=workspace_service.templateName)

    response.headers["Location"] = construct_location_header(operation)

    return OperationInResponse(operation=operation)