Update README.md

This commit is contained in:
Jose Daniel G. Percy 2025-04-08 03:59:51 +08:00
parent fb72f8e86b
commit 452a44d779

153
README.md
View File

@ -1,3 +1,152 @@
# lms-backend # Learner Management System (LMS) Backend
A learner management system made by WIT students, using Rust Actix This is the backend service for the Learner Management System, built with Rust using the Actix Web framework. It provides a RESTful API for the frontend application, handles business logic, interacts with a MariaDB database using SQLx, and implements secure PAKE SRP authentication. The application is designed to be run using Docker and Docker Compose.
## Features
* **RESTful API:** Provides endpoints for authentication, user profiles, admin functions, and potentially course/classroom management in the future.
* **Secure Authentication:** Implements Password-Authenticated Key Exchange (PAKE) using the Secure Remote Password (SRP-6a) protocol via the `srp` crate.
* **High Performance:** Built with Rust and Actix Web for excellent performance, memory safety, and concurrency.
* **Database Interaction:** Uses SQLx for asynchronous, compile-time checked SQL queries against MariaDB.
* **Database Schema Management:** Automatically creates database tables on initial startup if they don't exist.
* **Sample Data Population:** Populates essential data (e.g., courses, sample users without passwords) on first run.
* **Dockerized:** Fully containerized using Docker and Docker Compose for easy setup, consistent environments, and deployment.
* **Configuration:** Configurable via environment variables (`.env` file support).
* **Modular Structure:** Code organized into logical modules (handlers, db, models, errors, config).
* **Basic Logging:** Uses `env_logger` for request and application logging.
## Technologies Used
* **Rust** (Stable toolchain)
* **Actix Web** (v4): High-performance web framework.
* **SQLx:** Asynchronous SQL toolkit with compile-time query checking.
* **`srp` crate:** For SRP-6a protocol implementation.
* **MariaDB:** Relational database (run via Docker).
* **Docker & Docker Compose:** For containerization and orchestration.
* **`serde`:** For data serialization/deserialization (JSON).
* **`dotenv`:** For loading environment variables from `.env` files.
* **`env_logger`:** For flexible logging configuration.
* **`chrono`:** For date/time handling.
* **`hex`:** For encoding/decoding SRP values.
* **`uuid`:** For generating session tokens (current implementation).
## Prerequisites
* **Docker**
* **Docker Compose** (v1 or v2 syntax compatible with the `docker-compose.yml`)
* **Rust Toolchain** (Stable - only needed if building/running outside the provided Docker setup)
## Getting Started
1. **Clone the Repository:** Clone the repository containing *both* the `lms-backend` folder and the main `docker-compose.yml`.
```bash
git clone <your-main-repository-url>
cd <your-main-repository-directory> # Should contain lms-backend/ and docker-compose.yml
```
2. **Create Environment File:** In the **root directory** (the one containing `docker-compose.yml`), create a `.env` file to specify database credentials. You can copy the example below or rely on the defaults defined in `docker-compose.yml`.
```dotenv
# .env (in the root directory)
# MariaDB Credentials (used by docker-compose to init the DB)
MARIADB_ROOT_PASSWORD=supersecretroot
MARIADB_DATABASE=lms_db
MARIADB_USER=lms_user
MARIADB_PASSWORD=lms_password
# Backend Configuration (can override defaults)
# SERVER_ADDR=0.0.0.0:8080 # Already set in compose file
RUST_LOG=info,lms_backend=debug # Example: Set backend log level to debug
# SECRET_KEY=your_secret_for_jwt_if_used # Needed if switching to JWT sessions
```
3. **Build and Run using Docker Compose:** From the **root directory**, run:
```bash
docker-compose up --build -d
```
* `--build`: Forces rebuilding the backend image if code has changed.
* `-d`: Runs the containers in detached mode (in the background).
* The first run might take some time to download images and build the Rust application.
4. **Accessing the API:**
* The API should now be running and accessible at `http://localhost:8080`.
* Test the health check endpoint: `http://localhost:8080/api/health`. You should receive a JSON response indicating success.
5. **Stopping the Services:**
```bash
docker-compose down
```
## Project Structure (`lms-backend/src/`)
```
src/
├── main.rs # Entry point, server setup, middleware, routing
├── config.rs # Configuration loading (.env)
├── db.rs # Database logic (SQLx queries, migrations/setup, data population)
├── handlers.rs # Actix route handlers, business logic, API endpoint definitions
├── models.rs # Data structures (DB models, API request/response structs)
└── errors.rs # Custom error types and `ResponseError` implementation
```
## Configuration
Configuration is primarily handled via environment variables, loaded using the `dotenv` crate during startup within the container. Key variables:
* `DATABASE_URL`: The connection string for MariaDB (automatically constructed in `docker-compose.yml`).
* `SERVER_ADDR`: The address and port the Actix server binds to (e.g., `0.0.0.0:8080`).
* `RUST_LOG`: Controls logging verbosity (e.g., `info`, `debug`, `actix_web=warn,lms_backend=debug`).
* `SECRET_KEY`: **Required** if implementing JWT-based sessions in the future.
These variables are typically passed from the host's `.env` file (if present) or directly set in the `environment` section of the `backend` service in `docker-compose.yml`.
## API Endpoints
The following main API endpoints are implemented in `src/handlers.rs`:
* `GET /api/health`: Health check.
* `POST /api/auth/srp/start`: Initiates SRP login (provides salt, server ephemeral).
* `POST /api/auth/srp/verify`: Verifies client SRP proof, generates session token on success.
* `POST /api/auth/logout`: (Basic) Invalidates session token.
* `GET /api/profile/{user_id}`: Retrieves user profile information.
* `PUT /api/profile/settings`: Updates user settings (e.g., profile picture).
* `GET /api/admin/dashboard`: Gets admin dashboard counts.
* `GET /api/admin/students`: Lists students (basic).
* `GET /api/admin/students/{student_id}/financials`: Gets (mocked) financial data for a student.
Refer to `src/handlers.rs` and `src/models.rs` for detailed request/response structures.
## Database
* **Type:** MariaDB (run via `mariadb:10.11` Docker image).
* **Interaction:** Asynchronous queries via `sqlx`.
* **Schema:** Defined and created in `src/db.rs::init_db`. Tables include `students`, `teachers`, `courses`, `enrollments`. SRP salt and verifier fields replace traditional password hashes.
* **Persistence:** Database data is persisted using a Docker named volume (`mariadb_data`) defined in `docker-compose.yml`.
* **Initial Data:** `src/db.rs::populate_initial_data` adds sample courses and users (students/teachers) **without any password/SRP data set**. Users cannot log in until a password-setting mechanism is implemented.
## Authentication (SRP)
* Uses the PAKE SRP-6a protocol.
* **Flow:**
1. Client sends `userId` to `/api/auth/srp/start`.
2. Server looks up user (student or teacher), finds SRP `salt` and `verifier` (if set), generates server ephemeral `B`, and stores temporary challenge state (**in memory**). Responds with `salt`, `B`, and `userType`.
3. Client calculates its ephemeral `A` and proof `M1`, sends `userId`, `userType`, `A`, `M1` to `/api/auth/srp/verify`.
4. Server retrieves challenge state, verifies `M1`. If valid, calculates server proof `M2`, generates a session token (UUID), stores session (**in memory**), and responds with `M2` and login data (including token).
5. Client verifies `M2`.
## Important Notes & TODOs
* 🚨 **Production State Management:** The current use of `AppState` (in-memory `Mutex<HashMap>`) for storing active SRP challenges and user sessions is **NOT suitable for production**. It will lose state on restart and doesn't scale. **Replace this** with a persistent solution like Redis or a dedicated database table for sessions and potentially challenges (with TTL).
* 🔐 **Authentication Middleware:** Protected routes (`/profile/*`, `/admin/*`, etc.) currently **lack proper token validation middleware**. Implement Actix middleware to verify the `Authorization: Bearer <token>` header against the active session store before allowing access.
* 🔑 **Password Setting/Registration:** There is currently **no mechanism** for users to set their initial password or change it. An endpoint needs to be created that takes a username/password, generates the SRP salt and verifier using `srp::server::generate_verifier`, and stores them in the database for the corresponding user.
* 🧪 **Testing:** Implement comprehensive unit and integration tests for handlers, database logic, and authentication flow.
* 📈 **Scalability:** Consider connection pool tuning (`max_connections` in `main.rs`) and potential optimizations for high-load scenarios.
* 📚 **API Documentation:** Consider generating API documentation (e.g., using OpenAPI specs).
## Contributing
<!-- Optional: Link to Contribution Guidelines if applicable -->
## License
<!-- Optional: Link to License file if applicable -->