301 lines
6.6 KiB
Markdown
301 lines
6.6 KiB
Markdown
|
|
# SCAR Chat - Database Documentation
|
||
|
|
|
||
|
|
## Overview
|
||
|
|
|
||
|
|
The SCAR Chat server now includes a SQLite3 database system for user authentication and management. All passwords are securely stored using SHA256 hashing with per-user salt values.
|
||
|
|
|
||
|
|
## Database Schema
|
||
|
|
|
||
|
|
### Users Table
|
||
|
|
|
||
|
|
```sql
|
||
|
|
CREATE TABLE users(
|
||
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||
|
|
username TEXT UNIQUE NOT NULL,
|
||
|
|
password_hash TEXT NOT NULL,
|
||
|
|
salt TEXT NOT NULL,
|
||
|
|
email TEXT,
|
||
|
|
role TEXT DEFAULT 'user',
|
||
|
|
is_active BOOLEAN DEFAULT 1,
|
||
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||
|
|
);
|
||
|
|
```
|
||
|
|
|
||
|
|
**Fields:**
|
||
|
|
- `id`: Unique user identifier
|
||
|
|
- `username`: Unique username (required, no spaces allowed)
|
||
|
|
- `password_hash`: SHA256(password + salt) in hexadecimal format
|
||
|
|
- `salt`: 16-character random salt unique to each user
|
||
|
|
- `email`: Optional email address
|
||
|
|
- `role`: User role - `user`, `admin`, or `moderator`
|
||
|
|
- `is_active`: Boolean flag for account status (0=inactive, 1=active)
|
||
|
|
- `created_at`: Account creation timestamp
|
||
|
|
- `updated_at`: Last update timestamp
|
||
|
|
|
||
|
|
## Security Features
|
||
|
|
|
||
|
|
### Password Hashing
|
||
|
|
|
||
|
|
Passwords are hashed using SHA256 with a unique salt for each user:
|
||
|
|
|
||
|
|
```cpp
|
||
|
|
hash = SHA256(password + salt)
|
||
|
|
```
|
||
|
|
|
||
|
|
**Why this approach?**
|
||
|
|
- SHA256 is widely tested and cryptographically secure
|
||
|
|
- Per-user salt prevents rainbow table attacks
|
||
|
|
- Even if database is compromised, passwords are not recoverable
|
||
|
|
|
||
|
|
**Security Note:** In production, consider using bcrypt or Argon2 for additional computational cost and timing attack resistance.
|
||
|
|
|
||
|
|
### Minimum Requirements
|
||
|
|
|
||
|
|
- **Username:** Unique, required
|
||
|
|
- **Password:** Minimum 8 characters (enforced in code)
|
||
|
|
- **Email:** Optional but recommended for account recovery
|
||
|
|
|
||
|
|
## Database Manager Tool
|
||
|
|
|
||
|
|
The `dbmanager` executable provides command-line user management.
|
||
|
|
|
||
|
|
### Building
|
||
|
|
|
||
|
|
```bash
|
||
|
|
cd build
|
||
|
|
make dbmanager
|
||
|
|
```
|
||
|
|
|
||
|
|
### Commands
|
||
|
|
|
||
|
|
#### Register a New User
|
||
|
|
|
||
|
|
```bash
|
||
|
|
./dbmanager register <username> <password> [email] [role]
|
||
|
|
```
|
||
|
|
|
||
|
|
**Examples:**
|
||
|
|
```bash
|
||
|
|
# Register regular user
|
||
|
|
./dbmanager register john password123 john@example.com user
|
||
|
|
|
||
|
|
# Register admin
|
||
|
|
./dbmanager register admin SecureP@ss123 admin@scar.local admin
|
||
|
|
|
||
|
|
# Register moderator
|
||
|
|
./dbmanager register moderator ModPass456 mod@scar.local moderator
|
||
|
|
```
|
||
|
|
|
||
|
|
#### Authenticate User
|
||
|
|
|
||
|
|
```bash
|
||
|
|
./dbmanager authenticate <username> <password>
|
||
|
|
```
|
||
|
|
|
||
|
|
**Example:**
|
||
|
|
```bash
|
||
|
|
./dbmanager authenticate john password123
|
||
|
|
```
|
||
|
|
|
||
|
|
#### List All Users
|
||
|
|
|
||
|
|
```bash
|
||
|
|
./dbmanager list
|
||
|
|
```
|
||
|
|
|
||
|
|
**Output:**
|
||
|
|
```
|
||
|
|
================================================================================
|
||
|
|
Username Email Role Status
|
||
|
|
================================================================================
|
||
|
|
admin admin@scar.local admin Active
|
||
|
|
john john@example.com user Active
|
||
|
|
moderator mod@scar.local moderator Active
|
||
|
|
================================================================================
|
||
|
|
```
|
||
|
|
|
||
|
|
#### List Users by Role
|
||
|
|
|
||
|
|
```bash
|
||
|
|
./dbmanager list-role <role>
|
||
|
|
```
|
||
|
|
|
||
|
|
**Example:**
|
||
|
|
```bash
|
||
|
|
./dbmanager list-role admin
|
||
|
|
```
|
||
|
|
|
||
|
|
#### Update User Role
|
||
|
|
|
||
|
|
```bash
|
||
|
|
./dbmanager setrole <username> <role>
|
||
|
|
```
|
||
|
|
|
||
|
|
**Example:**
|
||
|
|
```bash
|
||
|
|
./dbmanager setrole john admin
|
||
|
|
```
|
||
|
|
|
||
|
|
#### Deactivate User
|
||
|
|
|
||
|
|
```bash
|
||
|
|
./dbmanager deactivate <username>
|
||
|
|
```
|
||
|
|
|
||
|
|
**Example:**
|
||
|
|
```bash
|
||
|
|
./dbmanager deactivate john
|
||
|
|
```
|
||
|
|
|
||
|
|
#### Activate User
|
||
|
|
|
||
|
|
```bash
|
||
|
|
./dbmanager activate <username>
|
||
|
|
```
|
||
|
|
|
||
|
|
**Example:**
|
||
|
|
```bash
|
||
|
|
./dbmanager activate john
|
||
|
|
```
|
||
|
|
|
||
|
|
## Using Database in Server Code
|
||
|
|
|
||
|
|
### Initialize Database
|
||
|
|
|
||
|
|
```cpp
|
||
|
|
#include "database.h"
|
||
|
|
|
||
|
|
Database db("scar_chat.db");
|
||
|
|
if (!db.initialize()) {
|
||
|
|
std::cerr << "Failed to initialize database" << std::endl;
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Register User
|
||
|
|
|
||
|
|
```cpp
|
||
|
|
if (db.register_user("alice", "password123", "alice@example.com", "user")) {
|
||
|
|
std::cout << "User registered successfully" << std::endl;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Authenticate User
|
||
|
|
|
||
|
|
```cpp
|
||
|
|
if (db.authenticate_user("alice", "password123")) {
|
||
|
|
std::cout << "Authentication successful" << std::endl;
|
||
|
|
} else {
|
||
|
|
std::cout << "Authentication failed" << std::endl;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Get User Information
|
||
|
|
|
||
|
|
```cpp
|
||
|
|
User user = db.get_user("alice");
|
||
|
|
if (!user.username.empty()) {
|
||
|
|
std::cout << "Found user: " << user.username << " (role: " << user.role << ")" << std::endl;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Get All Users
|
||
|
|
|
||
|
|
```cpp
|
||
|
|
std::vector<User> users = db.get_all_users();
|
||
|
|
for (const auto &user : users) {
|
||
|
|
std::cout << user.username << " - " << user.role << std::endl;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Get Users by Role
|
||
|
|
|
||
|
|
```cpp
|
||
|
|
std::vector<User> admins = db.get_users_by_role("admin");
|
||
|
|
for (const auto &admin : admins) {
|
||
|
|
std::cout << admin.username << std::endl;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Update User Role
|
||
|
|
|
||
|
|
```cpp
|
||
|
|
if (db.update_user_role("bob", "moderator")) {
|
||
|
|
std::cout << "User role updated" << std::endl;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Deactivate/Activate User
|
||
|
|
|
||
|
|
```cpp
|
||
|
|
db.deactivate_user("bob"); // Disable account
|
||
|
|
db.activate_user("bob"); // Re-enable account
|
||
|
|
```
|
||
|
|
|
||
|
|
## Database File Location
|
||
|
|
|
||
|
|
By default, the database is created as `scar_chat.db` in the current working directory.
|
||
|
|
|
||
|
|
**To use a custom location:**
|
||
|
|
|
||
|
|
```cpp
|
||
|
|
Database db("/path/to/custom/scar_chat.db");
|
||
|
|
db.initialize();
|
||
|
|
```
|
||
|
|
|
||
|
|
## Integration with Server
|
||
|
|
|
||
|
|
The database module is now compiled into `chat_server`. To integrate authentication:
|
||
|
|
|
||
|
|
1. Initialize database on server startup
|
||
|
|
2. Handle `LOGIN:username:password` messages from clients
|
||
|
|
3. Validate credentials using `authenticate_user()`
|
||
|
|
4. Store authenticated username with client session
|
||
|
|
5. Validate user permissions for actions (based on role)
|
||
|
|
|
||
|
|
## Troubleshooting
|
||
|
|
|
||
|
|
### Database File Already Exists
|
||
|
|
- The `initialize()` function checks for existing tables
|
||
|
|
- Existing data is preserved; tables are only created if they don't exist
|
||
|
|
|
||
|
|
### Password Too Short
|
||
|
|
- Minimum 8 characters required
|
||
|
|
- Error: `"Password must be at least 8 characters long"`
|
||
|
|
|
||
|
|
### User Already Exists
|
||
|
|
- Usernames are unique
|
||
|
|
- Error: `"User already exists"`
|
||
|
|
|
||
|
|
### Authentication Failed
|
||
|
|
- Check username spelling (case-sensitive)
|
||
|
|
- Verify password is correct
|
||
|
|
- Confirm user account is active (not deactivated)
|
||
|
|
|
||
|
|
## Database Cleanup
|
||
|
|
|
||
|
|
To reset the database (delete all data):
|
||
|
|
|
||
|
|
```bash
|
||
|
|
rm scar_chat.db
|
||
|
|
```
|
||
|
|
|
||
|
|
The next run of the database tool or server will create a fresh database with the schema.
|
||
|
|
|
||
|
|
## Performance Considerations
|
||
|
|
|
||
|
|
- SQLite3 is optimized for local file-based storage
|
||
|
|
- Suitable for small to medium deployments (< 10K concurrent users)
|
||
|
|
- For larger deployments, consider migrating to PostgreSQL or MySQL
|
||
|
|
- Database operations are fast (typical query < 1ms)
|
||
|
|
|
||
|
|
## Future Enhancements
|
||
|
|
|
||
|
|
- Session tokens and JWT authentication
|
||
|
|
- Password reset functionality
|
||
|
|
- User profile customization
|
||
|
|
- Activity logging and audit trails
|
||
|
|
- Rate limiting per user
|
||
|
|
- Two-factor authentication
|