diff --git a/resources/functions/tenant-management/index.py b/resources/functions/tenant-management/index.py index c03b8b5..c3074b8 100644 --- a/resources/functions/tenant-management/index.py +++ b/resources/functions/tenant-management/index.py @@ -1,7 +1,6 @@ # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. # SPDX-License-Identifier: Apache-2.0 -# import json import os from http import HTTPStatus import uuid @@ -26,13 +25,6 @@ cors_config = CORSConfig(allow_origin="*", max_age=300) app = APIGatewayHttpResolver(cors=cors_config, enable_validation=True) -# event_bus = boto3.client("events") -# eventbus_name = os.environ["EVENTBUS_NAME"] -# event_source = os.environ["EVENT_SOURCE"] -# onboarding_detail_type = os.environ["ONBOARDING_DETAIL_TYPE"] -# offboarding_detail_type = os.environ["OFFBOARDING_DETAIL_TYPE"] -# activate_detail_type = os.environ["ACTIVATE_DETAIL_TYPE"] -# deactivate_detail_type = os.environ["DEACTIVATE_DETAIL_TYPE"] dynamodb = boto3.resource("dynamodb") tenant_details_table = dynamodb.Table(os.environ["TENANT_DETAILS_TABLE"]) @@ -134,9 +126,6 @@ def delete_tenant(tenantId: Annotated[str, Path(min_length=0)]): try: response = __update_tenant(tenantId, {"sbtaws_active": False}) deleted_tenant = response["Attributes"] - # __create_control_plane_event( - # json.dumps(deleted_tenant), offboarding_detail_type - # ) except dynamodb.meta.client.exceptions.ConditionalCheckFailedException: logger.info(f"received request to update non-existing tenant {tenantId}") raise NotFoundError(f"Tenant {tenantId} not found.") @@ -173,74 +162,6 @@ def __update_tenant(tenantId, tenant): ) -# @app.put("/tenants//deactivate") -# @tracer.capture_method -# def deactivate_tenant(tenantId: Annotated[str, Path(min_length=0)]): -# logger.info("Request received to deactivate a tenant") - -# try: -# response = tenant_details_table.update_item( -# Key={ -# "tenantId": tenantId, -# }, -# UpdateExpression="set isActive = :isActive", -# ExpressionAttributeValues={":isActive": False}, -# ReturnValues="ALL_NEW", -# ) -# logger.info(f"update_item response {response}") - -# __create_control_plane_event( -# json.dumps({"tenantId": tenantId}), deactivate_detail_type -# ) -# except botocore.exceptions.ClientError as error: -# logger.error(error) -# raise InternalServerError("Unknown error during processing!") - -# else: -# return {"message": "Tenant deactivated"}, HTTPStatus.OK - - -# @app.put("/tenants//activate") -# @tracer.capture_method -# def activate_tenant(tenantId: Annotated[str, Path(min_length=0)]): -# logger.info("Request received to activate a tenant") - -# try: -# response = tenant_details_table.update_item( -# Key={ -# "tenantId": tenantId, -# }, -# UpdateExpression="set isActive = :isActive", -# ExpressionAttributeValues={":isActive": True}, -# ReturnValues="ALL_NEW", -# ) -# logger.info(f"update_item response {response}") - -# __create_control_plane_event( -# json.dumps(response["Attributes"]), activate_detail_type -# ) -# except botocore.exceptions.ClientError as error: -# logger.error(error) -# raise InternalServerError("Unknown error during processing!") - -# else: -# return {"message": "Tenant activated"}, HTTPStatus.OK - - -# def __create_control_plane_event(event_details, detail_type): -# response = event_bus.put_events( -# Entries=[ -# { -# "EventBusName": eventbus_name, -# "Source": event_source, -# "DetailType": detail_type, -# "Detail": event_details, -# } -# ] -# ) -# logger.info(response) - - @logger.inject_lambda_context( correlation_id_path=correlation_paths.API_GATEWAY_HTTP, log_event=True ) diff --git a/resources/functions/tenant-registrations/index.py b/resources/functions/tenant-registrations/index.py index b0c5814..cc5d594 100644 --- a/resources/functions/tenant-registrations/index.py +++ b/resources/functions/tenant-registrations/index.py @@ -92,7 +92,7 @@ def get_tenant_registration(tenant_registration_id: str): return {"message": "Internal server error"}, HTTPStatus.INTERNAL_SERVER_ERROR if "Item" not in response: - return {"message": "Tenant registration not found"}, HTTPStatus.NOT_FOUND + return {"message": "Tenant registration not found."}, HTTPStatus.NOT_FOUND return response["Item"] @@ -165,7 +165,7 @@ def delete_tenant_registration(tenant_registration_id: str): Key={"tenantRegistrationId": tenant_registration_id} ) if "Item" not in response: - return {"message": "Tenant registration not found"}, HTTPStatus.NOT_FOUND + return {"message": "Tenant registration not found."}, HTTPStatus.NOT_FOUND tenant_id = response["Item"].get("tenantId") if not tenant_id: diff --git a/scripts/sbt-aws.sh b/scripts/sbt-aws.sh index afacecc..3261d33 100755 --- a/scripts/sbt-aws.sh +++ b/scripts/sbt-aws.sh @@ -180,7 +180,7 @@ create_tenant_registration() { ] }, "tenantRegistrationData": { - "registrationStatus": "CREATING" + "tenantRegistrationData1": "test" } }') diff --git a/scripts/test-sbt-aws.sh b/scripts/test-sbt-aws.sh index 28b686a..dfdd948 100755 --- a/scripts/test-sbt-aws.sh +++ b/scripts/test-sbt-aws.sh @@ -40,6 +40,19 @@ check_dynamodb_table_entry() { fi } +# Test deleting a non-existent tenant registration +echo "Testing delete-tenant for non-existent tenant registration..." +fake_tenant_registration_id=$(openssl rand -hex 10) +delete_output=$(./sbt-aws.sh delete-tenant-registration "$fake_tenant_registration_id" 2>&1) +delete_response=$(echo "$delete_output" | jq -r '.') + +if [ "$(echo "$delete_response" | jq -r '.message')" = "Tenant registration not found." ]; then + log_test "pass" "Received expected error when deleting non-existent tenant" +else + log_test "fail" "Unexpected output when deleting non-existent tenant" +fi + + # Test create-tenant-registration echo "Testing create-tenant-registration..." response=$(./sbt-aws.sh create-tenant-registration) @@ -142,6 +155,64 @@ else log_test "fail" "Failed to delete tenant registration" fi +# Test create-user +echo "Testing create-user..." +user_id=$(./sbt-aws.sh create-user | jq -r '.data.userName') +if [ -n "$user_id" ] && [ "$user_id" != "null" ]; then + log_test "pass" "User created successfully with ID: $user_id" +else + log_test "fail" "Failed to create user" +fi + +# Test get-all-users +echo "Testing get-all-users..." +users=$(./sbt-aws.sh get-all-users 30) +if echo "$users" | grep -q "$user_id"; then + log_test "pass" "User found in get-all-users" +else + log_test "fail" "User not found in get-all-users" +fi + +# Test get-user +echo "Testing get-user..." +user_details=$(./sbt-aws.sh get-user "$user_id") +if [ -n "$user_details" ]; then + log_test "pass" "User details retrieved successfully" +else + log_test "fail" "Failed to retrieve user details" +fi + +# Test update-user +new_user_role="advancedUser" +new_user_email="newemail@example.com" +./sbt-aws.sh update-user "$user_id" "$new_user_role" "$new_user_email" >/dev/null +if [ $? -eq 0 ]; then + log_test "pass" "User update initiated successfully" + + # Get the updated user details + updated_user_details=$(./sbt-aws.sh get-user "$user_id") + updated_user_role=$(echo "$updated_user_details" | jq -r '.data' | jq -r '.userRole') + updated_user_email=$(echo "$updated_user_details" | jq -r '.data' | jq -r '.email') + + # Verify the updated user details + if [ "$updated_user_role" = "$new_user_role" ] && [ "$updated_user_email" = "$new_user_email" ]; then + log_test "pass" "User details updated successfully" + else + log_test "fail" "Failed to update user details" + fi +else + log_test "fail" "Failed to update user" +fi + +# Test delete-user +echo "Testing delete-user..." +./sbt-aws.sh delete-user "$user_id" >/dev/null +if [ $? -eq 0 ]; then + log_test "pass" "User deletion initiated successfully" +else + log_test "fail" "Failed to delete user" +fi + # Set the exit code based on the overall test status if [ "$TEST_PASSED" = true ]; then exit 0 diff --git a/src/control-plane/tenant-management/tenant-management-funcs.ts b/src/control-plane/tenant-management/tenant-management-funcs.ts index 2d2673e..42e1b08 100644 --- a/src/control-plane/tenant-management/tenant-management-funcs.ts +++ b/src/control-plane/tenant-management/tenant-management-funcs.ts @@ -107,13 +107,7 @@ export class TenantManagementLambda extends Construct { LayerVersion.fromLayerVersionArn(this, 'LambdaPowerTools', lambdaPowerToolsLayerARN), ], environment: { - // EVENTBUS_NAME: props.eventManager.busName, - // EVENT_SOURCE: props.eventManager.controlPlaneEventSource, TENANT_DETAILS_TABLE: props.table.tenantDetails.tableName, - // ONBOARDING_DETAIL_TYPE: DetailType.ONBOARDING_REQUEST, - // OFFBOARDING_DETAIL_TYPE: DetailType.OFFBOARDING_REQUEST, - // ACTIVATE_DETAIL_TYPE: DetailType.ACTIVATE_REQUEST, - // DEACTIVATE_DETAIL_TYPE: DetailType.DEACTIVATE_SUCCESS, }, }); diff --git a/src/control-plane/tenant-management/tenant-management.service.ts b/src/control-plane/tenant-management/tenant-management.service.ts index 95c27ff..07afeb8 100644 --- a/src/control-plane/tenant-management/tenant-management.service.ts +++ b/src/control-plane/tenant-management/tenant-management.service.ts @@ -104,61 +104,9 @@ export class TenantManagementService extends Construct { path: this.tenantIdPath, integration: tenantsHttpLambdaIntegration, }, - // { - // method: apigatewayV2.HttpMethod.PUT, - // path: `${this.tenantIdPath}/deactivate`, - // integration: tenantsHttpLambdaIntegration, - // }, - // { - // method: apigatewayV2.HttpMethod.PUT, - // path: `${this.tenantIdPath}/activate`, - // integration: tenantsHttpLambdaIntegration, - // }, ]; generateRoutes(props.api, routes, new HttpIamAuthorizer()); - // // create Another prop for extracting data into tenant-reg table and into tenant table - // const connection = new events.Connection(this, 'connection', { - // authorization: events.Authorization.oauth({ - // authorizationEndpoint: props.auth.tokenEndpoint, - // clientId: props.auth.machineClientId, - // clientSecret: props.auth.machineClientSecret, - // httpMethod: events.HttpMethod.POST, - // bodyParameters: { - // grant_type: events.HttpParameter.fromString('client_credentials'), - // ...(props.auth.updateTenantScope && { - // scope: events.HttpParameter.fromString(props.auth.updateTenantScope), - // }), - // ...(props.auth.machineClientAudience && { - // audience: events.HttpParameter.fromString(props.auth.machineClientAudience), - // }), - // }, - // }), - // }); - - // const putTenantAPIDestination = new events.ApiDestination(this, 'destination', { - // connection: connection, - // httpMethod: events.HttpMethod.PUT, - // endpoint: `${props.api.url}${this.tenantsPath.substring(1)}/*`, // skip the first '/' in tenantIdPath - // }); - - // const tenantUpdateServiceTarget = new ApiDestination(putTenantAPIDestination, { - // pathParameterValues: ['$.detail.tenantId'], - // event: events.RuleTargetInput.fromEventPath('$.detail.jobOutput'), - // }); - - // [ - // DetailType.PROVISION_SUCCESS, - // DetailType.PROVISION_FAILURE, - // DetailType.DEPROVISION_SUCCESS, - // DetailType.DEPROVISION_FAILURE, - // ].forEach((detailType) => { - // props.eventManager.addTargetToEvent(this, { - // eventType: detailType, - // target: tenantUpdateServiceTarget, - // }); - // }); - this.table = table; } } diff --git a/src/control-plane/tenant-registration/tenant-registration-funcs.ts b/src/control-plane/tenant-registration/tenant-registration-funcs.ts index 1b76378..2aad8ff 100644 --- a/src/control-plane/tenant-registration/tenant-registration-funcs.ts +++ b/src/control-plane/tenant-registration/tenant-registration-funcs.ts @@ -61,9 +61,6 @@ export class TenantRegistrationLambda extends Construct { environment: { TENANT_REGISTRATION_TABLE_NAME: props.table.tenantRegistration.tableName, TENANT_API_URL: props.api.url!, - // CODEBUILD_PROJECT_NAME: tenantInfraManager.projectName, - // TABLE_NAME_PREFIX: props.tableNamePrefix, - // SHARED_COGNITO_USER_POOL_ID: props.sharedCognitoUserPool.userPoolId, EVENTBUS_NAME: props.eventManager.busName, EVENT_SOURCE: props.eventManager.controlPlaneEventSource, ONBOARDING_DETAIL_TYPE: DetailType.ONBOARDING_REQUEST, @@ -85,8 +82,6 @@ export class TenantRegistrationLambda extends Construct { `${props.tenantsPath}/*`, props.api.defaultStage?.stageName ), - // todo: add star (/tenants/*) and suppression for this for PUT and DELETE - // to fix message: Forbidden issue when updating tenant props.api.arnForExecuteApi( 'PUT', `${props.tenantsPath}/*`, diff --git a/src/control-plane/tenant-registration/tenant-registration.service.ts b/src/control-plane/tenant-registration/tenant-registration.service.ts index e202194..5784b05 100644 --- a/src/control-plane/tenant-registration/tenant-registration.service.ts +++ b/src/control-plane/tenant-registration/tenant-registration.service.ts @@ -113,18 +113,6 @@ export class TenantRegistrationService extends Construct { path: this.tenantRegistrationsIdPath, integration: tenantsHttpLambdaIntegration, }, - // { - // method: apigatewayV2.HttpMethod.PUT, - // scope: props.auth.deactivateTenantRegistrationScope, - // path: `${this.tenantRegistrationsIdPath}/deactivate`, - // integration: tenantsHttpLambdaIntegration, - // }, - // { - // method: apigatewayV2.HttpMethod.PUT, - // scope: props.auth.activateTenantRegistrationScope, - // path: `${this.tenantRegistrationsIdPath}/activate`, - // integration: tenantsHttpLambdaIntegration, - // }, ]; generateRoutes(props.api, routes, props.authorizer);