re-uploading work

This commit is contained in:
2026-02-04 17:46:30 -06:00
commit 3b14c65998
1388 changed files with 381262 additions and 0 deletions

View File

@@ -0,0 +1,466 @@
# Testing Authentication Endpoints
This guide provides step-by-step instructions for testing the Attune authentication system.
## Prerequisites
1. **Database Running**
```bash
# Start PostgreSQL (if using Docker)
docker run -d \
--name postgres \
-e POSTGRES_PASSWORD=postgres \
-p 5432:5432 \
postgres:15
```
2. **Database Setup**
```bash
# Create database and user
psql -U postgres -c "CREATE DATABASE attune;"
psql -U postgres -c "CREATE USER svc_attune WITH PASSWORD 'attune_password';"
psql -U postgres -c "GRANT ALL PRIVILEGES ON DATABASE attune TO svc_attune;"
```
3. **Run Migrations**
```bash
export DATABASE_URL="postgresql://svc_attune:attune_password@localhost:5432/attune"
sqlx migrate run
```
4. **Set Environment Variables**
```bash
export DATABASE_URL="postgresql://svc_attune:attune_password@localhost:5432/attune"
export JWT_SECRET="my-super-secret-jwt-key-min-256-bits-please"
export JWT_ACCESS_EXPIRATION=3600
export JWT_REFRESH_EXPIRATION=604800
export RUST_LOG=info
```
## Starting the API Server
```bash
cd attune
cargo run --bin attune-api
```
Expected output:
```
INFO Starting Attune API Service
INFO Configuration loaded successfully
INFO Environment: development
INFO Connecting to database...
INFO Database connection established
INFO JWT configuration initialized
INFO Starting server on 127.0.0.1:8080
INFO Server listening on 127.0.0.1:8080
INFO Attune API Service is ready
```
## Testing with cURL
### 1. Health Check (Verify Server is Running)
```bash
curl http://localhost:8080/api/v1/health
```
Expected response:
```json
{
"status": "healthy"
}
```
### 2. Register a New User
```bash
curl -X POST http://localhost:8080/auth/register \
-H "Content-Type: application/json" \
-d '{
"login": "alice",
"password": "securepass123",
"display_name": "Alice Smith"
}'
```
Expected response:
```json
{
"data": {
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 3600
}
}
```
**Save the access_token for the next steps!**
### 3. Login with Existing User
```bash
curl -X POST http://localhost:8080/auth/login \
-H "Content-Type: application/json" \
-d '{
"login": "alice",
"password": "securepass123"
}'
```
Expected response:
```json
{
"data": {
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 3600
}
}
```
### 4. Get Current User (Protected Endpoint)
Replace `YOUR_ACCESS_TOKEN` with the actual token from step 2 or 3:
```bash
curl http://localhost:8080/auth/me \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```
Expected response:
```json
{
"data": {
"id": 1,
"login": "alice",
"display_name": "Alice Smith"
}
}
```
### 5. Change Password (Protected Endpoint)
```bash
curl -X POST http://localhost:8080/auth/change-password \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"current_password": "securepass123",
"new_password": "newsecurepass456"
}'
```
Expected response:
```json
{
"data": {
"success": true,
"message": "Password changed successfully"
}
}
```
### 6. Login with New Password
```bash
curl -X POST http://localhost:8080/auth/login \
-H "Content-Type: application/json" \
-d '{
"login": "alice",
"password": "newsecurepass456"
}'
```
Should return new tokens.
### 7. Refresh Access Token
Save the refresh_token from a previous login, then:
```bash
curl -X POST http://localhost:8080/auth/refresh \
-H "Content-Type: application/json" \
-d '{
"refresh_token": "YOUR_REFRESH_TOKEN"
}'
```
Expected response:
```json
{
"data": {
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 3600
}
}
```
## Error Cases to Test
### Invalid Credentials
```bash
curl -X POST http://localhost:8080/auth/login \
-H "Content-Type: application/json" \
-d '{
"login": "alice",
"password": "wrongpassword"
}'
```
Expected response (401):
```json
{
"error": "Invalid login or password",
"code": "UNAUTHORIZED"
}
```
### Missing Authentication Token
```bash
curl http://localhost:8080/auth/me
```
Expected response (401):
```json
{
"error": {
"code": 401,
"message": "Missing authentication token"
}
}
```
### Invalid Token
```bash
curl http://localhost:8080/auth/me \
-H "Authorization: Bearer invalid.token.here"
```
Expected response (401):
```json
{
"error": {
"code": 401,
"message": "Invalid authentication token"
}
}
```
### Duplicate Registration
Register the same user twice:
```bash
curl -X POST http://localhost:8080/auth/register \
-H "Content-Type: application/json" \
-d '{
"login": "alice",
"password": "securepass123"
}'
```
Expected response (409):
```json
{
"error": "Identity with login 'alice' already exists",
"code": "CONFLICT"
}
```
### Validation Errors
Short password:
```bash
curl -X POST http://localhost:8080/auth/register \
-H "Content-Type: application/json" \
-d '{
"login": "bob",
"password": "short"
}'
```
Expected response (422):
```json
{
"error": "Invalid registration request: ...",
"code": "VALIDATION_ERROR"
}
```
## Testing with HTTPie (Alternative)
If you prefer HTTPie (more readable):
```bash
# Install HTTPie
pip install httpie
# Register
http POST localhost:8080/auth/register \
login=alice password=securepass123 display_name="Alice Smith"
# Login
http POST localhost:8080/auth/login \
login=alice password=securepass123
# Get current user (set TOKEN variable first)
TOKEN="your_access_token_here"
http GET localhost:8080/auth/me \
"Authorization: Bearer $TOKEN"
# Change password
http POST localhost:8080/auth/change-password \
"Authorization: Bearer $TOKEN" \
current_password=securepass123 \
new_password=newsecurepass456
```
## Testing with Postman
1. **Import Collection**
- Create a new collection named "Attune Auth"
- Add base URL variable: `{{baseUrl}}` = `http://localhost:8080`
2. **Setup Environment**
- Create environment "Attune Local"
- Variables:
- `baseUrl`: `http://localhost:8080`
- `accessToken`: (will be set by tests)
- `refreshToken`: (will be set by tests)
3. **Add Requests**
- POST `{{baseUrl}}/auth/register`
- POST `{{baseUrl}}/auth/login`
- GET `{{baseUrl}}/auth/me` with header: `Authorization: Bearer {{accessToken}}`
- POST `{{baseUrl}}/auth/change-password`
- POST `{{baseUrl}}/auth/refresh`
4. **Test Scripts**
Add to login/register requests to save tokens:
```javascript
pm.test("Status is 200", function () {
pm.response.to.have.status(200);
});
var jsonData = pm.response.json();
pm.environment.set("accessToken", jsonData.data.access_token);
pm.environment.set("refreshToken", jsonData.data.refresh_token);
```
## Automated Testing
### Unit Tests
Run the authentication unit tests:
```bash
# Test password hashing
cargo test --package attune-api password
# Test JWT utilities
cargo test --package attune-api jwt
# Test middleware
cargo test --package attune-api middleware
# Run all API tests
cargo test --package attune-api
```
### Integration Tests (Future)
Integration tests will be added to test the full authentication flow:
```bash
cargo test --package attune-api --test auth_integration
```
## Troubleshooting
### Server Won't Start
1. **Database Connection Error**
```
Error: error communicating with database
```
- Verify PostgreSQL is running
- Check DATABASE_URL is correct
- Verify database exists and user has permissions
2. **Migration Error**
```
Error: migration version not found
```
- Run migrations: `sqlx migrate run`
3. **JWT_SECRET Warning**
```
WARN JWT_SECRET not set, using default
```
- Set JWT_SECRET environment variable
### Authentication Fails
1. **Invalid Credentials**
- Verify password is correct
- Check if identity exists in database:
```sql
SELECT * FROM attune.identity WHERE login = 'alice';
```
2. **Token Expired**
- Use the refresh token to get a new access token
- Check JWT_ACCESS_EXPIRATION setting
3. **Invalid Token Format**
- Ensure Authorization header format: `Bearer <token>`
- No extra spaces or quotes
### Database Issues
Check identities in database:
```sql
-- Connect to database
psql -U svc_attune -d attune
-- View all identities
SELECT id, login, display_name, created FROM attune.identity;
-- Check password hash exists
SELECT login,
attributes->>'password_hash' IS NOT NULL as has_password
FROM attune.identity;
```
## Security Notes
- **Never use default JWT_SECRET in production**
- Always use HTTPS in production
- Store tokens securely on the client side
- Implement rate limiting on auth endpoints (future)
- Consider adding MFA for production (future)
## Next Steps
After validating authentication works:
1. Test Pack Management API with authentication
2. Implement additional CRUD APIs
3. Add RBAC permission checking (Phase 2.13)
4. Add integration tests
5. Implement token revocation for logout
## Resources
- [Authentication Documentation](./authentication.md)
- [API Documentation](../README.md)
- [JWT.io](https://jwt.io) - JWT token decoder/debugger