c668485e6f
cognito and permit shared prod environment support * code complete * user creattion tool test harness
328 lines
12 KiB
Markdown
328 lines
12 KiB
Markdown
# Admin User Management Integration Tests
|
|
|
|
This directory contains integration tests for admin user management functionality that use **real AWS Cognito and Permit.io APIs** (no mocks).
|
|
|
|
## Overview
|
|
|
|
These tests validate the complete user management workflow including:
|
|
- User creation in AWS Cognito and Permit.io
|
|
- User retrieval and attribute updates
|
|
- User enable/disable operations
|
|
- User deletion from both systems
|
|
- Role assignment and unassignment in Permit.io
|
|
- User listing with pagination
|
|
- Idempotent operations
|
|
- Environment-based user filtering (`custom:environment_id`)
|
|
- Environment access checks (matching, mismatched, untagged, nonexistent users)
|
|
- EULA service pipeline simulation (list + filter)
|
|
|
|
## Why Integration Tests Are Separate
|
|
|
|
The admin user management code is **excluded from standard CI/CD coverage requirements** because:
|
|
1. Free tier LocalStack doesn't support AWS Cognito
|
|
2. Integration tests require real AWS credentials
|
|
3. Integration tests require real Permit.io API access
|
|
4. Tests create and modify real user accounts
|
|
5. Tests should not run automatically in CI/CD pipelines
|
|
|
|
These tests are designed for **manual execution** during development and pre-production validation.
|
|
|
|
## Prerequisites
|
|
|
|
### AWS Requirements
|
|
|
|
1. **AWS SSO Session** - You must have an active SSO session for the `aarete` profile:
|
|
```bash
|
|
task aws:login
|
|
```
|
|
|
|
2. **IAM Role** with the following Cognito permissions:
|
|
```json
|
|
{
|
|
"Version": "2012-10-17",
|
|
"Statement": [
|
|
{
|
|
"Effect": "Allow",
|
|
"Action": [
|
|
"cognito-idp:AdminCreateUser",
|
|
"cognito-idp:AdminDeleteUser",
|
|
"cognito-idp:AdminGetUser",
|
|
"cognito-idp:AdminUpdateUserAttributes",
|
|
"cognito-idp:AdminDisableUser",
|
|
"cognito-idp:AdminEnableUser",
|
|
"cognito-idp:ListUsers",
|
|
"cognito-idp:DescribeUserPool",
|
|
"cognito-idp:AddCustomAttributes"
|
|
],
|
|
"Resource": "arn:aws:cognito-idp:REGION:ACCOUNT_ID:userpool/POOL_ID"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
3. **Cognito User Pool ID** - `us-east-2_21upuTkkT` (from devbox.json)
|
|
|
|
### Permit.io Requirements
|
|
|
|
1. **Permit.io Account** with API access
|
|
2. **API Key** with permissions to:
|
|
- Create users
|
|
- Delete users
|
|
- Assign/unassign roles
|
|
- Read user roles
|
|
3. **Project ID** and **Environment ID** from Permit.io dashboard
|
|
4. **Roles configured** in Permit.io matching your `permit_policies.yaml`:
|
|
- `super_admin`
|
|
- `user_admin`
|
|
- `auditor`
|
|
- `client_user`
|
|
|
|
## Setup Instructions
|
|
|
|
### Step 1: Create Environment File
|
|
|
|
```bash
|
|
cd test/integration
|
|
cp .env.example .env
|
|
```
|
|
|
|
### Step 2: Configure Credentials
|
|
|
|
Edit `test/integration/.env` and fill in your actual credentials:
|
|
|
|
```bash
|
|
# AWS Configuration
|
|
AWS_REGION=us-east-2
|
|
COGNITO_USER_POOL_ID=us-east-2_21upuTkkT
|
|
|
|
# Suppress welcome emails to avoid AWS Cognito's 50 emails/day limit
|
|
COGNITO_SUPPRESS_EMAILS=true
|
|
|
|
# Permit.io Configuration
|
|
PERMIT_IO_API_KEY=permit_key_YOUR_KEY_HERE
|
|
PERMIT_IO_PROJECT_ID=default
|
|
PERMIT_IO_ENV_ID=dev
|
|
PERMIT_IO_TENANT=default
|
|
```
|
|
|
|
**IMPORTANT:** Never commit the `.env` file to git! It contains sensitive credentials.
|
|
|
|
### Step 3: Verify Permit.io Roles
|
|
|
|
Ensure the following roles exist in your Permit.io environment:
|
|
- `super_admin`
|
|
- `user_admin`
|
|
- `auditor`
|
|
- `client_user`
|
|
|
|
You can create roles through the Permit.io dashboard, API, or use the setup tool at `cmd/auth_related/permit.setup/`.
|
|
|
|
## Running the Tests
|
|
|
|
### CRITICAL: Devbox/LocalStack Environment Override
|
|
|
|
When running inside `devbox shell`, the following environment variables are set for LocalStack
|
|
and **will hijack all AWS SDK calls** (including Cognito) if not overridden:
|
|
|
|
| Variable | Devbox Value | Problem |
|
|
|---|---|---|
|
|
| `AWS_ENDPOINT_URL` | `http://localhost:4566` | Routes all calls to LocalStack |
|
|
| `AWS_ACCESS_KEY_ID` | `test` | Fake LocalStack credential |
|
|
| `AWS_SECRET_ACCESS_KEY` | `test` | Fake LocalStack credential |
|
|
| `AWS_SESSION_TOKEN` | (empty) | May conflict with SSO tokens |
|
|
| `AWS_REGION` | `us-east-1` | Cognito pool is in `us-east-2` |
|
|
|
|
**You MUST unset these variables** to reach real AWS Cognito. The recommended command prefix is:
|
|
|
|
```bash
|
|
env -u AWS_ACCESS_KEY_ID -u AWS_SECRET_ACCESS_KEY -u AWS_SESSION_TOKEN -u AWS_ENDPOINT_URL \
|
|
AWS_REGION=us-east-2 AWS_PROFILE=aarete
|
|
```
|
|
|
|
### Quick Start (Full Suite)
|
|
|
|
1. Authenticate with AWS SSO:
|
|
```bash
|
|
task aws:login
|
|
```
|
|
|
|
2. Verify credentials work (from devbox shell):
|
|
```bash
|
|
env -u AWS_ACCESS_KEY_ID -u AWS_SECRET_ACCESS_KEY -u AWS_SESSION_TOKEN -u AWS_ENDPOINT_URL \
|
|
aws sts get-caller-identity --profile aarete
|
|
```
|
|
|
|
3. Run all 29 integration tests:
|
|
```bash
|
|
env -u AWS_ACCESS_KEY_ID -u AWS_SECRET_ACCESS_KEY -u AWS_SESSION_TOKEN -u AWS_ENDPOINT_URL \
|
|
AWS_REGION=us-east-2 AWS_PROFILE=aarete \
|
|
go test -tags=integration -v -count=1 -timeout=300s ./test/integration/...
|
|
```
|
|
|
|
### Run Only EnvFilter Tests (16 tests - Cognito only)
|
|
|
|
```bash
|
|
env -u AWS_ACCESS_KEY_ID -u AWS_SECRET_ACCESS_KEY -u AWS_SESSION_TOKEN -u AWS_ENDPOINT_URL \
|
|
AWS_REGION=us-east-2 AWS_PROFILE=aarete \
|
|
go test -tags=integration -v -count=1 -timeout=300s ./test/integration/... -run TestEnvFilterSuite
|
|
```
|
|
|
|
### Run Only Admin Tests (13 tests - Cognito + Permit.io)
|
|
|
|
```bash
|
|
env -u AWS_ACCESS_KEY_ID -u AWS_SECRET_ACCESS_KEY -u AWS_SESSION_TOKEN -u AWS_ENDPOINT_URL \
|
|
AWS_REGION=us-east-2 AWS_PROFILE=aarete \
|
|
go test -tags=integration -v -count=1 -timeout=300s ./test/integration/... -run TestSuite
|
|
```
|
|
|
|
### Run Only Permit.io Tests (No Cognito)
|
|
|
|
```bash
|
|
env -u AWS_ACCESS_KEY_ID -u AWS_SECRET_ACCESS_KEY -u AWS_SESSION_TOKEN -u AWS_ENDPOINT_URL \
|
|
AWS_REGION=us-east-2 AWS_PROFILE=aarete \
|
|
go test -tags=integration -v -count=1 -timeout=300s ./test/integration/... -run 'TestSuite/TestPermitIO'
|
|
```
|
|
|
|
### Run a Specific Test
|
|
|
|
```bash
|
|
env -u AWS_ACCESS_KEY_ID -u AWS_SECRET_ACCESS_KEY -u AWS_SESSION_TOKEN -u AWS_ENDPOINT_URL \
|
|
AWS_REGION=us-east-2 AWS_PROFILE=aarete \
|
|
go test -tags=integration -v -count=1 -timeout=300s ./test/integration/... -run TestEnvFilterSuite/TestCreateUser_SetsEnvironmentID
|
|
```
|
|
|
|
## Test Suites
|
|
|
|
The test suite includes **29 integration tests** organized into two suites:
|
|
|
|
### EnvFilter Suite (16 tests - `TestEnvFilterSuite`)
|
|
|
|
Tests environment-based user filtering with `custom:environment_id` in real Cognito:
|
|
|
|
| Test | Description |
|
|
|------|-------------|
|
|
| `TestCreateUser_SetsEnvironmentID` | Creates user with environment_id, verifies attribute persisted |
|
|
| `TestCreateUser_NoEnvironmentID` | Creates user without environment_id (legacy/untagged) |
|
|
| `TestGetUser_ExtractsEnvironmentID` | Fetches user and extracts custom:environment_id |
|
|
| `TestListUsers_FiltersByEnvironment` | Filters user list by environment, includes untagged |
|
|
| `TestListUsers_NoFilterWhenEnvEmpty` | Empty filter returns all users (backward compat) |
|
|
| `TestUserBelongsToEnvironment_Integration` | Tests ownership logic with real Cognito data |
|
|
| `TestUpdateUser_PreservesEnvironmentID` | Updating other attrs doesn't lose environment_id |
|
|
| `TestDeleteUser_EnvScoped` | Delete works for same-env, blocked for cross-env |
|
|
| `TestDisableUser_EnvScoped` | Disable works for same-env, blocked for cross-env |
|
|
| `TestEnableUser_EnvScoped` | Enable works for same-env, blocked for cross-env |
|
|
| `TestEnsureEnvironmentIDAttribute_Idempotent` | Schema registration is idempotent |
|
|
| `TestCheckEnvAccess_MatchingUser_RealCognito` | Matching env user passes access check |
|
|
| `TestCheckEnvAccess_UntaggedUser_RealCognito` | Untagged user passes (backward compat) |
|
|
| `TestCheckEnvAccess_MismatchedUser_RealCognito` | Mismatched env user is denied |
|
|
| `TestCheckEnvAccess_NonexistentUser_RealCognito` | Nonexistent user sub is denied |
|
|
| `TestEULA_FetchUsersFilteredByEnv_RealCognito` | EULA pipeline: list + filter by env |
|
|
|
|
### Admin Suite (13 tests - `TestSuite`)
|
|
|
|
Tests complete user management workflow across Cognito and Permit.io:
|
|
|
|
| Test | Description |
|
|
|------|-------------|
|
|
| `TestCreateUser` | Creates user in both Cognito and Permit.io |
|
|
| `TestCreateUserIdempotent` | Verifies idempotent user creation behavior |
|
|
| `TestGetUser` | Retrieves user details from Cognito |
|
|
| `TestUpdateUserAttributes` | Updates user's first and last name |
|
|
| `TestDisableEnableUser` | Disables and re-enables a user account |
|
|
| `TestDeleteUser` | Deletes user from both Cognito and Permit.io |
|
|
| `TestListUsers` | Lists users with pagination support |
|
|
| `TestRoleAssignment` | Assigns and unassigns roles in Permit.io |
|
|
| `TestPermitIO_CreateAndGetUser` | Creates user in Permit.io, verifies exists |
|
|
| `TestPermitIO_AssignMultipleRoles` | Assigns/unassigns multiple roles |
|
|
| `TestPermitIO_DeleteUser` | Deletes user, verifies with 404 |
|
|
| `TestPermitIO_UserLifecycle` | Complete 9-step lifecycle test |
|
|
| `TestPermitIO_IdempotentOperations` | Tests duplicate operations are idempotent |
|
|
|
|
## Test User Management
|
|
|
|
### Automatic Cleanup
|
|
|
|
The test suites implement automatic cleanup in `TearDownSuite`:
|
|
- All test users are tracked during creation
|
|
- After all tests complete, users are automatically deleted from both Cognito and Permit.io
|
|
- If cleanup fails, warnings are logged but tests still pass
|
|
- **Optional:** Set `SKIP_PERMITIO_CLEANUP=true` to preserve Permit.io users for manual inspection
|
|
|
|
### Manual Cleanup
|
|
|
|
If tests are interrupted and cleanup doesn't run:
|
|
|
|
```bash
|
|
# List test users in Cognito (from devbox shell)
|
|
env -u AWS_ACCESS_KEY_ID -u AWS_SECRET_ACCESS_KEY -u AWS_SESSION_TOKEN -u AWS_ENDPOINT_URL \
|
|
aws cognito-idp list-users --user-pool-id us-east-2_21upuTkkT --profile aarete --region us-east-2
|
|
|
|
# Delete a specific user
|
|
env -u AWS_ACCESS_KEY_ID -u AWS_SECRET_ACCESS_KEY -u AWS_SESSION_TOKEN -u AWS_ENDPOINT_URL \
|
|
aws cognito-idp admin-delete-user \
|
|
--user-pool-id us-east-2_21upuTkkT \
|
|
--username user@example.com \
|
|
--profile aarete --region us-east-2
|
|
```
|
|
|
|
### Test Email Format
|
|
|
|
Test users are created with emails in these formats:
|
|
- Admin suite: `int-test-{name}-{timestamp}@example.com`
|
|
- EnvFilter suite: `envtest-{name}-{nanotimestamp}@example.com`
|
|
|
|
## AWS Cognito Email Limits
|
|
|
|
AWS Cognito has a **daily limit of 50 emails** when using the default email service. The test suite sets `COGNITO_SUPPRESS_EMAILS=true` to avoid this limit. Users are still created with `email_verified: true`.
|
|
|
|
## Troubleshooting
|
|
|
|
### Error: "Attributes did not conform to the schema: custom:environment_id"
|
|
|
|
**Cause:** The `custom:environment_id` attribute hasn't been registered on the Cognito user pool.
|
|
**Solution:** The EnvFilter suite's `SetupSuite` automatically calls `EnsureEnvironmentIDAttribute` to register it. If running individual tests, run the full `TestEnvFilterSuite` first.
|
|
|
|
### Error: "InvalidSecurityToken" or "UnrecognizedClientException"
|
|
|
|
**Cause:** Devbox/LocalStack credentials (`AWS_ACCESS_KEY_ID=test`) are being used instead of SSO.
|
|
**Solution:** Use the `env -u AWS_ACCESS_KEY_ID -u AWS_SECRET_ACCESS_KEY -u AWS_SESSION_TOKEN -u AWS_ENDPOINT_URL` prefix.
|
|
|
|
### Error: "Dial tcp localhost:4566: connection refused"
|
|
|
|
**Cause:** `AWS_ENDPOINT_URL=http://localhost:4566` is routing to LocalStack which isn't running.
|
|
**Solution:** Unset `AWS_ENDPOINT_URL` with the `env -u AWS_ENDPOINT_URL` prefix.
|
|
|
|
### Error: "ExpiredToken" or SSO session expired
|
|
|
|
**Solution:** Re-authenticate with `task aws:login` then re-run the tests.
|
|
|
|
### Error: Required environment variable not set
|
|
|
|
**Solution:** Ensure all required variables are set in `test/integration/.env`.
|
|
|
|
### Error: Role not found in Permit.io
|
|
|
|
**Solution:** Create the required roles in your Permit.io environment using `cmd/auth_related/permit.setup/`.
|
|
|
|
### Tests hang or timeout
|
|
|
|
**Solution:**
|
|
- Check network connectivity to AWS and Permit.io
|
|
- Verify AWS credentials are not expired (`task aws:login`)
|
|
- Try a longer timeout: `-timeout=600s`
|
|
|
|
## CI/CD Exclusion
|
|
|
|
The admin handler code is **intentionally excluded** from CI/CD coverage checks.
|
|
See `scripts/tests.yml` for the exclusion list. This allows `task fullsuite:ci` to pass
|
|
without requiring cloud credentials.
|
|
|
|
## Security Considerations
|
|
|
|
1. **Never commit credentials** - The `.env` file is gitignored
|
|
2. **Use test environments** - Don't run against production Cognito/Permit.io
|
|
3. **Limit IAM permissions** - Use least privilege for test credentials
|
|
4. **Rotate credentials** - Regularly rotate API keys and access keys
|
|
5. **Monitor test accounts** - Review test user creation in CloudWatch/Permit.io logs
|
|
6. **Clean up regularly** - Ensure test users are deleted after runs
|