# Das File Storage Web Application A production-ready file storage service built with FastAPI, PostgreSQL, and session-based authentication. ## Features - **Web Interface**: Modern, responsive GUI for users and admins - **User Authentication**: Session-based auth for web, HTTP Basic Auth and API Key for REST API - **Role-Based Access**: Admin and regular user roles - **File Management**: Upload, download, delete files via web UI or API - **Secure Sharing**: Generate secure share links without exposing usernames or filenames - **Admin Panel**: Full user management interface (create, delete, block users) - **Settings Page**: Change password, manage API keys - **Password Security**: PBKDF2-SHA256 password hashing - **Database**: PostgreSQL for all metadata storage ## Quick Start ### Using Docker Compose (Recommended) 1. Clone the repository 2. Update database credentials in `docker-compose.yml` 3. Run: ```bash docker-compose up -d ``` The application will be available at `http://localhost:8000` by default ### Project Structure ``` project/ ├── main.py # Main application file ├── requirements.txt # Python dependencies ├── docker-compose.yml # Docker configuration ├── Dockerfile # Container image ├── .env # Environment variables ├── templates/ # HTML templates │ ├── base.html # Base template │ ├── login.html # Login page │ ├── user_files.html # User dashboard │ ├── settings.html # Settings page │ └── admin.html # Admin panel └── uploads/ # File storage directory ``` ### Manual Installation 1. Install PostgreSQL and create a database: ```sql CREATE DATABASE filestore; ``` 2. Install Python dependencies: ```bash pip install -r requirements.txt ``` 3. Create `.env` file: ```bash cp .env.example .env # Edit .env with your database credentials ``` 4. Update `configs/server_config.yaml` file with your own server's configuration (including `secrets.yaml` if needed) 5. Create templates directory and add HTML files: ```bash mkdir templates # Copy all template files (base.html, login.html, user_files.html, settings.html, admin.html) ``` 6. Run the application: ```bash python main.py ``` Or with uvicorn: ```bash uvicorn main:app --host 0.0.0.0 --port 8000 --reload ``` ## Default Admin Account On first startup, a default admin account is created: - **Username**: `admin` - **Password**: `admin123` - **⚠️ Change this password immediately in production!** The admin API key will be printed in the console on first startup. ## Web Interface ### User Interface 1. **Login Page** (`/login`) - Clean, modern login interface - Username and password authentication 2. **Dashboard** (`/dashboard`) - View all your uploaded files - Upload new files with drag-and-drop - Download files - Generate and copy share links - Delete files - File size and upload date information 3. **Settings** (`/settings`) - Change your password - View and copy your API key - Regenerate API key - View account information ### Admin Interface 4. **Admin Panel** (`/admin`) - Dashboard statistics (total users, active/blocked, total files) - User management table - Create new users - Block/unblock users - Delete users - View file counts per user ### Navigation All pages have a navigation bar with: - User badge showing username and role - Quick access to dashboard, settings, and admin panel (if admin) - Logout button ## API Documentation Once running, visit: - Interactive API docs: `http://localhost:8000/docs` - Alternative docs: `http://localhost:8000/redoc` ## API Endpoints ### Authentication **HTTP Basic Auth**: Use username and password in the Authorization header ```bash curl -u username:password http://localhost:8000/api/files ``` **API Key Auth**: Use X-API-Key header ```bash curl -H "X-API-Key: your-api-key" http://localhost:8000/api/files ``` ### User Management (Admin Only) #### Create User ```bash POST /api/users Authorization: Basic admin:admin123 Content-Type: application/json { "username": "newuser", "password": "securepass123", "is_admin": false } ``` #### List Users ```bash GET /api/users Authorization: Basic admin:admin123 ``` #### Delete User ```bash DELETE /api/users/{user_id} Authorization: Basic admin:admin123 ``` #### Block/Unblock User ```bash PATCH /api/users/{user_id}/block?block=true Authorization: Basic admin:admin123 ``` #### Get Your API Key ```bash GET /api/users/me/api-key Authorization: Basic username:password ``` #### Regenerate API Key ```bash POST /api/users/me/api-key/regenerate Authorization: Basic username:password ``` ### File Management #### Upload File ```bash POST /api/files/upload Authorization: Basic username:password Content-Type: multipart/form-data file=@/path/to/file.pdf ``` With API Key: ```bash curl -X POST \ -H "X-API-Key: your-api-key" \ -F "file=@document.pdf" \ http://localhost:8000/api/files/upload ``` #### List Your Files ```bash GET /api/files Authorization: Basic username:password ``` #### Download File ```bash GET /api/files/{file_id}/download Authorization: Basic username:password ``` #### Delete File ```bash DELETE /api/files/{file_id} Authorization: Basic username:password ``` ### Public File Sharing #### Download Shared File (No Auth Required) ```bash GET /share/{share_token} ``` Example: `http://localhost:8000/share/abc123xyz...` ## Database Schema ### Users Table - `id`: Primary key - `username`: Unique username - `password_hash`: PBKDF2-SHA256 hashed password - `is_admin`: Admin role flag - `is_blocked`: Block status - `api_key`: Unique API key for REST authentication - `created_at`: Account creation timestamp ### Files Table - `id`: Primary key - `filename`: Original filename - `stored_filename`: Unique stored filename - `file_size`: File size in bytes - `content_type`: MIME type - `share_token`: Secure token for public sharing - `user_id`: Foreign key to users - `uploaded_at`: Upload timestamp ## Security Features 1. **Password Hashing**: PBKDF2-SHA256 with 100,000 iterations 2. **Secure Tokens**: Cryptographically secure random tokens for API keys and share links 3. **User Isolation**: Users can only access their own files 4. **Admin Controls**: Block/unblock users, manage accounts 5. **Share Links**: No exposure of usernames or original filenames ## Production Deployment ### Environment Variables ```bash DATABASE_URL=postgresql://user:pass@host:port/dbname UPLOAD_DIR=/var/app/uploads ``` ### Security Checklist - [ ] Change default admin password - [ ] Use strong database credentials - [ ] Enable HTTPS/TLS - [ ] Set up firewall rules - [ ] Configure backup strategy - [ ] Set up monitoring and logging - [ ] Limit file upload sizes - [ ] Implement rate limiting - [ ] Regular security updates ### Nginx Configuration Example ```nginx server { listen 80; server_name yourdomain.com; client_max_body_size 100M; location / { proxy_pass http://localhost:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } ``` ### PostgreSQL Optimization ```sql -- Create indexes for better performance CREATE INDEX idx_files_user_id ON files(user_id); CREATE INDEX idx_files_share_token ON files(share_token); CREATE INDEX idx_users_username ON users(username); CREATE INDEX idx_users_api_key ON users(api_key); ``` ## Testing ### Create a Test User ```bash curl -X POST http://localhost:8000/api/users \ -u admin:admin123 \ -H "Content-Type: application/json" \ -d '{"username": "testuser", "password": "testpass123"}' ``` ### Upload a Test File ```bash echo "Hello World" > test.txt curl -X POST http://localhost:8000/api/files/upload \ -u testuser:testpass123 \ -F "file=@test.txt" ``` ### List Files ```bash curl http://localhost:8000/api/files \ -u testuser:testpass123 ``` ## Troubleshooting ### Database Connection Issues - Verify PostgreSQL is running - Check DATABASE_URL is correct - Ensure database exists and user has permissions ### File Upload Issues - Check UPLOAD_DIR exists and has write permissions - Verify disk space is available - Check file size limits ### Authentication Issues - Verify username/password are correct - Check if user is blocked - Ensure API key is valid and not regenerated ## Support For issues and questions, please open an issue on the repository. ###### _Made by -=:dAs:=-_