diff --git a/backend/main.py b/backend/main.py index 2d057e7..aaa547e 100644 --- a/backend/main.py +++ b/backend/main.py @@ -67,10 +67,34 @@ if 'AUTHENTICATION_ENABLED' in os.environ: else: print(f"🔐 Authentication {'ENABLED' if config.get('authentication', {}).get('enabled', False) else 'DISABLED'} (from config.yaml)") -# Allow password hash to be set via environment variable (useful for demos) -if 'AUTHENTICATION_PASSWORD_HASH' in os.environ: +# Password configuration priority: +# 1. AUTHENTICATION_PASSWORD env var (plain text, hashed at startup) +# 2. AUTHENTICATION_PASSWORD_HASH env var (pre-hashed) +# 3. authentication.password in config.yaml (plain text, hashed at startup) +# 4. authentication.password_hash in config.yaml (pre-hashed) +# Default password is "admin" if nothing is configured +if 'AUTHENTICATION_PASSWORD' in os.environ: + # Plain text password from env var - hash it + plain_password = os.getenv('AUTHENTICATION_PASSWORD') + config['authentication']['password_hash'] = bcrypt.hashpw( + plain_password.encode('utf-8'), + bcrypt.gensalt() + ).decode('utf-8') + print("🔑 Password loaded from AUTHENTICATION_PASSWORD env var (hashed at startup)") +elif 'AUTHENTICATION_PASSWORD_HASH' in os.environ: + # Pre-hashed password from env var config['authentication']['password_hash'] = os.getenv('AUTHENTICATION_PASSWORD_HASH') print("🔑 Password hash loaded from AUTHENTICATION_PASSWORD_HASH env var") +elif config.get('authentication', {}).get('password'): + # Plain text password from config.yaml - hash it + plain_password = config['authentication']['password'] + config['authentication']['password_hash'] = bcrypt.hashpw( + plain_password.encode('utf-8'), + bcrypt.gensalt() + ).decode('utf-8') + # Clear the plain text password from config for security + del config['authentication']['password'] + print("🔑 Password loaded from config.yaml (hashed at startup)") # Allow secret key to be set via environment variable (for session security) if 'AUTHENTICATION_SECRET_KEY' in os.environ: diff --git a/config.yaml b/config.yaml index 9dbd2f5..5a3653a 100644 --- a/config.yaml +++ b/config.yaml @@ -35,9 +35,16 @@ authentication: # Generate with: python -c "import secrets; print(secrets.token_hex(32))" secret_key: "change_this_to_a_random_secret_key_in_production" - # Password hash - Generate with: python generate_password.py + # Password configuration - choose ONE of the following options: + # + # Option 1: Plain text password (recommended for ease of use) + # The password is hashed automatically at startup # ⚠️ Default password is "admin" - CHANGE THIS for production! - password_hash: "$2b$12$t/6PGExFzdpU2PUta0iVY.eDQwvu63kH.c/d4bEnnHaQ5CspH1yrG" # Default: "admin" + password: "admin" + + # Option 2: Pre-hashed password (for advanced users) + # Generate with: python generate_password.py + # password_hash: "$2b$12$..." # Session expiry in seconds (default: 7 days) session_max_age: 604800 diff --git a/documentation/AUTHENTICATION.md b/documentation/AUTHENTICATION.md index 0f7adb1..ed53822 100644 --- a/documentation/AUTHENTICATION.md +++ b/documentation/AUTHENTICATION.md @@ -49,9 +49,54 @@ For **local testing only**, you can use the default configuration: For any deployment exposed to a network, follow these steps: -### Step 1: Generate a Password Hash +--- -Choose your environment: +## Password Configuration Options + +NoteDiscovery supports two ways to set passwords: + +| Method | Best For | Security | +|--------|----------|----------| +| **Plain text password** | Docker, PikaPods, easy deployment | Password is hashed at startup | +| **Pre-hashed password** | Advanced users, extra security | You control the hashing | + +Both methods are secure - the plain text option simply hashes the password when the app starts. + +--- + +### Option A: Plain Text Password (Recommended for Docker/PikaPods) + +The easiest approach - just set your password directly: + +**Via Environment Variable:** +```bash +# Docker run +docker run -e AUTHENTICATION_ENABLED=true \ + -e AUTHENTICATION_PASSWORD=your_secure_password \ + ... + +# Docker Compose (.env file) +AUTHENTICATION_ENABLED=true +AUTHENTICATION_PASSWORD=your_secure_password +``` + +**Via config.yaml:** +```yaml +authentication: + enabled: true + password: "your_secure_password" + secret_key: "your_generated_secret_key_here" +``` + +The password is automatically hashed with bcrypt when the app starts. + +--- + +### Option B: Pre-Hashed Password (Advanced) + +For users who prefer to hash passwords themselves: + +#### Step 1: Generate a Password Hash **Docker Users:** @@ -81,7 +126,7 @@ The script will: **Copy the hash** - you'll need it for Step 3. -### Step 2: Generate a Secret Key +#### Step 2: Generate a Secret Key Generate a random secret key for session encryption: @@ -100,7 +145,7 @@ python -c "import secrets; print(secrets.token_hex(32))" **Copy the key** - you'll need it for Step 3. -### Step 3: Update `config.yaml` +#### Step 3: Update `config.yaml` Edit your `config.yaml` and update the authentication section: @@ -119,7 +164,9 @@ authentication: session_max_age: 604800 ``` -### Step 4: Restart the Application +--- + +### Restart the Application ```bash # If running locally @@ -132,11 +179,11 @@ docker-compose restart docker restart notediscovery ``` -### Step 5: Test Login +### Test Login Navigate to `http://localhost:8000` and you'll be redirected to the login page. -Enter the password you chose in Step 2. +Enter the password you configured. --- diff --git a/documentation/ENVIRONMENT_VARIABLES.md b/documentation/ENVIRONMENT_VARIABLES.md index 4b32ef2..5a0c268 100644 --- a/documentation/ENVIRONMENT_VARIABLES.md +++ b/documentation/ENVIRONMENT_VARIABLES.md @@ -17,9 +17,22 @@ NoteDiscovery supports environment variables to override configuration settings, | Variable | Type | Default | Description | |----------|------|---------|-------------| | `AUTHENTICATION_ENABLED` | boolean | `config.yaml` | Enable/disable authentication | -| `AUTHENTICATION_PASSWORD_HASH` | string | `config.yaml` | Bcrypt password hash | +| `AUTHENTICATION_PASSWORD` | string | `admin` | Plain text password (hashed automatically at startup) | +| `AUTHENTICATION_PASSWORD_HASH` | string | - | Pre-hashed bcrypt password (for advanced users) | | `AUTHENTICATION_SECRET_KEY` | string | `config.yaml` | Session secret key (for session security) | +> **Password Priority:** `AUTHENTICATION_PASSWORD` takes precedence over `AUTHENTICATION_PASSWORD_HASH`. If both are set, the plain text password is used. + +#### Example: Setting password via environment variable + +```bash +# Docker +docker run -e AUTHENTICATION_ENABLED=true -e AUTHENTICATION_PASSWORD=mysecretpassword ... + +# Docker Compose (in .env file or docker-compose.yml) +AUTHENTICATION_PASSWORD=mysecretpassword +``` + ### Demo Mode | Variable | Type | Default | Description |