Skip to content
This repository was archived by the owner on Apr 6, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 123 additions & 1 deletion sdk-test-awscli/test_all.sh
Original file line number Diff line number Diff line change
Expand Up @@ -748,11 +748,133 @@ run_kms() {
aws_cmd kms schedule-key-deletion --key-id "$key_id" --pending-window-in-days 7 >/dev/null 2>&1 || true
}

# ---------------------------------------------------------------------------
# Cognito
# ---------------------------------------------------------------------------

run_cognito() {
echo "--- Cognito Tests ---"

local out rc pool_id client_id

# CreateUserPool
out=$(aws_cmd cognito-idp create-user-pool --pool-name "cli-test-pool" 2>&1) && rc=0 || rc=1
pool_id=$(echo "$out" | python -c "import sys,json; print(json.load(sys.stdin)['UserPool']['Id'])" 2>/dev/null || echo "")
check "Cognito CreateUserPool" "$( [ -n "$pool_id" ] && echo true || echo false )" "$out"

# CreateUserPoolClient
out=$(aws_cmd cognito-idp create-user-pool-client --user-pool-id "$pool_id" --client-name "cli-client" 2>&1) && rc=0 || rc=1
client_id=$(echo "$out" | python -c "import sys,json; print(json.load(sys.stdin)['UserPoolClient']['ClientId'])" 2>/dev/null || echo "")
check "Cognito CreateUserPoolClient" "$( [ -n "$client_id" ] && echo true || echo false )" "$out"

# AdminCreateUser
out=$(aws_cmd cognito-idp admin-create-user \
--user-pool-id "$pool_id" \
--username "cliuser" \
--temporary-password "Temp123!" \
--user-attributes Name=email,Value=cliuser@example.com 2>&1) && rc=0 || rc=1
local created_user
created_user=$(echo "$out" | python -c "import sys,json; print(json.load(sys.stdin)['User']['Username'])" 2>/dev/null || echo "")
check "Cognito AdminCreateUser" "$( [ "$created_user" = "cliuser" ] && echo true || echo false )" "$out"

# AdminSetUserPassword
out=$(aws_cmd cognito-idp admin-set-user-password \
--user-pool-id "$pool_id" --username "cliuser" \
--password "Perm456!" --permanent 2>&1) && rc=0 || rc=1
check "Cognito AdminSetUserPassword" "$( [ $rc -eq 0 ] && echo true || echo false )" "$out"

# CreateGroup
out=$(aws_cmd cognito-idp create-group \
--user-pool-id "$pool_id" \
--group-name "test-group" \
--description "Test group" \
--precedence 1 2>&1) && rc=0 || rc=1
local group_name
group_name=$(echo "$out" | python -c "import sys,json; print(json.load(sys.stdin)['Group']['GroupName'])" 2>/dev/null || echo "")
check "Cognito CreateGroup" "$( [ "$group_name" = "test-group" ] && echo true || echo false )" "$out"

# GetGroup
out=$(aws_cmd cognito-idp get-group \
--user-pool-id "$pool_id" --group-name "test-group" 2>&1) && rc=0 || rc=1
local got_name got_desc got_prec
got_name=$(echo "$out" | python -c "import sys,json; print(json.load(sys.stdin)['Group']['GroupName'])" 2>/dev/null || echo "")
got_desc=$(echo "$out" | python -c "import sys,json; print(json.load(sys.stdin)['Group']['Description'])" 2>/dev/null || echo "")
got_prec=$(echo "$out" | python -c "import sys,json; print(json.load(sys.stdin)['Group']['Precedence'])" 2>/dev/null || echo "")
check "Cognito GetGroup" "$( [ "$got_name" = "test-group" ] && [ "$got_desc" = "Test group" ] && [ "$got_prec" = "1" ] && echo true || echo false )" "$out"

# CreateGroup duplicate
out=$(aws_cmd cognito-idp create-group \
--user-pool-id "$pool_id" --group-name "test-group" 2>&1) && rc=0 || rc=1
check "Cognito CreateGroup duplicate rejected" "$( [ $rc -ne 0 ] && echo true || echo false )" "$out"

# ListGroups
out=$(aws_cmd cognito-idp list-groups --user-pool-id "$pool_id" 2>&1) && rc=0 || rc=1
local found_group
found_group=$(echo "$out" | python -c "import sys,json; d=json.load(sys.stdin); print('true' if any(g['GroupName']=='test-group' for g in d.get('Groups',[])) else 'false')" 2>/dev/null || echo false)
check "Cognito ListGroups" "$found_group" "$out"

# AdminAddUserToGroup
out=$(aws_cmd cognito-idp admin-add-user-to-group \
--user-pool-id "$pool_id" --group-name "test-group" --username "cliuser" 2>&1) && rc=0 || rc=1
check "Cognito AdminAddUserToGroup" "$( [ $rc -eq 0 ] && echo true || echo false )" "$out"

# AdminListGroupsForUser
out=$(aws_cmd cognito-idp admin-list-groups-for-user \
--user-pool-id "$pool_id" --username "cliuser" 2>&1) && rc=0 || rc=1
local user_has_group
user_has_group=$(echo "$out" | python -c "import sys,json; d=json.load(sys.stdin); print('true' if any(g['GroupName']=='test-group' for g in d.get('Groups',[])) else 'false')" 2>/dev/null || echo false)
check "Cognito AdminListGroupsForUser" "$user_has_group" "$out"

# InitiateAuth and verify cognito:groups in JWT
out=$(aws_cmd cognito-idp initiate-auth \
--auth-flow USER_PASSWORD_AUTH \
--client-id "$client_id" \
--auth-parameters USERNAME=cliuser,PASSWORD=Perm456! 2>&1) && rc=0 || rc=1
local jwt_groups
jwt_groups=$(echo "$out" | python -c "
import sys,json,base64
d=json.load(sys.stdin)
token=d['AuthenticationResult']['AccessToken']
payload=base64.urlsafe_b64decode(token.split('.')[1]+'==')
claims=json.loads(payload)
groups=claims.get('cognito:groups',[])
print('true' if 'test-group' in groups else 'false')
" 2>/dev/null || echo false)
check "Cognito JWT cognito:groups claim" "$jwt_groups" "$out"

# AdminRemoveUserFromGroup
out=$(aws_cmd cognito-idp admin-remove-user-from-group \
--user-pool-id "$pool_id" --group-name "test-group" --username "cliuser" 2>&1) && rc=0 || rc=1
check "Cognito AdminRemoveUserFromGroup" "$( [ $rc -eq 0 ] && echo true || echo false )" "$out"

# AdminListGroupsForUser — empty
out=$(aws_cmd cognito-idp admin-list-groups-for-user \
--user-pool-id "$pool_id" --username "cliuser" 2>&1) && rc=0 || rc=1
local groups_empty
groups_empty=$(echo "$out" | python -c "import sys,json; d=json.load(sys.stdin); print('true' if len(d.get('Groups',[]))==0 else 'false')" 2>/dev/null || echo false)
check "Cognito AdminListGroupsForUser empty" "$groups_empty" "$out"

# DeleteGroup
out=$(aws_cmd cognito-idp delete-group \
--user-pool-id "$pool_id" --group-name "test-group" 2>&1) && rc=0 || rc=1
check "Cognito DeleteGroup" "$( [ $rc -eq 0 ] && echo true || echo false )" "$out"

# GetGroup after delete — expect not found
out=$(aws_cmd cognito-idp get-group \
--user-pool-id "$pool_id" --group-name "test-group" 2>&1) && rc=0 || rc=1
check "Cognito GetGroup not found" "$( [ $rc -ne 0 ] && echo true || echo false )" "$out"

# Cleanup
aws_cmd cognito-idp admin-delete-user --user-pool-id "$pool_id" --username "cliuser" >/dev/null 2>&1 || true
aws_cmd cognito-idp delete-user-pool-client --user-pool-id "$pool_id" --client-id "$client_id" >/dev/null 2>&1 || true
aws_cmd cognito-idp delete-user-pool --user-pool-id "$pool_id" >/dev/null 2>&1 || true
}

# ---------------------------------------------------------------------------
# Group registry and entry point
# ---------------------------------------------------------------------------

ALL_GROUPS=(ssm sqs sns s3 dynamodb dynamodb-gsi dynamodb-scan-filter iam sts secretsmanager kms)
ALL_GROUPS=(ssm sqs sns s3 dynamodb dynamodb-gsi dynamodb-scan-filter iam sts secretsmanager kms cognito)

resolve_enabled() {
local names=()
Expand Down
121 changes: 121 additions & 0 deletions sdk-test-java/src/main/java/com/floci/test/tests/CognitoTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import software.amazon.awssdk.services.cognitoidentityprovider.CognitoIdentityProviderClient;
import software.amazon.awssdk.services.cognitoidentityprovider.model.*;

import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Map;

@FlociTestGroup
Expand Down Expand Up @@ -90,6 +92,125 @@ public void run(TestContext ctx) {
}
}

// ── Groups ────────────────────────────────────────────────────

// CreateGroup
try {
CreateGroupResponse groupResp = cognito.createGroup(b -> b
.userPoolId(fPoolId)
.groupName("test-group")
.description("Test group")
.precedence(1));
ctx.check("Cognito CreateGroup",
"test-group".equals(groupResp.group().groupName()));
} catch (Exception e) {
ctx.check("Cognito CreateGroup", false, e);
}

// GetGroup
try {
GetGroupResponse ggResp = cognito.getGroup(b -> b
.userPoolId(fPoolId).groupName("test-group"));
ctx.check("Cognito GetGroup",
"test-group".equals(ggResp.group().groupName())
&& "Test group".equals(ggResp.group().description())
&& ggResp.group().precedence() == 1);
} catch (Exception e) {
ctx.check("Cognito GetGroup", false, e);
}

// CreateGroup duplicate
try {
cognito.createGroup(b -> b.userPoolId(fPoolId).groupName("test-group"));
ctx.check("Cognito CreateGroup duplicate rejected", false);
} catch (GroupExistsException e) {
ctx.check("Cognito CreateGroup duplicate rejected", true);
} catch (Exception e) {
ctx.check("Cognito CreateGroup duplicate rejected", false, e);
}

// ListGroups
try {
ListGroupsResponse lgResp = cognito.listGroups(b -> b.userPoolId(fPoolId));
ctx.check("Cognito ListGroups",
lgResp.groups().stream().anyMatch(g -> "test-group".equals(g.groupName())));
} catch (Exception e) {
ctx.check("Cognito ListGroups", false, e);
}

// AdminAddUserToGroup
try {
cognito.adminAddUserToGroup(b -> b
.userPoolId(fPoolId).groupName("test-group").username(fUsername));
ctx.check("Cognito AdminAddUserToGroup", true);
} catch (Exception e) {
ctx.check("Cognito AdminAddUserToGroup", false, e);
}

// AdminListGroupsForUser
try {
AdminListGroupsForUserResponse algResp = cognito.adminListGroupsForUser(b -> b
.userPoolId(fPoolId).username(fUsername));
ctx.check("Cognito AdminListGroupsForUser",
algResp.groups().stream().anyMatch(g -> "test-group".equals(g.groupName())));
} catch (Exception e) {
ctx.check("Cognito AdminListGroupsForUser", false, e);
}

// Authenticate and verify cognito:groups in JWT
if (clientId != null) {
final String fClientId = clientId;
try {
AdminInitiateAuthResponse authResp = cognito.adminInitiateAuth(b -> b
.userPoolId(fPoolId).clientId(fClientId)
.authFlow(AuthFlowType.ADMIN_NO_SRP_AUTH)
.authParameters(Map.of("USERNAME", fUsername, "PASSWORD", "any")));
String token = authResp.authenticationResult().accessToken();
String[] parts = token.split("\\.");
String payload = new String(Base64.getUrlDecoder().decode(parts[1]), StandardCharsets.UTF_8);
ctx.check("Cognito JWT cognito:groups claim",
payload.contains("\"cognito:groups\"") && payload.contains("\"test-group\""));
} catch (Exception e) {
ctx.check("Cognito JWT cognito:groups claim", false, e);
}
}

// AdminRemoveUserFromGroup
try {
cognito.adminRemoveUserFromGroup(b -> b
.userPoolId(fPoolId).groupName("test-group").username(fUsername));
ctx.check("Cognito AdminRemoveUserFromGroup", true);
} catch (Exception e) {
ctx.check("Cognito AdminRemoveUserFromGroup", false, e);
}

// AdminListGroupsForUser — empty after removal
try {
AdminListGroupsForUserResponse algResp2 = cognito.adminListGroupsForUser(b -> b
.userPoolId(fPoolId).username(fUsername));
ctx.check("Cognito AdminListGroupsForUser empty", algResp2.groups().isEmpty());
} catch (Exception e) {
ctx.check("Cognito AdminListGroupsForUser empty", false, e);
}

// DeleteGroup
try {
cognito.deleteGroup(b -> b.userPoolId(fPoolId).groupName("test-group"));
ctx.check("Cognito DeleteGroup", true);
} catch (Exception e) {
ctx.check("Cognito DeleteGroup", false, e);
}

// GetGroup after delete — expect not found
try {
cognito.getGroup(b -> b.userPoolId(fPoolId).groupName("test-group"));
ctx.check("Cognito GetGroup not found", false);
} catch (ResourceNotFoundException e) {
ctx.check("Cognito GetGroup not found", true);
} catch (Exception e) {
ctx.check("Cognito GetGroup not found", false, e);
}

// ── Cleanup ───────────────────────────────────────────────────

try {
Expand Down
76 changes: 75 additions & 1 deletion sdk-test-node/test-all.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { KMSClient, CreateKeyCommand, ListKeysCommand, DescribeKeyCommand, Encry
import { KinesisClient, CreateStreamCommand, DescribeStreamCommand, PutRecordCommand, GetShardIteratorCommand, GetRecordsCommand, DeleteStreamCommand, ListStreamsCommand } from "@aws-sdk/client-kinesis";
import { CloudWatchClient, PutMetricDataCommand, GetMetricStatisticsCommand, ListMetricsCommand, PutMetricAlarmCommand, DescribeAlarmsCommand, DeleteAlarmsCommand } from "@aws-sdk/client-cloudwatch";
import { createPublicKey, createVerify } from "node:crypto";
import { CognitoIdentityProviderClient, CreateUserPoolCommand, CreateUserPoolClientCommand, CreateResourceServerCommand, DescribeResourceServerCommand, ListResourceServersCommand, UpdateResourceServerCommand, DeleteResourceServerCommand, DeleteUserPoolClientCommand, AdminCreateUserCommand, AdminSetUserPasswordCommand, InitiateAuthCommand, RespondToAuthChallengeCommand, SignUpCommand, ConfirmSignUpCommand, AdminGetUserCommand, ListUsersCommand, DeleteUserPoolCommand } from "@aws-sdk/client-cognito-identity-provider";
import { CognitoIdentityProviderClient, CreateUserPoolCommand, CreateUserPoolClientCommand, CreateResourceServerCommand, DescribeResourceServerCommand, ListResourceServersCommand, UpdateResourceServerCommand, DeleteResourceServerCommand, DeleteUserPoolClientCommand, AdminCreateUserCommand, AdminSetUserPasswordCommand, InitiateAuthCommand, RespondToAuthChallengeCommand, SignUpCommand, ConfirmSignUpCommand, AdminGetUserCommand, ListUsersCommand, DeleteUserPoolCommand, CreateGroupCommand, GetGroupCommand, ListGroupsCommand, DeleteGroupCommand, AdminAddUserToGroupCommand, AdminRemoveUserFromGroupCommand, AdminListGroupsForUserCommand } from "@aws-sdk/client-cognito-identity-provider";

const ENDPOINT = process.env.FLOCI_ENDPOINT || "http://localhost:4566";
const REGION = "us-east-1";
Expand Down Expand Up @@ -1228,6 +1228,80 @@ async function testCognito() {
check("SignUp+Confirm succeeded", true);
});

// ── Groups ──────────────────────────────────────────────────────

await tryOk("CreateGroup", async () => {
const r = await cognito.send(new CreateGroupCommand({
UserPoolId: poolId, GroupName: "test-group",
Description: "Test group", Precedence: 1
}));
check("Group name returned", r.Group.GroupName === "test-group");
});

await tryOk("GetGroup", async () => {
const r = await cognito.send(new GetGroupCommand({
UserPoolId: poolId, GroupName: "test-group"
}));
check("GetGroup name", r.Group.GroupName === "test-group");
check("GetGroup description", r.Group.Description === "Test group");
check("GetGroup precedence", r.Group.Precedence === 1);
});

await tryFail("CreateGroup duplicate", () =>
cognito.send(new CreateGroupCommand({
UserPoolId: poolId, GroupName: "test-group"
})));

await tryOk("ListGroups", async () => {
const r = await cognito.send(new ListGroupsCommand({ UserPoolId: poolId }));
check("Group in list", r.Groups.some(g => g.GroupName === "test-group"));
});

await tryOk("AdminAddUserToGroup", () =>
cognito.send(new AdminAddUserToGroupCommand({
UserPoolId: poolId, GroupName: "test-group", Username: "nodeuser"
})));

await tryOk("AdminListGroupsForUser", async () => {
const r = await cognito.send(new AdminListGroupsForUserCommand({
UserPoolId: poolId, Username: "nodeuser"
}));
check("User has group", r.Groups.some(g => g.GroupName === "test-group"));
});

await tryOk("InitiateAuth groups in JWT", async () => {
const r = await cognito.send(new InitiateAuthCommand({
AuthFlow: "USER_PASSWORD_AUTH",
AuthParameters: { USERNAME: "nodeuser", PASSWORD: "Perm456!" },
ClientId: clientId
}));
const payload = decodeJwtPart(r.AuthenticationResult.AccessToken, 1);
check("JWT cognito:groups present", Array.isArray(payload["cognito:groups"]));
check("JWT cognito:groups contains test-group", payload["cognito:groups"]?.includes("test-group"));
});

await tryOk("AdminRemoveUserFromGroup", () =>
cognito.send(new AdminRemoveUserFromGroupCommand({
UserPoolId: poolId, GroupName: "test-group", Username: "nodeuser"
})));

await tryOk("AdminListGroupsForUser empty", async () => {
const r = await cognito.send(new AdminListGroupsForUserCommand({
UserPoolId: poolId, Username: "nodeuser"
}));
check("No groups after removal", r.Groups.length === 0);
});

await tryOk("DeleteGroup", () =>
cognito.send(new DeleteGroupCommand({
UserPoolId: poolId, GroupName: "test-group"
})));

await tryFail("GetGroup not found", () =>
cognito.send(new GetGroupCommand({
UserPoolId: poolId, GroupName: "test-group"
})));

await tryOk("JWKS endpoint", async () => {
const resp = await fetch(`${ENDPOINT}/${poolId}/.well-known/jwks.json`);
check("JWKS status 200", resp.ok);
Expand Down
Loading