From 3c92ad7f137b174f02d4e53b3598fbe1144c6e1a Mon Sep 17 00:00:00 2001 From: Rik <24355251+Riktastic@users.noreply.github.com> Date: Thu, 30 Jan 2025 23:03:02 +0100 Subject: [PATCH 1/6] Update README.md Fixed some grammatical errors, made it look better. --- README.md | 112 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 75 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index 2e757ad..a869c5d 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,15 @@ -```markdown # 🦀 RustAPI **An example API built with Rust, Axum, SQLx, and PostgreSQL** [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) ## 🚀 Core Features -- **Rust API Template** - Production-ready starter template with modern practices -- **PostgreSQL Integration** - Full database support with SQLx migrations -- **Comprehensive Health Monitoring** +- **Rust API template** - Production-ready starter template with modern practices, +- **PostgreSQL integration** - Full database support with SQLx migrations, +- **Easy to secure** - HTTP/2 with secure TLS defaults (AWS-LC, FIPS 140-3), +- **Easy to configure** - `.env` and environment variables, +- **JWT authentication** - Secure token-based auth with Argon2 password hashing, +- **Optimized for performance** - Brotli compression, +- **Comprehensive health monitoring** Docker-compatible endpoint with system metrics: ```json { @@ -19,15 +22,14 @@ "status": "degraded" } ``` -- **JWT Authentication** - Secure token-based auth with Argon2 password hashing -- **Granular Access Control** - Role-based endpoint protection: +- **Granular access control** - Role-based endpoint protection: ```rust .route("/", post(post_todo).layer(axum::middleware::from_fn(|req, next| { let allowed_roles = vec![1, 2]; authorize(req, next, allowed_roles) }))) ``` -- **User Context Injection** - Automatic user profile handling in endpoints: +- **User context injection** - Automatic user profile handling in endpoints: ```rust pub async fn post_todo( Extension(user): Extension, // Injected user @@ -39,12 +41,67 @@ })))); } ``` -- **Modern protocols ** - HTTP/2 with secure TLS defaults -- **Observability** - Integrated tracing -- **Optimized for performance** - Brotli compression -- **Easy configuration** - `.env` and environment variables -- **Documented codebase** - Extensive inline comments for easy modification and readability -- **Latest dependencies** - Regularly updated Rust ecosystem crates +- **Observability** - Integrated tracing, +- **Documented codebase** - Extensive inline comments for easy modification and readability, +- **Latest dependencies** - Regularly updated Rust ecosystem crates, + +## 🛠️ Technology stack +| Category | Key Technologies | +|-----------------------|---------------------------------| +| Web Framework | Axum 0.8 + Tower | +| Database | PostgreSQL + SQLx 0.8 | +| Security | JWT + Argon2 + Rustls | +| Monitoring | Tracing + Sysinfo | + +## 📂 Project structure +``` +rustapi/ +├── migrations/ # SQL schema migrations. Creates the required tables and inserts demo data. +├── src/ +│ ├── core/ # Core modules: for reading configuration files, starting the server and configuring HTTPS/ +│ ├── database/ # Database connectivity, getters and setters for the database. +│ ├── middlewares/ # Currently just the authentication system. +│ ├── models/ # Data structures +│ └── routes/ # API endpoints +│ └── mod.rs # API endpoint router. +│ └── .env # Configuration file. +└── Dockerfile # Builds a docker container for the application. +└── compose.yaml # Docker-compose.yaml. Runs container for the application (also includes a PostgreSQL-container). +``` + +## 🌐 Default API endpoints + +| Method | Endpoint | Auth Required | Allowed Roles | Description | +|--------|------------------------|---------------|---------------|--------------------------------------| +| POST | `/signin` | No | None | Authenticate user and get JWT token | +| GET | `/protected` | Yes | 1, 2 | Test endpoint for authenticated users | +| GET | `/health` | No | None | System health check with metrics | +| | | | | | +| **User routes** | | | | | +| GET | `/users/all` | No* | None | Get all users | +| GET | `/users/{id}` | No* | None | Get user by ID | +| POST | `/users/` | No* | None | Create new user | +| | | | | | +| **Todo routes** | | | | | +| GET | `/todos/all` | No* | None | Get all todos | +| POST | `/todos/` | Yes | 1, 2 | Create new todo | +| GET | `/todos/{id}` | No* | None | Get todo by ID | + +**Key:** +🔒 = Requires JWT in `Authorization: Bearer ` header +\* Currently unprotected - recommend adding authentication for production +**Roles:** 1 = User, 2 = Administrator + +**Security notes:** +- All POST endpoints expect JSON payloads +- User creation endpoint should be protected in production +- Consider adding rate limiting to authentication endpoints +**Notes:** +- 🔒 = Requires JWT in `Authorization: Bearer ` header +- Roles: `1` = Regular User, `2` = Administrator +- *Marked endpoints currently unprotected - recommend adding middleware for production use +- All POST endpoints expect JSON payloads + ## 📦 Installation & Usage ```bash @@ -59,7 +116,7 @@ sqlx database create && sqlx migrate run cargo run --release ``` -### 🔐 Default Accounts +### 🔐 Default accounts **Warning:** These accounts should only be used for initial testing. Always change or disable them in production environments. @@ -68,13 +125,15 @@ cargo run --release | `user@test.com` | `test` | User | | `admin@test.com` | `test` | Administrator | -⚠️ **Security Recommendations:** +⚠️ **Security recommendations:** 1. Rotate passwords immediately after initial setup 2. Disable default accounts before deploying to production 3. Implement proper user management endpoints -## ⚙️ Configuration +### ⚙️ Configuration +Create a .env file in the root of the project or configure the application using environment variables. + ```env # ============================== # 📌 DATABASE CONFIGURATION @@ -145,24 +204,3 @@ SERVER_COMPRESSION_LEVEL=6 # Argon2 salt for password hashing (must be kept secret!) AUTHENTICATION_ARGON2_SALT="dMjQgtSmoQIH3Imi" ``` - -## 📂 Project Structure -``` -rustapi/ -├── migrations/ # SQL schema versions -├── src/ -│ ├── core/ # Config, TLS, server setup -│ ├── database/ # Query handling -│ ├── middlewares/ # Auth system -│ ├── models/ # Data structures -│ └── routes/ # API endpoints -└── Dockerfile # Containerization -``` - -## 🛠️ Technology Stack -| Category | Key Technologies | -|-----------------------|---------------------------------| -| Web Framework | Axum 0.8 + Tower | -| Database | PostgreSQL + SQLx 0.8 | -| Security | JWT + Argon2 + Rustls | -| Monitoring | Tracing + Sysinfo | From b2fd07c982f7f5bba2147075c9a6b30cfd522c6e Mon Sep 17 00:00:00 2001 From: Rik <24355251+Riktastic@users.noreply.github.com> Date: Thu, 30 Jan 2025 23:07:04 +0100 Subject: [PATCH 2/6] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a869c5d..a3b4aec 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# 🦀 RustAPI +# 🦀 AxumRustAPI **An example API built with Rust, Axum, SQLx, and PostgreSQL** [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) From 35e6103d1795534f33e89c192f21295f42d86299 Mon Sep 17 00:00:00 2001 From: Rik <24355251+Riktastic@users.noreply.github.com> Date: Thu, 30 Jan 2025 23:10:04 +0100 Subject: [PATCH 3/6] Create LICENSE --- LICENSE | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..b0fec39 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 Rik Heijmann + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From 2ff578c9088e47b634883923cceb166eed8f7449 Mon Sep 17 00:00:00 2001 From: Rik <24355251+Riktastic@users.noreply.github.com> Date: Thu, 30 Jan 2025 22:25:26 +0000 Subject: [PATCH 4/6] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a3b4aec..846168b 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# 🦀 AxumRustAPI +# 🦀 Axum API Quickstart **An example API built with Rust, Axum, SQLx, and PostgreSQL** [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) From e94168edb555cf459b4380dbee84fae14507ef2c Mon Sep 17 00:00:00 2001 From: Rik <24355251+Riktastic@users.noreply.github.com> Date: Thu, 30 Jan 2025 22:28:15 +0000 Subject: [PATCH 5/6] Update README.md --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 846168b..1db554e 100644 --- a/README.md +++ b/README.md @@ -73,19 +73,19 @@ rustapi/ | Method | Endpoint | Auth Required | Allowed Roles | Description | |--------|------------------------|---------------|---------------|--------------------------------------| -| POST | `/signin` | No | None | Authenticate user and get JWT token | +| POST | `/signin` | No | | Authenticate user and get JWT token | | GET | `/protected` | Yes | 1, 2 | Test endpoint for authenticated users | -| GET | `/health` | No | None | System health check with metrics | +| GET | `/health` | No | | System health check with metrics | | | | | | | | **User routes** | | | | | -| GET | `/users/all` | No* | None | Get all users | -| GET | `/users/{id}` | No* | None | Get user by ID | -| POST | `/users/` | No* | None | Create new user | +| GET | `/users/all` | No* | | Get all users | +| GET | `/users/{id}` | No* | | Get user by ID | +| POST | `/users/` | No* | | Create new user | | | | | | | | **Todo routes** | | | | | -| GET | `/todos/all` | No* | None | Get all todos | +| GET | `/todos/all` | No* | | Get all todos | | POST | `/todos/` | Yes | 1, 2 | Create new todo | -| GET | `/todos/{id}` | No* | None | Get todo by ID | +| GET | `/todos/{id}` | No* | | Get todo by ID | **Key:** 🔒 = Requires JWT in `Authorization: Bearer ` header From 830dbdb2074fc62e056ef70d374bea3f26ac0589 Mon Sep 17 00:00:00 2001 From: Rik <24355251+Riktastic@users.noreply.github.com> Date: Thu, 30 Jan 2025 22:38:01 +0000 Subject: [PATCH 6/6] Renamed project. --- src/main.rs | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/src/main.rs b/src/main.rs index 36dde6a..8da78a2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -24,23 +24,15 @@ async fn main() { // Print a cool startup message with ASCII art and emojis println!("{}", r#" - ##### ## ## - ## ## ## - ## ## ## ## ##### ####### ##### #### #### - ##### ## ## ## ## ## ## ## ## ## - #### ## ## ## ## ## ## ## ## ## -## ## ## ### ## ## ## ### ## ## ## -## ## ### ## ##### ### ### ## ##### ###### - ## - - Rustapi - An example API built with Rust, Axum, SQLx, and PostgreSQL - GitHub: https://github.com/Riktastic/rustapi + Axum-API-Quickstart + - An example API built with Rust, Axum, SQLx, and PostgreSQL + - GitHub: https://github.com/Riktastic/Axum-API-Quickstart/ "#); println!("🚀 Starting Rustapi..."); - // Retrieve server IP and port from the environment, default to 0.0.0.0:3000 - let ip: IpAddr = config::get_env_with_default("SERVER_IP", "0.0.0.0") + // Retrieve server IP and port from the environment, default to 127.0.0.1:3000 + let ip: IpAddr = config::get_env_with_default("SERVER_IP", "127.0.0.1") .parse() .expect("❌ Invalid IP address format. Please provide a valid IPv4 address. For example 0.0.0.0 or 127.0.0.1."); let port: u16 = config::get_env_u16("SERVER_PORT", 3000);