Update "unnamed"
@@ -1,648 +0,0 @@
|
|||||||
# User Management and Authentication System
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
The DanceLessonsCoach user management and authentication system provides secure user authentication, personalized experiences, and administrative capabilities. This document describes the system architecture, API endpoints, and integration points.
|
|
||||||
|
|
||||||
## Architecture
|
|
||||||
|
|
||||||
```mermaid
|
|
||||||
graph TD
|
|
||||||
A[Client] -->|HTTP Request| B[Authentication Middleware]
|
|
||||||
B -->|Valid Token| C[Authorized Endpoints]
|
|
||||||
B -->|Invalid Token| D[401 Unauthorized]
|
|
||||||
C --> E[Greet Service]
|
|
||||||
C --> F[User Profile Service]
|
|
||||||
C --> G[Admin Service]
|
|
||||||
E -->|Personalized Response| A
|
|
||||||
F -->|User Data| H[PostgreSQL]
|
|
||||||
G -->|Admin Operations| H
|
|
||||||
```
|
|
||||||
|
|
||||||
## Core Components
|
|
||||||
|
|
||||||
### 1. User Model
|
|
||||||
|
|
||||||
**Database Schema:**
|
|
||||||
```sql
|
|
||||||
CREATE TABLE users (
|
|
||||||
id SERIAL PRIMARY KEY,
|
|
||||||
created_at TIMESTAMP WITH TIME ZONE,
|
|
||||||
updated_at TIMESTAMP WITH TIME ZONE,
|
|
||||||
deleted_at TIMESTAMP WITH TIME ZONE,
|
|
||||||
username VARCHAR(50) UNIQUE NOT NULL,
|
|
||||||
password_hash VARCHAR(255) NOT NULL,
|
|
||||||
description TEXT,
|
|
||||||
current_goal TEXT,
|
|
||||||
is_admin BOOLEAN DEFAULT FALSE,
|
|
||||||
allow_password_reset BOOLEAN DEFAULT FALSE,
|
|
||||||
last_login TIMESTAMP WITH TIME ZONE
|
|
||||||
);
|
|
||||||
```
|
|
||||||
|
|
||||||
**Fields:**
|
|
||||||
- `username`: Unique identifier (3-50 alphanumeric characters)
|
|
||||||
- `password_hash`: bcrypt-hashed password
|
|
||||||
- `description`: User's personal description
|
|
||||||
- `current_goal`: User's current dance learning goal
|
|
||||||
- `is_admin`: Administrative privileges flag
|
|
||||||
- `allow_password_reset`: Flag for password reset eligibility
|
|
||||||
|
|
||||||
### 2. Authentication Service
|
|
||||||
|
|
||||||
**Features:**
|
|
||||||
- JWT token generation and validation
|
|
||||||
- bcrypt password hashing (work factor 12)
|
|
||||||
- 30-minute token expiration
|
|
||||||
- Secure cookie-based token storage
|
|
||||||
- Admin master password authentication
|
|
||||||
|
|
||||||
**Environment Variables:**
|
|
||||||
```bash
|
|
||||||
# JWT Configuration
|
|
||||||
DLC_JWT_SECRET="your-secure-random-secret-key"
|
|
||||||
DLC_JWT_EXPIRATION="30m"
|
|
||||||
|
|
||||||
# Admin Configuration
|
|
||||||
DLC_ADMIN_USERNAME="admin"
|
|
||||||
DLC_ADMIN_MASTER_PASSWORD="secure-master-password"
|
|
||||||
|
|
||||||
# Database Configuration
|
|
||||||
DLC_DB_HOST="localhost"
|
|
||||||
DLC_DB_PORT="5432"
|
|
||||||
DLC_DB_USER="dancecoach"
|
|
||||||
DLC_DB_PASSWORD="secure-password"
|
|
||||||
DLC_DB_NAME="dance_lessons_coach"
|
|
||||||
DLC_DB_SSL_MODE="disable"
|
|
||||||
```
|
|
||||||
|
|
||||||
## API Endpoints
|
|
||||||
|
|
||||||
### Authentication Endpoints
|
|
||||||
|
|
||||||
#### POST `/api/v1/auth/register`
|
|
||||||
**Request:**
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"username": "john_doe",
|
|
||||||
"password": "securePassword123!"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Response (201 Created):**
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"id": 1,
|
|
||||||
"username": "john_doe",
|
|
||||||
"created_at": "2024-04-06T10:00:00Z",
|
|
||||||
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Validation Rules:**
|
|
||||||
- `username`: Required, 3-50 chars, alphanumeric only
|
|
||||||
- `password`: Required, min 8 chars
|
|
||||||
|
|
||||||
#### POST `/api/v1/auth/login`
|
|
||||||
**Request:**
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"username": "john_doe",
|
|
||||||
"password": "securePassword123!"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Response (200 OK):**
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"id": 1,
|
|
||||||
"username": "john_doe",
|
|
||||||
"is_admin": false,
|
|
||||||
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
|
|
||||||
"expires_at": "2024-04-06T10:30:00Z"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### POST `/api/v1/auth/reset-password`
|
|
||||||
**Request (for flagged users only):**
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"username": "john_doe",
|
|
||||||
"new_password": "newSecurePassword456!"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Response (200 OK):**
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"message": "Password reset successfully"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### User Profile Endpoints
|
|
||||||
|
|
||||||
#### GET `/api/v1/users/me`
|
|
||||||
**Headers:**
|
|
||||||
```
|
|
||||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
|
||||||
```
|
|
||||||
|
|
||||||
**Response (200 OK):**
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"id": 1,
|
|
||||||
"username": "john_doe",
|
|
||||||
"description": "Dance enthusiast learning salsa",
|
|
||||||
"current_goal": "Master basic salsa steps",
|
|
||||||
"created_at": "2024-04-06T10:00:00Z",
|
|
||||||
"last_login": "2024-04-06T10:15:00Z"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### PUT `/api/v1/users/me`
|
|
||||||
**Request:**
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"description": "Passionate dancer learning multiple styles",
|
|
||||||
"current_goal": "Prepare for salsa competition"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Response (200 OK):**
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"id": 1,
|
|
||||||
"username": "john_doe",
|
|
||||||
"description": "Passionate dancer learning multiple styles",
|
|
||||||
"current_goal": "Prepare for salsa competition",
|
|
||||||
"updated_at": "2024-04-06T10:30:00Z"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### PUT `/api/v1/users/me/password`
|
|
||||||
**Request:**
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"current_password": "securePassword123!",
|
|
||||||
"new_password": "evenMoreSecurePassword456!"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Response (200 OK):**
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"message": "Password updated successfully"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Admin Endpoints
|
|
||||||
|
|
||||||
#### GET `/api/v1/admin/users`
|
|
||||||
**Headers:**
|
|
||||||
```
|
|
||||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
|
||||||
X-Admin-Key: master-admin-key
|
|
||||||
```
|
|
||||||
|
|
||||||
**Response (200 OK):**
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"users": [
|
|
||||||
{
|
|
||||||
"id": 1,
|
|
||||||
"username": "john_doe",
|
|
||||||
"is_admin": false,
|
|
||||||
"allow_password_reset": false,
|
|
||||||
"created_at": "2024-04-06T10:00:00Z"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 2,
|
|
||||||
"username": "jane_smith",
|
|
||||||
"is_admin": true,
|
|
||||||
"allow_password_reset": true,
|
|
||||||
"created_at": "2024-04-05T15:30:00Z"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"total": 2
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### POST `/api/v1/admin/users/{username}/allow-reset`
|
|
||||||
**Headers:**
|
|
||||||
```
|
|
||||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
|
||||||
X-Admin-Key: master-admin-key
|
|
||||||
```
|
|
||||||
|
|
||||||
**Response (200 OK):**
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"message": "Password reset allowed for user john_doe"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### DELETE `/api/v1/admin/users/{username}`
|
|
||||||
**Headers:**
|
|
||||||
```
|
|
||||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
|
||||||
X-Admin-Key: master-admin-key
|
|
||||||
```
|
|
||||||
|
|
||||||
**Response (200 OK):**
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"message": "User john_doe deleted successfully"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Integration with Greet Service
|
|
||||||
|
|
||||||
### Current Behavior
|
|
||||||
```
|
|
||||||
GET /api/v1/greet/John
|
|
||||||
Response: {"message": "Hello John!"}
|
|
||||||
```
|
|
||||||
|
|
||||||
### New Behavior with Authentication
|
|
||||||
```
|
|
||||||
GET /api/v1/greet
|
|
||||||
Headers: Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
|
||||||
Response: {"message": "Hello john_doe!"}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Implementation:**
|
|
||||||
```go
|
|
||||||
func (s *Service) Greet(ctx context.Context, name string) string {
|
|
||||||
// Extract authenticated username from context
|
|
||||||
username := auth.GetUsernameFromContext(ctx)
|
|
||||||
|
|
||||||
if username != "" {
|
|
||||||
return "Hello " + username + "!"
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fallback to original behavior
|
|
||||||
if name == "" {
|
|
||||||
return "Hello world!"
|
|
||||||
}
|
|
||||||
return "Hello " + name + "!"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Password Reset Workflow
|
|
||||||
|
|
||||||
```mermaid
|
|
||||||
sequenceDiagram
|
|
||||||
participant User
|
|
||||||
participant Admin
|
|
||||||
participant System
|
|
||||||
participant Database
|
|
||||||
|
|
||||||
User->>System: Forgot password (no auth)
|
|
||||||
System-->>User: 403 Forbidden
|
|
||||||
|
|
||||||
User->>Admin: Request password reset
|
|
||||||
Admin->>System: POST /api/v1/admin/users/john_doe/allow-reset
|
|
||||||
System->>Database: Set allow_password_reset = true
|
|
||||||
Database-->>System: Success
|
|
||||||
System-->>Admin: 200 OK
|
|
||||||
|
|
||||||
User->>System: POST /api/v1/auth/reset-password
|
|
||||||
System->>Database: Check allow_password_reset flag
|
|
||||||
Database-->>System: Flag is true
|
|
||||||
System->>Database: Update password_hash
|
|
||||||
Database-->>System: Success
|
|
||||||
System->>Database: Set allow_password_reset = false
|
|
||||||
System-->>User: 200 OK
|
|
||||||
```
|
|
||||||
|
|
||||||
## Security Considerations
|
|
||||||
|
|
||||||
### Password Storage
|
|
||||||
- **Algorithm:** bcrypt with work factor 12
|
|
||||||
- **Implementation:** `golang.org/x/crypto/bcrypt`
|
|
||||||
- **Salt:** Automatic per-password salt
|
|
||||||
|
|
||||||
### JWT Security
|
|
||||||
- **Algorithm:** HS256 with secure random key
|
|
||||||
- **Expiration:** 30 minutes (configurable)
|
|
||||||
- **Storage:** HTTP-only, Secure cookies
|
|
||||||
- **Claims:** User ID, username, admin flag, expiration
|
|
||||||
|
|
||||||
### Rate Limiting
|
|
||||||
- **Authentication Endpoints:** 5 requests per minute per IP
|
|
||||||
- **Password Reset:** 3 attempts per hour per user
|
|
||||||
- **Implementation:** Chi middleware
|
|
||||||
|
|
||||||
### Input Validation
|
|
||||||
- **Username:** 3-50 alphanumeric characters
|
|
||||||
- **Password:** Minimum 8 characters
|
|
||||||
- **Description/Goal:** Maximum 500 characters
|
|
||||||
|
|
||||||
## Error Handling
|
|
||||||
|
|
||||||
### Standard Error Format
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"error": "error_code",
|
|
||||||
"message": "Human-readable message",
|
|
||||||
"details": [
|
|
||||||
{
|
|
||||||
"field": "username",
|
|
||||||
"message": "Username must be at least 3 characters"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Common Error Codes
|
|
||||||
- `auth_invalid_credentials`: Invalid username/password
|
|
||||||
- `auth_token_expired`: JWT token expired
|
|
||||||
- `auth_token_invalid`: Invalid JWT token
|
|
||||||
- `auth_unauthorized`: Missing or invalid authorization
|
|
||||||
- `validation_failed`: Input validation failed
|
|
||||||
- `user_not_found`: User does not exist
|
|
||||||
- `user_exists`: Username already taken
|
|
||||||
- `password_reset_not_allowed`: User not flagged for reset
|
|
||||||
- `admin_required`: Admin privileges required
|
|
||||||
|
|
||||||
## Database Setup
|
|
||||||
|
|
||||||
### Docker Compose
|
|
||||||
```yaml
|
|
||||||
version: '3.8'
|
|
||||||
|
|
||||||
services:
|
|
||||||
postgres:
|
|
||||||
image: postgres:15-alpine
|
|
||||||
container_name: dance-lessons-coach-db
|
|
||||||
environment:
|
|
||||||
POSTGRES_USER: dancecoach
|
|
||||||
POSTGRES_PASSWORD: secure-password
|
|
||||||
POSTGRES_DB: dance_lessons_coach
|
|
||||||
ports:
|
|
||||||
- "5432:5432"
|
|
||||||
volumes:
|
|
||||||
- postgres_data:/var/lib/postgresql/data
|
|
||||||
healthcheck:
|
|
||||||
test: ["CMD-SHELL", "pg_isready -U dancecoach"]
|
|
||||||
interval: 5s
|
|
||||||
timeout: 5s
|
|
||||||
retries: 5
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
postgres_data:
|
|
||||||
```
|
|
||||||
|
|
||||||
### Database Migration
|
|
||||||
```bash
|
|
||||||
# Initialize database
|
|
||||||
go run cmd/server/main.go migrate
|
|
||||||
|
|
||||||
# Run migrations
|
|
||||||
goose -dir migrations/postgres up
|
|
||||||
```
|
|
||||||
|
|
||||||
## Testing Strategy
|
|
||||||
|
|
||||||
### Unit Tests
|
|
||||||
- Password hashing/verification
|
|
||||||
- JWT token generation/validation
|
|
||||||
- User model validation
|
|
||||||
- Repository methods
|
|
||||||
|
|
||||||
### Integration Tests
|
|
||||||
- Authentication flow
|
|
||||||
- Authorization middleware
|
|
||||||
- Database operations
|
|
||||||
- Password reset workflow
|
|
||||||
|
|
||||||
### BDD Tests
|
|
||||||
```gherkin
|
|
||||||
Feature: User Authentication
|
|
||||||
Scenario: Successful user registration
|
|
||||||
Given I am not authenticated
|
|
||||||
When I register with valid credentials
|
|
||||||
Then I should receive a JWT token
|
|
||||||
And my user account should be created
|
|
||||||
|
|
||||||
Scenario: Successful login
|
|
||||||
Given I have a registered account
|
|
||||||
When I login with correct credentials
|
|
||||||
Then I should receive a JWT token
|
|
||||||
And the token should expire in 30 minutes
|
|
||||||
|
|
||||||
Scenario: Personalized greeting for authenticated user
|
|
||||||
Given I am authenticated as "john_doe"
|
|
||||||
When I request the default greeting
|
|
||||||
Then the response should be "{"message":"Hello john_doe!"}"
|
|
||||||
```
|
|
||||||
|
|
||||||
## CI/CD Integration
|
|
||||||
|
|
||||||
### New Dependencies
|
|
||||||
```bash
|
|
||||||
# Add to go.mod
|
|
||||||
require (
|
|
||||||
github.com/golang-jwt/jwt/v5 v5.0.0
|
|
||||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa
|
|
||||||
gorm.io/gorm v1.25.0
|
|
||||||
gorm.io/driver/postgres v1.5.0
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Pipeline Changes
|
|
||||||
1. Add PostgreSQL service to CI environment
|
|
||||||
2. Run database migrations before tests
|
|
||||||
3. Include authentication tests in test suite
|
|
||||||
4. Add security scanning for dependencies
|
|
||||||
|
|
||||||
## Deployment Considerations
|
|
||||||
|
|
||||||
### Configuration
|
|
||||||
```yaml
|
|
||||||
# config.yaml
|
|
||||||
database:
|
|
||||||
host: localhost
|
|
||||||
port: 5432
|
|
||||||
user: dancecoach
|
|
||||||
password: secure-password
|
|
||||||
name: dance_lessons_coach
|
|
||||||
ssl_mode: disable
|
|
||||||
|
|
||||||
auth:
|
|
||||||
jwt_secret: your-secure-random-secret-key
|
|
||||||
jwt_expiration: 30m
|
|
||||||
admin_username: admin
|
|
||||||
admin_master_password: secure-master-password
|
|
||||||
```
|
|
||||||
|
|
||||||
### Environment Variables
|
|
||||||
```bash
|
|
||||||
# Database
|
|
||||||
export DLC_DB_HOST="localhost"
|
|
||||||
export DLC_DB_PORT="5432"
|
|
||||||
export DLC_DB_USER="dancecoach"
|
|
||||||
export DLC_DB_PASSWORD="secure-password"
|
|
||||||
export DLC_DB_NAME="dance_lessons_coach"
|
|
||||||
export DLC_DB_SSL_MODE="disable"
|
|
||||||
|
|
||||||
# Authentication
|
|
||||||
export DLC_JWT_SECRET="your-secure-random-secret-key"
|
|
||||||
export DLC_JWT_EXPIRATION="30m"
|
|
||||||
export DLC_ADMIN_USERNAME="admin"
|
|
||||||
export DLC_ADMIN_MASTER_PASSWORD="secure-master-password"
|
|
||||||
```
|
|
||||||
|
|
||||||
## Monitoring and Observability
|
|
||||||
|
|
||||||
### Metrics
|
|
||||||
- `auth_login_success_total`: Successful logins
|
|
||||||
- `auth_login_failure_total`: Failed login attempts
|
|
||||||
- `auth_register_total`: User registrations
|
|
||||||
- `auth_token_issued_total`: JWT tokens issued
|
|
||||||
- `user_active_total`: Active users
|
|
||||||
|
|
||||||
### Logging
|
|
||||||
- Authentication attempts (success/failure)
|
|
||||||
- Password changes
|
|
||||||
- Admin operations
|
|
||||||
- Rate limiting events
|
|
||||||
|
|
||||||
### Alerts
|
|
||||||
- Multiple failed login attempts
|
|
||||||
- Admin account modifications
|
|
||||||
- Unusual password reset activity
|
|
||||||
|
|
||||||
## Future Enhancements
|
|
||||||
|
|
||||||
### Short-term (Next 3 Months)
|
|
||||||
1. **Refresh Tokens:** Long-lived refresh tokens with rotation
|
|
||||||
2. **Rate Limiting:** IP-based rate limiting for auth endpoints
|
|
||||||
3. **Password Strength:** Enforce stronger password requirements
|
|
||||||
4. **Account Lockout:** Temporary lockout after failed attempts
|
|
||||||
|
|
||||||
### Medium-term (Next 6 Months)
|
|
||||||
1. **Multi-factor Authentication:** TOTP or backup codes
|
|
||||||
2. **User Activity Logging:** Comprehensive audit trails
|
|
||||||
3. **Session Management:** View and revoke active sessions
|
|
||||||
4. **Password Expiration:** Enforce periodic password changes
|
|
||||||
|
|
||||||
### Long-term (Future)
|
|
||||||
1. **OAuth Integration:** Google, Facebook, Apple sign-in
|
|
||||||
2. **Social Features:** User profiles, followers, messaging
|
|
||||||
3. **Role-Based Access:** Fine-grained permissions
|
|
||||||
4. **User Preferences:** Theme, language, notifications
|
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
|
|
||||||
### Common Issues
|
|
||||||
|
|
||||||
**Issue:** Authentication fails with valid credentials
|
|
||||||
- **Check:** Password hash comparison logic
|
|
||||||
- **Check:** JWT secret key configuration
|
|
||||||
- **Check:** Database connection
|
|
||||||
|
|
||||||
**Issue:** Password reset not working
|
|
||||||
- **Check:** User has `allow_password_reset` flag set
|
|
||||||
- **Check:** Admin has set the flag correctly
|
|
||||||
- **Check:** Rate limiting not blocking requests
|
|
||||||
|
|
||||||
**Issue:** Personalized greeting not showing username
|
|
||||||
- **Check:** Authentication middleware is properly configured
|
|
||||||
- **Check:** JWT token is valid and not expired
|
|
||||||
- **Check:** Context contains username after authentication
|
|
||||||
|
|
||||||
## Migration Guide
|
|
||||||
|
|
||||||
### From No Authentication to User System
|
|
||||||
|
|
||||||
1. **Add Dependencies:**
|
|
||||||
```bash
|
|
||||||
go get github.com/golang-jwt/jwt/v5
|
|
||||||
go get golang.org/x/crypto
|
|
||||||
go get gorm.io/gorm
|
|
||||||
go get gorm.io/driver/postgres
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **Update Configuration:**
|
|
||||||
- Add database configuration
|
|
||||||
- Add JWT configuration
|
|
||||||
- Add admin configuration
|
|
||||||
|
|
||||||
3. **Update Server:**
|
|
||||||
- Add authentication middleware
|
|
||||||
- Add user repository initialization
|
|
||||||
- Add auth routes
|
|
||||||
|
|
||||||
4. **Update Greet Service:**
|
|
||||||
- Modify to check for authenticated username
|
|
||||||
- Maintain backward compatibility
|
|
||||||
|
|
||||||
5. **Update Tests:**
|
|
||||||
- Add authentication scenarios
|
|
||||||
- Update existing tests for new behavior
|
|
||||||
- Add BDD tests for user management
|
|
||||||
|
|
||||||
6. **Update CI/CD:**
|
|
||||||
- Add PostgreSQL to test environment
|
|
||||||
- Update test scripts
|
|
||||||
- Add security scanning
|
|
||||||
|
|
||||||
## References
|
|
||||||
|
|
||||||
- [GORM Documentation](https://gorm.io/)
|
|
||||||
- [JWT RFC 7519](https://tools.ietf.org/html/rfc7519)
|
|
||||||
- [bcrypt Documentation](https://pkg.go.dev/golang.org/x/crypto/bcrypt)
|
|
||||||
- [OWASP Authentication Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html)
|
|
||||||
- [Chi Router Middleware](https://github.com/go-chi/chi)
|
|
||||||
|
|
||||||
## Appendix
|
|
||||||
|
|
||||||
### Username Validation Regex
|
|
||||||
```go
|
|
||||||
var usernameRegex = regexp.MustCompile(`^[a-zA-Z0-9]{3,50}$`)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Password Hashing Example
|
|
||||||
```go
|
|
||||||
import "golang.org/x/crypto/bcrypt"
|
|
||||||
|
|
||||||
func HashPassword(password string) (string, error) {
|
|
||||||
bytes, err := bcrypt.GenerateFromPassword([]byte(password), 12)
|
|
||||||
return string(bytes), err
|
|
||||||
}
|
|
||||||
|
|
||||||
func CheckPasswordHash(password, hash string) bool {
|
|
||||||
err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
|
|
||||||
return err == nil
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### JWT Token Example
|
|
||||||
```go
|
|
||||||
import (
|
|
||||||
"github.com/golang-jwt/jwt/v5"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Claims struct {
|
|
||||||
UserID uint `json:"user_id"`
|
|
||||||
Username string `json:"username"`
|
|
||||||
IsAdmin bool `json:"is_admin"`
|
|
||||||
jwt.RegisteredClaims
|
|
||||||
}
|
|
||||||
|
|
||||||
func GenerateJWT(user *User, secret string, expiration time.Duration) (string, error) {
|
|
||||||
claims := &Claims{
|
|
||||||
UserID: user.ID,
|
|
||||||
Username: user.Username,
|
|
||||||
IsAdmin: user.IsAdmin,
|
|
||||||
RegisteredClaims: jwt.RegisteredClaims{
|
|
||||||
ExpiresAt: jwt.NewNumericDate(time.Now().Add(expiration)),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
|
||||||
return token.SignedString([]byte(secret))
|
|
||||||
}
|
|
||||||
```
|
|
||||||
155
unnamed.md
Normal file
155
unnamed.md
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
# DanceLessonsCoach User Management & Authentication
|
||||||
|
|
||||||
|
# 🎯 Key Features
|
||||||
|
|
||||||
|
### 👤 Personalized Greetings
|
||||||
|
**"Hello Alex! Ready for your salsa lesson? 💃"**
|
||||||
|
|
||||||
|
When you're logged in, DanceLessonsCoach remembers your name and welcomes you personally. No more generic "Hello world" - now it's "Hello [YourName]" with a touch of dance enthusiasm!
|
||||||
|
|
||||||
|
### 📝 Your Dance Profile
|
||||||
|
**Express your dance personality and track your progress**
|
||||||
|
|
||||||
|
- **About Me:** Share your dance story and personality
|
||||||
|
- **Current Goal:** Set and update your dance learning objectives
|
||||||
|
- **Progress Tracking:** See how far you've come in your dance journey
|
||||||
|
|
||||||
|
### 🔐 Secure & Private
|
||||||
|
**Dance-focused authentication without compromising privacy**
|
||||||
|
|
||||||
|
- Simple username/password system - no email required
|
||||||
|
- Industry-standard security to protect your account
|
||||||
|
- Optional authentication - use as guest or create an account
|
||||||
|
- Admin support for password recovery when needed
|
||||||
|
|
||||||
|
### 👥 Admin Support
|
||||||
|
**Quick help when you need it**
|
||||||
|
|
||||||
|
Forgot your password? Our admins can quickly enable password reset so you can get back to dancing without hassle.
|
||||||
|
|
||||||
|
## 💃 User Experience Journey
|
||||||
|
|
||||||
|
### New User Registration
|
||||||
|
```
|
||||||
|
1. Click "Create Account"
|
||||||
|
2. Choose your username
|
||||||
|
3. Set a secure password
|
||||||
|
4. Start your personalized dance journey!
|
||||||
|
```
|
||||||
|
|
||||||
|
### Returning User Login
|
||||||
|
```
|
||||||
|
1. Enter your username and password
|
||||||
|
2. Receive your personalized greeting
|
||||||
|
3. Continue where you left off
|
||||||
|
4. Update your profile anytime
|
||||||
|
```
|
||||||
|
|
||||||
|
### Password Recovery (Admin-Assisted)
|
||||||
|
```
|
||||||
|
1. Contact our admin team
|
||||||
|
2. Quick verification process
|
||||||
|
3. Set your new password
|
||||||
|
4. Back to dancing in minutes!
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🎨 What Makes Us Different
|
||||||
|
|
||||||
|
### Privacy First
|
||||||
|
- **No email required** - Create account with just username
|
||||||
|
- **No personal data collection** - We respect your privacy
|
||||||
|
- **Guest mode available** - Try before you commit
|
||||||
|
|
||||||
|
### Dance Focused
|
||||||
|
- **Dance-specific profiles** - Designed for dancers, by dancers
|
||||||
|
- **Goal tracking** - Set and achieve your dance objectives
|
||||||
|
- **Community identity** - Express your unique dance personality
|
||||||
|
|
||||||
|
### Personal Connection
|
||||||
|
- **App remembers you** - Personalized greetings every time
|
||||||
|
- **Your dance journey** - Progress tracking and motivation
|
||||||
|
- **Emotional connection** - More than just a dance app
|
||||||
|
|
||||||
|
## 🚀 Coming Soon
|
||||||
|
|
||||||
|
### Short-term Enhancements
|
||||||
|
- **Profile customization** - More ways to express yourself
|
||||||
|
- **Dance style preferences** - Tailor your experience
|
||||||
|
- **Activity tracking** - Monitor your learning progress
|
||||||
|
|
||||||
|
### Future Features
|
||||||
|
- **Dance partner matching** - Connect with other dancers
|
||||||
|
- **Achievement badges** - Celebrate your milestones
|
||||||
|
- **Community events** - Join dance challenges and competitions
|
||||||
|
- **Personal coach matching** - Find your perfect instructor
|
||||||
|
|
||||||
|
## 📱 Simple & Intuitive Interface
|
||||||
|
|
||||||
|
### Login Screen
|
||||||
|
```
|
||||||
|
+---------------------+
|
||||||
|
| DanceLessonsCoach |
|
||||||
|
| |
|
||||||
|
| Username: [______] |
|
||||||
|
| Password: [______] |
|
||||||
|
| |
|
||||||
|
| [Login] [Register] |
|
||||||
|
| |
|
||||||
|
| Continue as guest |
|
||||||
|
+---------------------+
|
||||||
|
```
|
||||||
|
|
||||||
|
### Personalized Experience
|
||||||
|
```
|
||||||
|
+---------------------+
|
||||||
|
| Hello Alex! 👋 |
|
||||||
|
| |
|
||||||
|
| Ready for today's |
|
||||||
|
| salsa lesson? 💃 |
|
||||||
|
| |
|
||||||
|
| [Start Lesson] |
|
||||||
|
+---------------------+
|
||||||
|
```
|
||||||
|
|
||||||
|
### Your Dance Profile
|
||||||
|
```
|
||||||
|
+---------------------+
|
||||||
|
| 👤 Alex's Profile |
|
||||||
|
| |
|
||||||
|
| 💬 About Me: |
|
||||||
|
| Passionate salsa |
|
||||||
|
| dancer learning |
|
||||||
|
| multiple styles |
|
||||||
|
| |
|
||||||
|
| 🎯 Current Goal: |
|
||||||
|
| Master basic steps |
|
||||||
|
| by summer 🌞 |
|
||||||
|
| |
|
||||||
|
| [Edit Profile] |
|
||||||
|
+---------------------+
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🎯 Our Vision
|
||||||
|
|
||||||
|
DanceLessonsCoach aims to create the most personal and engaging dance learning experience. By combining personalized technology with dance expertise, we help you:
|
||||||
|
|
||||||
|
- **Feel connected** to your dance journey
|
||||||
|
- **Stay motivated** with progress tracking
|
||||||
|
- **Achieve your goals** with progress tracking
|
||||||
|
- **Join a community** of like-minded dancers
|
||||||
|
- **Achieve your goals** with personalized coaching
|
||||||
|
|
||||||
|
## 📞 Support & Community
|
||||||
|
|
||||||
|
Need help or want to connect with other dancers?
|
||||||
|
|
||||||
|
- **Admin Support:** Quick password recovery assistance
|
||||||
|
- **Community Forum:** Share your progress and tips
|
||||||
|
- **Dance Challenges:** Join fun competitions
|
||||||
|
- **Feedback:** Help shape the future of DanceLessonsCoach
|
||||||
|
|
||||||
|
## 🌟 Join the DanceLessonsCoach Family
|
||||||
|
|
||||||
|
Whether you're a beginner taking your first dance steps or an experienced dancer looking to refine your skills, DanceLessonsCoach provides the personalized experience you deserve.
|
||||||
|
|
||||||
|
**Create your account today and start your dance journey!** 💃🕺
|
||||||
Reference in New Issue
Block a user