aws-sdk#IAM TypeScript Examples

The following examples show how to use aws-sdk#IAM. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: utils.ts    From malagu with MIT License 7 votes vote down vote up
export async function createClients(region: string, credentials: Credentials) {
    const clientConfig = {
        region,
        credentials: {
            accessKeyId: credentials.accessKeyId,
            secretAccessKey: credentials.accessKeySecret,
            sessionToken: credentials.token
        }
    };
    return {
        lambdaClient: new Lambda(clientConfig),
        apiGatewayClient: new ApiGatewayV2(clientConfig),
        iamClient: new IAM(clientConfig)
    }
}
Example #2
Source File: iamMatcher.ts    From amplify-codegen with Apache License 2.0 6 votes vote down vote up
toBeIAMRoleWithArn = async (roleName: string, arn?: string) => {
  const iam = new IAM();
  let pass: boolean;
  let message: string;
  try {
    const { Role: role } = await iam.getRole({ RoleName: roleName }).promise();
    if (arn) {
      pass = role.Arn === arn ? true : false;
      if (pass) {
        message = `role name ${roleName} has arn ${arn}`;
      } else {
        message = `expected ${roleName} to have ${arn}. Received ${role.Arn}`;
      }
    } else {
      pass = true;
    }
  } catch (e) {
    pass = false;
    message = `Role ${roleName} does not exist`;
  }

  const result = {
    message: () => message,
    pass,
  };
  return result;
}
Example #3
Source File: handlers.ts    From aws-resource-providers with MIT License 6 votes vote down vote up
@handlerEvent(Action.Read)
    @commonAws({ serviceName: 'IAM', debug: true })
    public async read(action: Action, args: HandlerArgs<ResourceModel>, service: IAM, model: ResourceModel): Promise<ResourceModel> {
        const response = await service.getSAMLProvider({ SAMLProviderArn: model.arn }).promise();
        const read = new ResourceModel({
            Name: model.name,
            MetadataDocument: response.SAMLMetadataDocument,
            Arn: model.arn,
        });
        return Promise.resolve(read);
    }
Example #4
Source File: handlers.ts    From aws-resource-providers with MIT License 6 votes vote down vote up
@handlerEvent(Action.Delete)
    @commonAws({ serviceName: 'IAM', debug: true })
    public async delete(action: Action, args: HandlerArgs<ResourceModel>, service: IAM, model: ResourceModel): Promise<null> {
        try {
            await service.deleteSAMLProvider({ SAMLProviderArn: model.arn }).promise();
        } catch (err) {
            if (err && err.code === 'NoSuchEntity') {
                throw new exceptions.NotFound(ResourceModel.TYPE_NAME, model.arn || args.request.logicalResourceIdentifier);
            } else {
                // Raise the original exception
                throw err;
            }
        }
        return Promise.resolve(null);
    }
Example #5
Source File: handlers.ts    From aws-resource-providers with MIT License 6 votes vote down vote up
@handlerEvent(Action.Update)
    @commonAws({ serviceName: 'IAM', debug: true })
    public async update(action: Action, args: HandlerArgs<ResourceModel>, service: IAM, model: ResourceModel): Promise<ResourceModel> {
        const previousModel = args.request.previousResourceState;

        if (previousModel.name !== model.name) {
            throw new exceptions.InvalidRequest(`Changing the name of a saml provider is not supported.`);
        }

        await service
            .updateSAMLProvider({
                SAMLProviderArn: model.arn,
                SAMLMetadataDocument: model.metadataDocument,
            })
            .promise();

        return Promise.resolve(model);
    }
Example #6
Source File: handlers.ts    From aws-resource-providers with MIT License 6 votes vote down vote up
/**
     * Retrieves the password policy for the AWS account.
     *
     * @param service AWS service from current session passed through from caller
     * @param logicalResourceId The logical name of the resource as specified
     * in the template
     * @param resourceId The resource unique identifier
     * @param request The current state for the password policy
     */
    private async retrievePasswordPolicy(service: IAM, logger: Logger, logicalResourceId?: string, resourceId?: string, request?: PasswordPolicy): Promise<PasswordPolicy> {
        let result: PasswordPolicy = null;
        try {
            const response = await service.getAccountPasswordPolicy().promise();
            logger.log('getAccountPasswordPolicy response', response);
            const passwordPolicy = request && Object.keys(request).length && request.serialize ? request.serialize() : JSON.parse(JSON.stringify(response.PasswordPolicy));
            result = PasswordPolicy.deserialize({
                ...passwordPolicy,
                ResourceId: resourceId,
            });
            logger.log(PasswordPolicy.TYPE_NAME, `[${result.resourceId}] [${logicalResourceId}]`, 'successfully retrieved.');
        } catch (err) {
            logger.log(err);
            if (err && err.code === 'NoSuchEntity') {
                throw new exceptions.NotFound(PasswordPolicy.TYPE_NAME, resourceId || logicalResourceId);
            } else {
                // Raise the original exception
                throw err;
            }
        }
        return Promise.resolve(result);
    }
Example #7
Source File: handlers.ts    From aws-resource-providers with MIT License 6 votes vote down vote up
/**
     * Updates or inserts the password policy settings for the AWS account. This operation does not
     * support partial updates. No parameters are required, but if you do not specify a
     * parameter, that parameter's value reverts to its default value.
     *
     * @param service AWS service from current session passed through from caller
     * @param request The updated options for the password policy
     * @param logicalResourceId The logical name of the resource as specified
     * in the template
     * @param resourceId The resource unique identifier
     */
    private async upsertPasswordPolicy(service: IAM, logger: Logger, request: PasswordPolicy, logicalResourceId?: string, resourceId?: string): Promise<PasswordPolicy> {
        let result: PasswordPolicy = null;
        const params = JSON.parse(JSON.stringify(request));
        delete params['ResourceId'];
        delete params['ExpirePasswords'];
        logger.log('updateAccountPasswordPolicy input', params);
        const response = await service.updateAccountPasswordPolicy(params).promise();
        logger.log('updateAccountPasswordPolicy response', response);
        result = PasswordPolicy.deserialize({
            ...params,
            ResourceId: resourceId || uuidv4(),
        });
        logger.log(PasswordPolicy.TYPE_NAME, `[${result.resourceId}] [${logicalResourceId}]`, 'successfully upserted.');
        return Promise.resolve(result);
    }
Example #8
Source File: handlers.ts    From aws-resource-providers with MIT License 6 votes vote down vote up
/**
     * CloudFormation invokes this handler when the resource is initially created
     * during stack create operations.
     */
    @handlerEvent(Action.Create)
    @commonAws({ service: IAM, debug: true })
    public async create(action: Action, args: HandlerArgs<PasswordPolicy>, service: IAM, model: PasswordPolicy): Promise<PasswordPolicy> {
        const { logicalResourceIdentifier } = args.request;
        if (model?.resourceId) {
            args.logger.log(this.typeName, `[${model.resourceId}] [${logicalResourceIdentifier}]`, 'cannot contain identifier.');
            throw new exceptions.InvalidRequest('Resource identifier cannot be provided during creation.');
        }
        try {
            await this.retrievePasswordPolicy(service, args.logger, logicalResourceIdentifier);
            throw new exceptions.AlreadyExists(PasswordPolicy.TYPE_NAME, logicalResourceIdentifier);
        } catch (err) {}
        const result = await this.upsertPasswordPolicy(service, args.logger, model, logicalResourceIdentifier);
        args.logger.log('CREATE model primary identifier', result.getPrimaryIdentifier());
        args.logger.log('CREATE model additional identifiers', result.getAdditionalIdentifiers());
        return Promise.resolve(result);
    }
Example #9
Source File: handlers.ts    From aws-resource-providers with MIT License 6 votes vote down vote up
/**
     * CloudFormation invokes this handler when the resource is updated
     * as part of a stack update operation.
     */
    @handlerEvent(Action.Update)
    @commonAws({ service: IAM, debug: true })
    public async update(action: Action, args: HandlerArgs<PasswordPolicy>, service: IAM, model: PasswordPolicy): Promise<PasswordPolicy> {
        const { logicalResourceIdentifier, previousResourceState } = args.request;
        const resourceId = previousResourceState.resourceId;
        if (!model?.resourceId) {
            throw new exceptions.NotFound(this.typeName, model.resourceId);
        } else if (model.resourceId !== resourceId) {
            args.logger.log(this.typeName, `[NEW ${model.resourceId}] [${logicalResourceIdentifier}]`, `does not match identifier from saved resource [OLD ${resourceId}].`);
            throw new exceptions.NotUpdatable('No resource matching the provided identifier.');
        }
        await this.retrievePasswordPolicy(service, args.logger, logicalResourceIdentifier, resourceId);
        const result = await this.upsertPasswordPolicy(service, args.logger, model, logicalResourceIdentifier, resourceId);
        return Promise.resolve(result);
    }
Example #10
Source File: handlers.ts    From aws-resource-providers with MIT License 6 votes vote down vote up
/**
     * CloudFormation invokes this handler when the resource is deleted, either when
     * the resource is deleted from the stack as part of a stack update operation,
     * or the stack itself is deleted.
     */
    @handlerEvent(Action.Delete)
    @commonAws({ service: IAM, debug: true })
    public async delete(action: Action, args: HandlerArgs<PasswordPolicy>, service: IAM, model: PasswordPolicy): Promise<null> {
        const { logicalResourceIdentifier } = args.request;
        const result = await this.retrievePasswordPolicy(service, args.logger, logicalResourceIdentifier, model.resourceId);
        if (result) {
            const response = await service.deleteAccountPasswordPolicy().promise();
            args.logger.log('deleteAccountPasswordPolicy response', response);
            args.logger.log(this.typeName, `[${result.resourceId}] [${logicalResourceIdentifier}]`, 'successfully deleted.');
        }
        return Promise.resolve(null);
    }
Example #11
Source File: handlers.ts    From aws-resource-providers with MIT License 6 votes vote down vote up
/**
     * CloudFormation invokes this handler as part of a stack update operation when
     * detailed information about the resource's current state is required.
     */
    @handlerEvent(Action.Read)
    @commonAws({ service: IAM, debug: true })
    public async read(action: Action, args: HandlerArgs<PasswordPolicy>, service: IAM, model: PasswordPolicy): Promise<PasswordPolicy> {
        const { logicalResourceIdentifier } = args.request;
        return await this.retrievePasswordPolicy(service, args.logger, logicalResourceIdentifier, model.resourceId, model);
    }
Example #12
Source File: handlers.ts    From aws-resource-providers with MIT License 6 votes vote down vote up
/**
     * CloudFormation invokes this handler when summary information about multiple
     * resources of this resource provider is required.
     */
    @handlerEvent(Action.List)
    @commonAws({ service: IAM, debug: true })
    public async list(action: Action, args: HandlerArgs<PasswordPolicy>, service: IAM, model: PasswordPolicy): Promise<PasswordPolicy[]> {
        const { logicalResourceIdentifier } = args.request;
        const models: Array<PasswordPolicy> = [];
        try {
            const result: PasswordPolicy = await this.retrievePasswordPolicy(service, args.logger, logicalResourceIdentifier, model.resourceId, model);
            models.push(result);
        } catch (err) {
            if (!(err instanceof exceptions.NotFound)) {
                throw err;
            }
        }
        return Promise.resolve(models);
    }
Example #13
Source File: handlers.ts    From aws-resource-providers with MIT License 6 votes vote down vote up
@handlerEvent(Action.Create)
    @commonAws({ serviceName: 'IAM', debug: true })
    public async create(action: Action, args: HandlerArgs<ResourceModel>, service: IAM, model: ResourceModel): Promise<ResourceModel> {
        const response = await service
            .createSAMLProvider({
                Name: model.name,
                SAMLMetadataDocument: model.metadataDocument,
            })
            .promise();

        model.arn = response.SAMLProviderArn;
        return Promise.resolve(model);
    }
Example #14
Source File: handlers.ts    From aws-resource-providers with MIT License 5 votes vote down vote up
@handlerEvent(Action.Read)
    @commonAws({ serviceName: 'ServiceQuotas', debug: true })
    public async read(action: Action, args: HandlerArgs<ResourceModel>, service: IAM, model: ResourceModel): Promise<ResourceModel> {
        const read = new ResourceModel({
            Arn: model.arn,
        });
        return Promise.resolve(read);
    }
Example #15
Source File: handlers.test.ts    From aws-resource-providers with MIT License 5 votes vote down vote up
describe('when calling handler', () => {
    let testEntrypointPayload: any;
    let spySession: jest.SpyInstance;
    let spySessionClient: jest.SpyInstance;
    let iam: AwsServiceMockBuilder<IAM>;
    let fixtureMap: Map<Action, Record<string, any>>;

    beforeAll(() => {
        fixtureMap = new Map<Action, Record<string, any>>();
        fixtureMap.set(Action.Create, createFixture);
        fixtureMap.set(Action.Read, readFixture);
        fixtureMap.set(Action.Update, updateFixture);
        fixtureMap.set(Action.Delete, deleteFixture);
    });

    beforeEach(async () => {
        iam = on(IAM, { snapshot: false });
        spySession = jest.spyOn(SessionProxy, 'getSession');
        spySessionClient = jest.spyOn<any, any>(SessionProxy.prototype, 'client');
        spySessionClient.mockReturnValue(iam.instance);
        testEntrypointPayload = {
            credentials: { accessKeyId: '', secretAccessKey: '', sessionToken: '' },
            region: 'us-east-1',
            action: 'CREATE',
        };
    });

    afterEach(() => {
        jest.clearAllMocks();
        jest.restoreAllMocks();
    });

    test('all operations fail without session - iam saml provider', async () => {
        expect.assertions(fixtureMap.size);
        spySession.mockReturnValue(null);
        for (const [action, request] of fixtureMap) {
            const progress = await resource.testEntrypoint({ ...testEntrypointPayload, action, request }, null);
            expect(progress.errorCode).toBe(exceptions.InvalidCredentials.name);
        }
    });
});
Example #16
Source File: index.ts    From cloudstructs with Apache License 2.0 5 votes vote down vote up
constructor(scope: Construct, id: string, props: SamlIdentityProviderProps) {
    super(scope, id);

    const name = props.name ?? `${Names.uniqueId(this)}IdentityProvider`;

    const arn = Stack.of(this).formatArn({
      service: 'iam',
      region: '',
      resource: 'saml-provider',
      resourceName: name,
    });

    const idp = new cr.AwsCustomResource(this, 'Resource', {
      resourceType: 'Custom::SamlIdentityProvider',
      onCreate: {
        service: 'IAM',
        action: 'createSAMLProvider',
        parameters: {
          Name: name,
          SAMLMetadataDocument: props.metadataDocument,
        } as IAM.CreateSAMLProviderRequest,
        physicalResourceId: cr.PhysicalResourceId.fromResponse('SAMLProviderArn'),
      },
      onUpdate: {
        service: 'IAM',
        action: 'updateSAMLProvider',
        parameters: {
          SAMLProviderArn: new cr.PhysicalResourceIdReference().toJSON(),
          SAMLMetadataDocument: props.metadataDocument,
        } as IAM.UpdateSAMLProviderRequest,
        physicalResourceId: cr.PhysicalResourceId.fromResponse('SAMLProviderArn'),
      },
      onDelete: {
        service: 'IAM',
        action: 'deleteSAMLProvider',
        parameters: {
          SAMLProviderArn: new cr.PhysicalResourceIdReference().toJSON(),
        } as IAM.DeleteSAMLProviderRequest,
      },
      policy: cr.AwsCustomResourcePolicy.fromStatements([
        new iam.PolicyStatement({
          actions: [
            'iam:createSAMLProvider',
            'iam:updateSAMLProvider',
            'iam:deleteSAMLProvider',
          ],
          resources: [arn],
        }),
      ]),
    });

    this.samlIdentityProviderArn = idp.getResponseField('SAMLProviderArn');
  }
Example #17
Source File: deploy.ts    From malagu with MIT License 5 votes vote down vote up
iamClient: IAM
Example #18
Source File: iamMatcher.ts    From amplify-codegen with Apache License 2.0 5 votes vote down vote up
toHaveValidPolicyConditionMatchingIdpId = async (roleName: string, idpId: string) => {
  let pass: boolean = false;
  let message: string = '';

  try {
    const iam = new IAM({
      accessKeyId: process.env.AWS_ACCESS_KEY_ID,
      secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
    });

    const { Role: role } = await iam.getRole({ RoleName: roleName }).promise();
    const assumeRolePolicyDocument = JSON.parse(decodeURIComponent(role.AssumeRolePolicyDocument));

    pass = assumeRolePolicyDocument.Statement.some(statement => {
      if (statement.Condition) {
        return (
          statement.Condition.StringEquals &&
          statement.Condition.StringEquals['cognito-identity.amazonaws.com:aud'] &&
          statement.Condition.StringEquals['cognito-identity.amazonaws.com:aud'] === idpId &&
          statement.Condition['ForAnyValue:StringLike'] &&
          statement.Condition['ForAnyValue:StringLike']['cognito-identity.amazonaws.com:amr'] &&
          /authenticated/.test(statement.Condition['ForAnyValue:StringLike']['cognito-identity.amazonaws.com:amr'])
        );
      } else {
        return false;
      }
    });

    message = pass ? 'Found Matching Condition' : 'Matching Condition does not exist';

  } catch (e) {
    pass = false;
    message = 'IAM GetRole threw Error: ' + e.message;
  }

  return {
    message: () => message,
    pass,
  };
}
Example #19
Source File: handlers.test.ts    From aws-resource-providers with MIT License 4 votes vote down vote up
describe('when calling handler', () => {
    let testEntrypointPayload: any;
    let spySession: jest.SpyInstance;
    let spySessionClient: jest.SpyInstance;
    let iam: AwsServiceMockBuilder<IAM>;
    let fixtureMap: Map<Action, Record<string, any>>;

    beforeAll(() => {
        fixtureMap = new Map<Action, Record<string, any>>();
        fixtureMap.set(Action.Create, createFixture);
        fixtureMap.set(Action.Read, readFixture);
        fixtureMap.set(Action.Update, updateFixture);
        fixtureMap.set(Action.Delete, deleteFixture);
        fixtureMap.set(Action.List, listFixture);
    });

    beforeEach(() => {
        iam = on(IAM, { snapshot: false });
        iam.mock('getAccountPasswordPolicy').resolve({
            PasswordPolicy: {
                MinimumPasswordLength: 6,
            },
        });
        iam.mock('updateAccountPasswordPolicy').resolve({});
        iam.mock('deleteAccountPasswordPolicy').resolve({});
        spySession = jest.spyOn(SessionProxy, 'getSession');
        spySessionClient = jest.spyOn<any, any>(SessionProxy.prototype, 'client');
        spySessionClient.mockReturnValue(iam.instance);
        testEntrypointPayload = {
            credentials: { accessKeyId: '', secretAccessKey: '', sessionToken: '' },
            region: 'us-east-1',
            action: 'CREATE',
        };
    });

    afterEach(() => {
        jest.clearAllMocks();
        jest.restoreAllMocks();
    });

    test('create operation successful - iam password policy', async () => {
        const spyUuid = jest.spyOn(uuid, 'v4');
        const request = fixtureMap.get(Action.Create);
        const progress = await resource.testEntrypoint({ ...testEntrypointPayload, action: Action.Create, request }, null);
        const model = PasswordPolicy.deserialize({
            ...request.desiredResourceState,
            ResourceId: IDENTIFIER,
        });
        expect(spyUuid).toHaveBeenCalledTimes(1);
        expect(progress).toMatchObject({ status: OperationStatus.Success, message: '', callbackDelaySeconds: 0 });
        expect(progress.resourceModel.serialize()).toMatchObject(model.serialize());
    });

    test('create operation fail generic - iam password policy', async () => {
        expect.assertions(7);
        const mockGet = iam.mock('getAccountPasswordPolicy').reject({ ...new Error(), code: 'ServiceUnavailableException' });
        const mockUpdate = iam.mock('updateAccountPasswordPolicy').reject({ ...new Error(), code: 'ServiceUnavailableException' });
        const spyRetrieve = jest.spyOn<any, any>(resource, 'retrievePasswordPolicy');
        const spyUpsert = jest.spyOn<any, any>(resource, 'upsertPasswordPolicy');
        const request = fixtureMap.get(Action.Create);
        const progress = await resource.testEntrypoint({ ...testEntrypointPayload, action: Action.Create, request }, null);
        expect(progress).toMatchObject({ status: OperationStatus.Failed, errorCode: exceptions.InternalFailure.name });
        expect(mockGet.mock).toHaveBeenCalledTimes(1);
        expect(spyRetrieve).toHaveBeenCalledTimes(1);
        expect(spyRetrieve).toHaveReturned();
        expect(mockUpdate.mock).toHaveBeenCalledTimes(1);
        expect(spyUpsert).toHaveBeenCalledTimes(1);
        expect(spyUpsert).toHaveReturned();
    });

    test('create operation fail with contain identifier - iam password policy', async () => {
        const request = createInvalidRequest;
        const progress = await resource.testEntrypoint({ ...testEntrypointPayload, action: Action.Create, request }, null);
        expect(progress).toMatchObject({ status: OperationStatus.Failed, errorCode: exceptions.InvalidRequest.name });
    });

    test('update operation successful - iam password policy', async () => {
        const request = fixtureMap.get(Action.Update);
        const progress = await resource.testEntrypoint({ ...testEntrypointPayload, action: Action.Update, request }, null);
        expect(progress).toMatchObject({ status: OperationStatus.Success, message: '', callbackDelaySeconds: 0 });
        expect(progress.resourceModel.serialize()).toMatchObject(request.desiredResourceState);
    });

    test('update operation fail not found - iam password policy', async () => {
        const request = updateNotFound;
        const progress = await resource.testEntrypoint({ ...testEntrypointPayload, action: Action.Update, request }, null);
        expect(progress).toMatchObject({ status: OperationStatus.Failed, errorCode: exceptions.NotFound.name });
    });

    test('update operation fail not updatable - iam password policy', async () => {
        const request = updateNotUpdatable;
        const progress = await resource.testEntrypoint({ ...testEntrypointPayload, action: Action.Update, request }, null);
        expect(progress).toMatchObject({ status: OperationStatus.Failed, errorCode: exceptions.NotUpdatable.name });
    });

    test('delete operation successful - iam password policy', async () => {
        const request = fixtureMap.get(Action.Delete);
        const progress = await resource.testEntrypoint({ ...testEntrypointPayload, action: Action.Delete, request }, null);
        expect(progress).toMatchObject({ status: OperationStatus.Success, message: '', callbackDelaySeconds: 0 });
        expect(progress.resourceModel).toBeNull();
    });

    test('delete operation fail not found - iam password policy', async () => {
        const mockGet = iam.mock('getAccountPasswordPolicy').reject({ ...new Error(), code: 'NoSuchEntity' });
        const spyRetrieve = jest.spyOn<any, any>(resource, 'retrievePasswordPolicy');
        const request = fixtureMap.get(Action.Delete);
        const progress = await resource.testEntrypoint({ ...testEntrypointPayload, action: Action.Delete, request }, null);
        expect(progress).toMatchObject({ status: OperationStatus.Failed, errorCode: exceptions.NotFound.name });
        expect(mockGet.mock).toHaveBeenCalledTimes(1);
        expect(spyRetrieve).toHaveBeenCalledTimes(1);
        expect(spyRetrieve).toHaveReturned();
    });

    test('delete operation fail generic - iam password policy', async () => {
        const mockDelete = iam.mock('deleteAccountPasswordPolicy').reject({ ...new Error(), code: 'ServiceUnavailableException' });
        const request = fixtureMap.get(Action.Delete);
        const progress = await resource.testEntrypoint({ ...testEntrypointPayload, action: Action.Delete, request }, null);
        expect(progress).toMatchObject({ status: OperationStatus.Failed, errorCode: exceptions.InternalFailure.name });
        expect(mockDelete.mock).toHaveBeenCalledTimes(1);
    });

    test('read operation successful - iam password policy', async () => {
        const request = fixtureMap.get(Action.Read);
        const progress = await resource.testEntrypoint({ ...testEntrypointPayload, action: Action.Read, request }, null);
        expect(progress).toMatchObject({ status: OperationStatus.Success, message: '', callbackDelaySeconds: 0 });
        expect(progress.resourceModel.serialize()).toMatchObject(request.desiredResourceState);
    });

    test('list operation successful - iam password policy', async () => {
        const request = fixtureMap.get(Action.List);
        const progress = await resource.testEntrypoint({ ...testEntrypointPayload, action: Action.List, request }, null);
        expect(progress).toMatchObject({ status: OperationStatus.Success, message: '', callbackDelaySeconds: 0 });
        expect(progress.resourceModels[0].serialize()).toMatchObject(request.desiredResourceState);
    });

    test('all operations fail without session - iam password policy', async () => {
        expect.assertions(fixtureMap.size);
        spySession.mockReturnValue(null);
        jest.spyOn(global, 'setTimeout').mockImplementation((callback: any) => callback());
        for (const [action, request] of fixtureMap) {
            const progress = await resource.testEntrypoint({ ...testEntrypointPayload, action, request }, null);
            expect(progress.errorCode).toBe(exceptions.InvalidCredentials.name);
        }
    });
});