Skip to content

Commit

Permalink
feat: support for adminEnable/DisableUser
Browse files Browse the repository at this point in the history
  • Loading branch information
jagregory committed May 30, 2022
1 parent 4920c19 commit 462af6e
Show file tree
Hide file tree
Showing 8 changed files with 272 additions and 2 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ A _Good Enough_ offline emulator for [Amazon Cognito](https://aws.amazon.com/cog
| AdminDeleteUser ||
| AdminDeleteUserAttributes ||
| AdminDisableProviderForUser ||
| AdminDisableUser | |
| AdminEnableUser | |
| AdminDisableUser | |
| AdminEnableUser | |
| AdminForgetDevice ||
| AdminGetDevice ||
| AdminGetUser ||
Expand Down
38 changes: 38 additions & 0 deletions integration-tests/aws-sdk/adminDisableUser.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { withCognitoSdk } from "./setup";

describe(
"CognitoIdentityServiceProvider.adminDisableUser",
withCognitoSdk((Cognito) => {
it("updates a user's attributes", async () => {
const client = Cognito();

await client
.adminCreateUser({
UserAttributes: [
{ Name: "email", Value: "[email protected]" },
{ Name: "custom:example", Value: "1" },
],
Username: "abc",
UserPoolId: "test",
DesiredDeliveryMediums: ["EMAIL"],
})
.promise();

await client
.adminDisableUser({
UserPoolId: "test",
Username: "abc",
})
.promise();

const user = await client
.adminGetUser({
UserPoolId: "test",
Username: "abc",
})
.promise();

expect(user.Enabled).toEqual(false);
});
})
);
54 changes: 54 additions & 0 deletions integration-tests/aws-sdk/adminEnableUser.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { withCognitoSdk } from "./setup";

describe(
"CognitoIdentityServiceProvider.adminEnableUser",
withCognitoSdk((Cognito) => {
it("updates a user's attributes", async () => {
const client = Cognito();

await client
.adminCreateUser({
UserAttributes: [
{ Name: "email", Value: "[email protected]" },
{ Name: "custom:example", Value: "1" },
],
Username: "abc",
UserPoolId: "test",
DesiredDeliveryMediums: ["EMAIL"],
})
.promise();

await client
.adminDisableUser({
UserPoolId: "test",
Username: "abc",
})
.promise();

let user = await client
.adminGetUser({
UserPoolId: "test",
Username: "abc",
})
.promise();

expect(user.Enabled).toEqual(false);

await client
.adminEnableUser({
UserPoolId: "test",
Username: "abc",
})
.promise();

user = await client
.adminGetUser({
UserPoolId: "test",
Username: "abc",
})
.promise();

expect(user.Enabled).toEqual(true);
});
})
);
55 changes: 55 additions & 0 deletions src/targets/adminDisableUser.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { ClockFake } from "../__tests__/clockFake";
import { newMockCognitoService } from "../__tests__/mockCognitoService";
import { newMockUserPoolService } from "../__tests__/mockUserPoolService";
import { TestContext } from "../__tests__/testContext";
import * as TDB from "../__tests__/testDataBuilder";
import { UserNotFoundError } from "../errors";
import { UserPoolService } from "../services";
import { AdminDisableUser, AdminDisableUserTarget } from "./adminDisableUser";

const originalDate = new Date();

describe("AdminDisableUser target", () => {
let adminDisableUser: AdminDisableUserTarget;
let mockUserPoolService: jest.Mocked<UserPoolService>;
let clock: ClockFake;

beforeEach(() => {
mockUserPoolService = newMockUserPoolService();
clock = new ClockFake(originalDate);

adminDisableUser = AdminDisableUser({
clock,
cognito: newMockCognitoService(mockUserPoolService),
});
});

it("enables the user", async () => {
const existingUser = TDB.user();

mockUserPoolService.getUserByUsername.mockResolvedValue(existingUser);

const newDate = new Date();
clock.advanceTo(newDate);

await adminDisableUser(TestContext, {
Username: existingUser.Username,
UserPoolId: "test",
});

expect(mockUserPoolService.saveUser).toHaveBeenCalledWith(TestContext, {
...existingUser,
UserLastModifiedDate: newDate,
Enabled: false,
});
});

it("throws if the user doesn't exist", async () => {
await expect(
adminDisableUser(TestContext, {
Username: "user",
UserPoolId: "test",
})
).rejects.toEqual(new UserNotFoundError());
});
});
32 changes: 32 additions & 0 deletions src/targets/adminDisableUser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import {
AdminDisableUserRequest,
AdminDisableUserResponse,
} from "aws-sdk/clients/cognitoidentityserviceprovider";
import { UserNotFoundError } from "../errors";
import { Services } from "../services";
import { Target } from "./Target";

export type AdminDisableUserTarget = Target<
AdminDisableUserRequest,
AdminDisableUserResponse
>;

type AdminDisableUserServices = Pick<Services, "cognito" | "clock">;

export const AdminDisableUser =
({ cognito, clock }: AdminDisableUserServices): AdminDisableUserTarget =>
async (ctx, req) => {
const userPool = await cognito.getUserPool(ctx, req.UserPoolId);
const user = await userPool.getUserByUsername(ctx, req.Username);
if (!user) {
throw new UserNotFoundError();
}

await userPool.saveUser(ctx, {
...user,
Enabled: false,
UserLastModifiedDate: clock.get(),
});

return {};
};
55 changes: 55 additions & 0 deletions src/targets/adminEnableUser.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { ClockFake } from "../__tests__/clockFake";
import { newMockCognitoService } from "../__tests__/mockCognitoService";
import { newMockUserPoolService } from "../__tests__/mockUserPoolService";
import { TestContext } from "../__tests__/testContext";
import * as TDB from "../__tests__/testDataBuilder";
import { UserNotFoundError } from "../errors";
import { UserPoolService } from "../services";
import { AdminEnableUser, AdminEnableUserTarget } from "./adminEnableUser";

const originalDate = new Date();

describe("AdminEnableUser target", () => {
let adminEnableUser: AdminEnableUserTarget;
let mockUserPoolService: jest.Mocked<UserPoolService>;
let clock: ClockFake;

beforeEach(() => {
mockUserPoolService = newMockUserPoolService();
clock = new ClockFake(originalDate);

adminEnableUser = AdminEnableUser({
clock,
cognito: newMockCognitoService(mockUserPoolService),
});
});

it("enables the user", async () => {
const existingUser = TDB.user();

mockUserPoolService.getUserByUsername.mockResolvedValue(existingUser);

const newDate = new Date();
clock.advanceTo(newDate);

await adminEnableUser(TestContext, {
Username: existingUser.Username,
UserPoolId: "test",
});

expect(mockUserPoolService.saveUser).toHaveBeenCalledWith(TestContext, {
...existingUser,
UserLastModifiedDate: newDate,
Enabled: true,
});
});

it("throws if the user doesn't exist", async () => {
await expect(
adminEnableUser(TestContext, {
Username: "user",
UserPoolId: "test",
})
).rejects.toEqual(new UserNotFoundError());
});
});
32 changes: 32 additions & 0 deletions src/targets/adminEnableUser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import {
AdminEnableUserRequest,
AdminEnableUserResponse,
} from "aws-sdk/clients/cognitoidentityserviceprovider";
import { UserNotFoundError } from "../errors";
import { Services } from "../services";
import { Target } from "./Target";

export type AdminEnableUserTarget = Target<
AdminEnableUserRequest,
AdminEnableUserResponse
>;

type AdminEnableUserServices = Pick<Services, "cognito" | "clock">;

export const AdminEnableUser =
({ cognito, clock }: AdminEnableUserServices): AdminEnableUserTarget =>
async (ctx, req) => {
const userPool = await cognito.getUserPool(ctx, req.UserPoolId);
const user = await userPool.getUserByUsername(ctx, req.Username);
if (!user) {
throw new UserNotFoundError();
}

await userPool.saveUser(ctx, {
...user,
Enabled: true,
UserLastModifiedDate: clock.get(),
});

return {};
};
4 changes: 4 additions & 0 deletions src/targets/targets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { AdminCreateUser } from "./adminCreateUser";
import { AdminDeleteUser } from "./adminDeleteUser";

import { AdminDeleteUserAttributes } from "./adminDeleteUserAttributes";
import { AdminDisableUser } from "./adminDisableUser";
import { AdminEnableUser } from "./adminEnableUser";
import { AdminGetUser } from "./adminGetUser";
import { AdminInitiateAuth } from "./adminInitiateAuth";
import { AdminListGroupsForUser } from "./adminListGroupsForUser";
Expand Down Expand Up @@ -48,6 +50,8 @@ export const Targets = {
AdminCreateUser,
AdminDeleteUser,
AdminDeleteUserAttributes,
AdminDisableUser,
AdminEnableUser,
AdminGetUser,
AdminInitiateAuth,
AdminListGroupsForUser,
Expand Down

0 comments on commit 462af6e

Please sign in to comment.