6.6 KiB
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
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 identifierusername: Unique username (required, no spaces allowed)password_hash: SHA256(password + salt) in hexadecimal formatsalt: 16-character random salt unique to each useremail: Optional email addressrole: User role -user,admin, ormoderatoris_active: Boolean flag for account status (0=inactive, 1=active)created_at: Account creation timestampupdated_at: Last update timestamp
Security Features
Password Hashing
Passwords are hashed using SHA256 with a unique salt for each user:
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
cd build
make dbmanager
Commands
Register a New User
./dbmanager register <username> <password> [email] [role]
Examples:
# 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
./dbmanager authenticate <username> <password>
Example:
./dbmanager authenticate john password123
List All Users
./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
./dbmanager list-role <role>
Example:
./dbmanager list-role admin
Update User Role
./dbmanager setrole <username> <role>
Example:
./dbmanager setrole john admin
Deactivate User
./dbmanager deactivate <username>
Example:
./dbmanager deactivate john
Activate User
./dbmanager activate <username>
Example:
./dbmanager activate john
Using Database in Server Code
Initialize Database
#include "database.h"
Database db("scar_chat.db");
if (!db.initialize()) {
std::cerr << "Failed to initialize database" << std::endl;
return 1;
}
Register User
if (db.register_user("alice", "password123", "alice@example.com", "user")) {
std::cout << "User registered successfully" << std::endl;
}
Authenticate User
if (db.authenticate_user("alice", "password123")) {
std::cout << "Authentication successful" << std::endl;
} else {
std::cout << "Authentication failed" << std::endl;
}
Get User Information
User user = db.get_user("alice");
if (!user.username.empty()) {
std::cout << "Found user: " << user.username << " (role: " << user.role << ")" << std::endl;
}
Get All Users
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
std::vector<User> admins = db.get_users_by_role("admin");
for (const auto &admin : admins) {
std::cout << admin.username << std::endl;
}
Update User Role
if (db.update_user_role("bob", "moderator")) {
std::cout << "User role updated" << std::endl;
}
Deactivate/Activate User
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:
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:
- Initialize database on server startup
- Handle
LOGIN:username:passwordmessages from clients - Validate credentials using
authenticate_user() - Store authenticated username with client session
- 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):
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