Compare commits

..

9 Commits

Author SHA1 Message Date
2c30abb5c6 Updated gitignore (#36)
All checks were successful
Release Tagging / release (push) Successful in 33s
Rust Build / Check (push) Successful in 46s
Rust Build / Test Suite (push) Successful in 55s
Rust Build / Rustfmt (push) Successful in 27s
Rust Build / Clippy (push) Successful in 41s
Rust Build / build (push) Successful in 1m5s
Rust Build / Check (pull_request) Successful in 39s
Rust Build / Test Suite (pull_request) Successful in 53s
Rust Build / Rustfmt (pull_request) Successful in 25s
Rust Build / Clippy (pull_request) Successful in 39s
Rust Build / build (pull_request) Successful in 1m1s
Reviewed-on: #36
Co-authored-by: phoenix <kundeng00@pm.me>
Co-committed-by: phoenix <kundeng00@pm.me>
2025-05-27 20:23:50 +00:00
1817ab01d6 Test fix (#35)
All checks were successful
Release Tagging / release (push) Successful in 32s
Rust Build / Check (push) Successful in 46s
Rust Build / Test Suite (push) Successful in 57s
Rust Build / Rustfmt (push) Successful in 34s
Rust Build / Clippy (push) Successful in 47s
Rust Build / build (push) Successful in 1m18s
Rust Build / Check (pull_request) Successful in 46s
Rust Build / Test Suite (pull_request) Successful in 1m3s
Rust Build / Rustfmt (pull_request) Successful in 27s
Rust Build / Clippy (pull_request) Successful in 46s
Rust Build / build (pull_request) Successful in 1m24s
Reviewed-on: #35
Co-authored-by: phoenix <kundeng00@pm.me>
Co-committed-by: phoenix <kundeng00@pm.me>
2025-04-27 18:06:13 +00:00
31be156be3 Added ssh default for building docker image (#33)
All checks were successful
Rust Build / Check (push) Successful in 46s
Rust Build / Test Suite (push) Successful in 1m3s
Rust Build / Rustfmt (push) Successful in 28s
Rust Build / Clippy (push) Successful in 46s
Rust Build / build (push) Successful in 1m16s
Rust Build / Check (pull_request) Successful in 53s
Rust Build / Test Suite (pull_request) Successful in 1m0s
Rust Build / Rustfmt (pull_request) Successful in 27s
Rust Build / Clippy (pull_request) Successful in 52s
Rust Build / build (pull_request) Successful in 1m15s
Release Tagging / release (push) Successful in 43s
Reviewed-on: #33
Co-authored-by: phoenix <kundeng00@pm.me>
Co-committed-by: phoenix <kundeng00@pm.me>
2025-04-27 16:31:11 +00:00
fc6b66f2e6 Docker changes (#31)
All checks were successful
Release Tagging / release (push) Successful in 34s
Rust Build / Check (push) Successful in 49s
Rust Build / Test Suite (push) Successful in 1m18s
Rust Build / Rustfmt (push) Successful in 33s
Rust Build / Clippy (push) Successful in 52s
Rust Build / build (push) Successful in 1m30s
Rust Build / Check (pull_request) Successful in 58s
Rust Build / Test Suite (pull_request) Successful in 1m8s
Rust Build / Rustfmt (pull_request) Successful in 32s
Rust Build / Clippy (pull_request) Successful in 52s
Rust Build / build (pull_request) Successful in 1m19s
Reviewed-on: #31
Co-authored-by: phoenix <kundeng00@pm.me>
Co-committed-by: phoenix <kundeng00@pm.me>
2025-04-13 18:38:38 +00:00
6dec9942cc Version bump (#29)
All checks were successful
Release Tagging / release (push) Successful in 37s
Rust Build / Check (push) Successful in 57s
Rust Build / Test Suite (push) Successful in 1m14s
Rust Build / Rustfmt (push) Successful in 29s
Rust Build / Clippy (push) Successful in 1m5s
Rust Build / build (push) Successful in 1m22s
Rust Build / Check (pull_request) Successful in 57s
Rust Build / Test Suite (pull_request) Successful in 1m15s
Rust Build / Rustfmt (pull_request) Successful in 39s
Rust Build / Clippy (pull_request) Successful in 55s
Rust Build / build (pull_request) Successful in 1m40s
Reviewed-on: #29
Co-authored-by: phoenix <kundeng00@pm.me>
Co-committed-by: phoenix <kundeng00@pm.me>
2025-04-12 00:16:34 +00:00
a855db9ecc Workflow changes (#30)
Some checks failed
Rust Build / Check (push) Successful in 49s
Rust Build / Test Suite (push) Successful in 1m36s
Rust Build / Rustfmt (push) Successful in 29s
Rust Build / Clippy (push) Successful in 52s
Rust Build / build (push) Successful in 1m33s
Rust Build / Check (pull_request) Successful in 1m1s
Rust Build / Test Suite (pull_request) Successful in 1m17s
Rust Build / Rustfmt (pull_request) Successful in 36s
Rust Build / Clippy (pull_request) Successful in 53s
Rust Build / build (pull_request) Successful in 1m31s
Release Tagging / release (push) Failing after 38s
Reviewed-on: #30
Co-authored-by: phoenix <kundeng00@pm.me>
Co-committed-by: phoenix <kundeng00@pm.me>
2025-04-11 23:57:37 +00:00
17af1a00c0 Add docker (#28)
All checks were successful
Release Tagging / release (push) Successful in 36s
Rust Build / Check (push) Successful in 48s
Rust Build / Test Suite (push) Successful in 1m9s
Rust Build / Rustfmt (push) Successful in 29s
Rust Build / Clippy (push) Successful in 56s
Rust Build / build (push) Successful in 1m22s
Rust Build / Check (pull_request) Successful in 47s
Rust Build / Test Suite (pull_request) Successful in 1m2s
Rust Build / Rustfmt (pull_request) Successful in 35s
Rust Build / Clippy (pull_request) Successful in 52s
Rust Build / build (pull_request) Successful in 1m24s
Reviewed-on: #28
Co-authored-by: phoenix <kundeng00@pm.me>
Co-committed-by: phoenix <kundeng00@pm.me>
2025-04-11 01:07:20 +00:00
50e735e1a9 Update last_login of user (#26)
All checks were successful
Release Tagging / release (push) Successful in 55s
Rust Build / Check (pull_request) Successful in 58s
Rust Build / Test Suite (pull_request) Successful in 1m3s
Rust Build / Rustfmt (pull_request) Successful in 33s
Rust Build / Clippy (pull_request) Successful in 50s
Rust Build / build (pull_request) Successful in 1m18s
Rust Build / Check (push) Successful in 44s
Rust Build / Test Suite (push) Successful in 57s
Rust Build / Rustfmt (push) Successful in 31s
Rust Build / Clippy (push) Successful in 46s
Rust Build / build (push) Successful in 1m11s
Reviewed-on: #26
Co-authored-by: phoenix <kundeng00@pm.me>
Co-committed-by: phoenix <kundeng00@pm.me>
2025-04-11 01:01:18 +00:00
f6cf968f86 main merge (#25)
All checks were successful
Release Tagging / release (push) Successful in 35s
Rust Build / Check (push) Successful in 49s
Rust Build / Test Suite (push) Successful in 1m8s
Rust Build / Rustfmt (push) Successful in 29s
Rust Build / Clippy (push) Successful in 1m0s
Rust Build / build (push) Successful in 1m24s
Rust Build / Check (pull_request) Successful in 48s
Rust Build / Test Suite (pull_request) Successful in 1m5s
Rust Build / Rustfmt (pull_request) Successful in 29s
Rust Build / Clippy (pull_request) Successful in 50s
Rust Build / build (pull_request) Successful in 1m19s
Reviewed-on: #25
2025-04-10 22:46:29 +00:00
12 changed files with 210 additions and 10 deletions

21
.dockerignore.yaml Normal file
View File

@@ -0,0 +1,21 @@
# Ignore build artifacts
target/
pkg/
# Ignore git directory
.git/
.gitea/
# Ignore environment files (configure via docker-compose instead)
.env*
# Ignore IDE/editor specific files
.idea/
.vscode/
# Ignore OS specific files
*.DS_Store
# Add any other files/directories you don't need in the image
# e.g., logs/, tmp/

View File

@@ -1,2 +1,6 @@
DATABASE_URL=postgres://username:password@localhost/database_name
SECRET_KEY=refero34o8rfhfjn983thf39fhc943rf923n3h
POSTGRES_USER=icarus_op_test
POSTGRES_PASSWORD=password
POSTGRES_DB=icarus_auth_test_db
POSTGRES_HOST=localhost
DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:5432/${POSTGRES_DB}

View File

@@ -4,8 +4,6 @@ on:
push:
branches:
- devel
tags:
- 'v*' # Trigger on tags matching v*
jobs:
release:
@@ -53,5 +51,3 @@ jobs:
Release of version ${{ steps.version.outputs.project_tag_release }}
# draft: false
# prerelease: ${{ startsWith(github.ref, 'v') == false }} # prerelease if not a valid release tag

1
.gitignore vendored
View File

@@ -1,3 +1,4 @@
/target
Cargo.lock
.env
.env.docker

View File

@@ -1,6 +1,6 @@
[package]
name = "icarus_auth"
version = "0.3.2"
version = "0.3.4"
edition = "2024"
rust-version = "1.86"

71
Dockerfile Normal file
View File

@@ -0,0 +1,71 @@
# Stage 1: Build the application
# Use a specific Rust version for reproducibility. Choose one that matches your development environment.
# Using slim variant for smaller base image
FROM rust:1.86 as builder
# Set the working directory inside the container
WORKDIR /usr/src/app
# Install build dependencies if needed (e.g., for certain crates like sqlx with native TLS)
# RUN apt-get update && apt-get install -y pkg-config libssl-dev
# Install build dependencies if needed (e.g., git for cloning)
RUN apt-get update && apt-get install -y --no-install-recommends \
pkg-config libssl3 \
ca-certificates \
openssh-client git \
&& rm -rf /var/lib/apt/lists/*
# << --- ADD HOST KEY HERE --- >>
# Replace 'yourgithost.com' with the actual hostname (e.g., github.com)
RUN mkdir -p -m 0700 ~/.ssh && \
ssh-keyscan git.kundeng.us >> ~/.ssh/known_hosts
# Copy Cargo manifests
COPY Cargo.toml Cargo.lock ./
# Build *only* dependencies to leverage Docker cache
# This dummy build caches dependencies as a separate layer
RUN --mount=type=ssh mkdir src && \
echo "fn main() {println!(\"if you see this, the build broke\")}" > src/main.rs && \
cargo build --release --quiet && \
rm -rf src target/release/deps/icarus_auth* # Clean up dummy build artifacts (replace icarus_auth)
# Copy the actual source code
COPY src ./src
# If you have other directories like `templates` or `static`, copy them too
COPY .env ./.env
COPY migrations ./migrations
# << --- SSH MOUNT ADDED HERE --- >>
# Build *only* dependencies to leverage Docker cache
# This dummy build caches dependencies as a separate layer
# Mount the SSH agent socket for this command
RUN --mount=type=ssh \
cargo build --release --quiet
# Stage 2: Create the final, smaller runtime image
# Use a minimal base image like debian-slim or even distroless for security/size
FROM ubuntu:24.04
# Install runtime dependencies if needed (e.g., SSL certificates)
RUN apt-get update && apt-get install -y ca-certificates libssl-dev libssl3 && rm -rf /var/lib/apt/lists/*
# Set the working directory
WORKDIR /usr/local/bin
# Copy the compiled binary from the builder stage
# Replace 'icarus_auth' with the actual name of your binary (usually the crate name)
COPY --from=builder /usr/src/app/target/release/icarus_auth .
# Copy other necessary files like .env (if used for runtime config) or static assets
# It's generally better to configure via environment variables in Docker though
COPY --from=builder /usr/src/app/.env .
COPY --from=builder /usr/src/app/migrations ./migrations
# Expose the port your Axum app listens on (e.g., 3000 or 8000)
EXPOSE 3000
# Set the command to run your application
# Ensure this matches the binary name copied above
CMD ["./icarus_auth"]

26
README.md Normal file
View File

@@ -0,0 +1,26 @@
# Getting Started
Copy the `.env.sample` file to `.env` and ensure that the variables are populated. This project
can be used with regular hosting or with docker. For the sake of getting up to speed quickly,
Docker will be covered. Make sure docker is running and your ssh identity has been loaded.
Build image
```
docker compose build
```
Start images
```
docker compose up -d --force-recreate
```
Bring it down
```
docker compose down -v
```
Pruning
```
docker system prune -a
```

45
docker-compose.yaml Normal file
View File

@@ -0,0 +1,45 @@
version: '3.8' # Use a recent version
services:
# Your Rust Application Service
auth_api:
build: # Tells docker-compose to build the Dockerfile in the current directory
context: .
ssh: ["default"] # Uses host's SSH agent
container_name: icarus_auth # Optional: Give the container a specific name
ports:
# Map host port 8000 to container port 3000 (adjust as needed)
- "8000:3000"
env_file:
- .env
depends_on:
auth_db:
condition: service_healthy # Wait for the DB to be healthy before starting the app
restart: unless-stopped # Optional: Restart policy
# PostgreSQL Database Service
auth_db:
image: postgres:17.4-alpine # Use an official Postgres image (Alpine variant is smaller)
container_name: icarus_auth_db # Optional: Give the container a specific name
environment:
# These MUST match the user, password, and database name in the DATABASE_URL above
POSTGRES_USER: ${POSTGRES_USER:-icarus_op}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-password}
POSTGRES_DB: ${POSTGRES_DB:-icarus_auth}
volumes:
# Persist database data using a named volume
- postgres_data:/var/lib/postgresql/data
ports: []
healthcheck:
# Checks if Postgres is ready to accept connections
test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"]
interval: 10s
timeout: 5s
retries: 5
start_period: 10s
restart: always # Optional: Restart policy
# Define the named volume for data persistence
volumes:
postgres_data:
driver: local # Use the default local driver

View File

@@ -51,13 +51,16 @@ pub mod endpoint {
let (token_literal, duration) = token_stuff::create_token(&key).unwrap();
if token_stuff::verify_token(&key, &token_literal) {
let current_time = time::OffsetDateTime::now_utc();
let _ = repo::user::update_last_login(&pool, &user, &current_time).await;
(
StatusCode::OK,
Json(response::Response {
message: String::from("Successful"),
data: vec![icarus_models::login_result::LoginResult {
id: user.id,
username: user.username,
username: user.username.clone(),
token: token_literal,
token_type: String::from(token_stuff::TOKENTYPE),
expiration: duration,

View File

@@ -36,7 +36,6 @@ pub mod db {
async fn get_db_url() -> String {
#[cfg(debug_assertions)] // Example: Only load .env in debug builds
dotenvy::dotenv().ok();
env::var(keys::DBURL).expect(keys::error::ERROR)
}

View File

@@ -74,6 +74,7 @@ mod tests {
pub const LIMIT: usize = 6;
pub async fn get_pool() -> Result<sqlx::PgPool, sqlx::Error> {
dotenvy::dotenv().ok(); // Load .env file if it exists
let tm_db_url = std::env::var(keys::DBURL).expect("DATABASE_URL must be present");
let tm_options = sqlx::postgres::PgConnectOptions::from_str(&tm_db_url).unwrap();
sqlx::PgPool::connect_with(tm_options).await

View File

@@ -42,6 +42,39 @@ pub mod user {
}
}
pub async fn update_last_login(
pool: &sqlx::PgPool,
user: &icarus_models::user::User,
time: &time::OffsetDateTime,
) -> Result<time::OffsetDateTime, sqlx::Error> {
let result = sqlx::query(
r#"
UPDATE "user" SET last_login = $1 WHERE id = $2 RETURNING last_login
"#,
)
.bind(time)
.bind(user.id)
.fetch_optional(pool)
.await
.map_err(|e| {
eprintln!("Error updating time: {}", e);
e
});
match result {
Ok(row) => match row {
Some(r) => {
let last_login: time::OffsetDateTime = r
.try_get("last_login")
.map_err(|_e| sqlx::Error::RowNotFound)?;
Ok(last_login)
}
None => Err(sqlx::Error::RowNotFound),
},
Err(err) => Err(err),
}
}
pub async fn exists(pool: &sqlx::PgPool, username: &String) -> Result<bool, sqlx::Error> {
let result = sqlx::query(
r#"