Compare commits

..

5 Commits

Author SHA1 Message Date
711581f8a7 tsk-70: Version bump
All checks were successful
Rust Build / Check (pull_request) Successful in 45s
Rust Build / Test Suite (pull_request) Successful in 1m11s
Rust Build / Rustfmt (pull_request) Successful in 32s
Rust Build / Clippy (pull_request) Successful in 40s
Rust Build / build (pull_request) Successful in 58s
2025-10-20 13:04:08 -04:00
ff93dd8016 tsk-70: Code formatting 2025-10-20 13:03:44 -04:00
d67673584e tsk-70: Removing src/lib.rs 2025-10-20 13:03:26 -04:00
3c710c3367 tsk-70: Saving changes 2025-10-20 13:03:05 -04:00
bc5c3e5e8d tsk-70: Moved contents of src/lib.rs elsewhere 2025-10-20 13:02:48 -04:00
13 changed files with 593 additions and 609 deletions

View File

@@ -17,7 +17,7 @@ jobs:
- name: Install Rust
uses: actions-rs/toolchain@v1
with:
toolchain: 1.94
toolchain: 1.90.0
components: cargo
- name: Extract Version from Cargo.toml

View File

@@ -18,7 +18,7 @@ jobs:
- uses: actions/checkout@v5
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: 1.94
toolchain: 1.90.0
- run: |
mkdir -p ~/.ssh
echo "${{ secrets.MYREPO_TOKEN }}" > ~/.ssh/icarus_models_deploy_key
@@ -36,7 +36,7 @@ jobs:
# --- Add database service definition ---
services:
postgres:
image: postgres:18.3-alpine
image: postgres:17.5
env:
# Use secrets for DB init, with fallbacks for flexibility
POSTGRES_USER: ${{ secrets.DB_TEST_USER || 'testuser' }}
@@ -53,7 +53,7 @@ jobs:
- uses: actions/checkout@v5
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: 1.94
toolchain: 1.90.0
# --- Add this step for explicit verification ---
- name: Verify Docker Environment
run: |
@@ -95,7 +95,7 @@ jobs:
- uses: actions/checkout@v5
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: 1.94
toolchain: 1.90.0
- run: rustup component add rustfmt
- run: |
mkdir -p ~/.ssh
@@ -114,7 +114,7 @@ jobs:
- uses: actions/checkout@v5
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: 1.94
toolchain: 1.90.0
- run: rustup component add clippy
- run: |
mkdir -p ~/.ssh
@@ -133,7 +133,7 @@ jobs:
- uses: actions/checkout@v5
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: 1.94
toolchain: 1.90.0
- run: |
mkdir -p ~/.ssh
echo "${{ secrets.MYREPO_TOKEN }}" > ~/.ssh/icarus_models_deploy_key

988
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,30 +1,30 @@
[package]
name = "icarus_auth"
version = "0.7.0"
version = "0.6.4"
edition = "2024"
rust-version = "1.94"
rust-version = "1.90"
[dependencies]
axum = { version = "0.8.8" }
axum = { version = "0.8.6" }
serde = { version = "1.0.228", features = ["derive"] }
serde_json = { version = "1.0.149" }
tokio = { version = "1.51", features = ["rt-multi-thread"] }
tracing-subscriber = { version = "0.3.23" }
tower = { version = "0.5.3", features = ["full"] }
tower-http = { version = "0.6.8", features = ["cors"] }
hyper = { version = "1.9.0" }
serde_json = { version = "1.0.145" }
tokio = { version = "1.47.1", features = ["rt-multi-thread"] }
tracing-subscriber = { version = "0.3.20" }
tower = { version = "0.5.2", features = ["full"] }
tower-http = { version = "0.6.6", features = ["cors"] }
hyper = { version = "1.7.0" }
sqlx = { version = "0.8.6", features = ["postgres", "runtime-tokio-native-tls", "time", "uuid"] }
uuid = { version = "1.23", features = ["v4", "serde"] }
uuid = { version = "1.18.1", features = ["v4", "serde"] }
argon2 = { version = "0.5.3", features = ["std"] } # Use the latest 0.5.x version
rand = { version = "0.10.0" }
time = { version = "0.3.47", features = ["macros", "serde"] }
rand = { version = "0.9.2" }
time = { version = "0.3.41", features = ["macros", "serde"] }
josekit = { version = "0.10.3" }
utoipa = { version = "5.4.0", features = ["axum_extras"] }
utoipa-swagger-ui = { version = "9.0.2", features = ["axum"] }
icarus_models = { git = "ssh://git@git.kundeng.us/phoenix/icarus_models.git", tag = "v0.10.0" }
icarus_envy = { git = "ssh://git@git.kundeng.us/phoenix/icarus_envy.git", tag = "v0.6.0" }
icarus_models = { git = "ssh://git@git.kundeng.us/phoenix/icarus_models.git", tag = "v0.8.0" }
icarus_envy = { git = "ssh://git@git.kundeng.us/phoenix/icarus_envy.git", tag = "v0.5.0" }
[dev-dependencies]
http-body-util = { version = "0.1.3" }
url = { version = "2.5.8" }
once_cell = { version = "1.21.4" } # Useful for lazy initialization in tests/app setup
url = { version = "2.5.7" }
once_cell = { version = "1.21.3" } # Useful for lazy initialization in tests/app setup

View File

@@ -1,7 +1,7 @@
# 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.94 as builder
FROM rust:1.90 as builder
# Set the working directory inside the container
WORKDIR /usr/src/app
@@ -64,7 +64,7 @@ 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 8001
EXPOSE 3000
# Set the command to run your application
# Ensure this matches the binary name copied above

View File

@@ -2,13 +2,6 @@ A auth web API services for the Icarus project.
# Getting Started
Install the `sqlx` tool to use migrations.
```
cargo install sqlx-cli
```
This will be used to scaffold development for local environments.
The easiest way to get started is through docker. This assumes that docker is already installed
on your system. Copy the `.env.docker.sample` as `.env`. Most of the data in the env file doesn't
need to be modified. The `SECRET_KEY` variable should be changed since it will be used for token
@@ -40,4 +33,4 @@ docker system prune -a
```
To view the OpenAPI spec, run the project and access `/swagger-ui`. If running through docker,
the url would be something like `http://localhost:8001/swagger-ui`.
the url would be something like `http://localhost:8000/swagger-ui`.

View File

@@ -19,7 +19,7 @@ services:
# PostgreSQL Database Service
auth_db:
image: postgres:18.3-alpine # Use an official Postgres image (Alpine variant is smaller)
image: postgres:17.5-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

View File

@@ -23,7 +23,6 @@ CREATE TABLE IF NOT EXISTS "salt" (
CREATE TABLE IF NOT EXISTS "passphrase" (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
username TEXT NOT NULL,
passphrase TEXT NOT NULL,
date_created TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

View File

@@ -1,2 +1,2 @@
-- Add migration script here
INSERT INTO "passphrase" (id, username, passphrase) VALUES('22f9c775-cce9-457a-a147-9dafbb801f61', 'service', 'iUOo1fxshf3y1tUGn1yU8l9raPApHCdinW0VdCHdRFEjqhR3Bf02aZzsKbLtaDFH');
INSERT INTO "passphrase" (id, passphrase) VALUES('22f9c775-cce9-457a-a147-9dafbb801f61', 'iUOo1fxshf3y1tUGn1yU8l9raPApHCdinW0VdCHdRFEjqhR3Bf02aZzsKbLtaDFH');

27
run_migrations.txt Normal file
View File

@@ -0,0 +1,27 @@
TODO: At some point, move this somewhere that is appropriate
# Make sure role has CREATEDB
ALTER ROLE username_that_needs_permission CREATEDB;
# Install migrations
cargo install sqlx-cli
# Make sure to populate DATABASE_URL with correct value.
# By default, the DATABASE_URL found in .env file will be used
export DATABASE_URL="postgres://icarus_op_test:password@localhost/icarus_auth_test"
# init
sqlx migrate add init_migration
sqlx migrate run
# Create
sqlx database create
# Drop
sqlx database drop
# setup
sqlx database setup
# Reset
sqlx database reset

View File

@@ -59,6 +59,10 @@ pub mod endpoint {
use super::request;
use super::response;
// TODO: At some point, get the username from the DB
// Name of service username when returning a login result
pub const SERVICE_USERNAME: &str = "service";
async fn not_found(message: &str) -> (StatusCode, Json<response::Response>) {
(
StatusCode::NOT_FOUND,
@@ -114,7 +118,7 @@ pub mod endpoint {
}),
)
} else {
return not_found("Could not verify token").await;
return not_found("Could not verify password").await;
}
} else {
return not_found("Error Hashing").await;
@@ -150,7 +154,7 @@ pub mod endpoint {
let mut response = response::service_login::Response::default();
match repo::service::valid_passphrase(&pool, &payload.passphrase).await {
Ok((id, username, _date_created)) => {
Ok((id, _passphrase, _date_created)) => {
let key = icarus_envy::environment::get_secret_key().await.value;
let (token_literal, duration) =
token_stuff::create_service_token(&key, &id).unwrap();
@@ -158,7 +162,7 @@ pub mod endpoint {
if token_stuff::verify_token(&key, &token_literal) {
let login_result = icarus_models::login_result::LoginResult {
id,
username,
username: String::from(SERVICE_USERNAME),
token: token_literal,
token_type: String::from(icarus_models::token::TOKEN_TYPE),
expiration: duration,
@@ -212,15 +216,15 @@ pub mod endpoint {
// Get passphrase record with id
match token_stuff::extract_id_from_token(&key, &payload.access_token) {
Ok(id) => match repo::service::get_passphrase(&pool, &id).await {
Ok((username, _, _)) => {
match token_stuff::create_service_refresh_token(&key, &id) {
Ok((returned_id, _, _)) => {
match token_stuff::create_service_refresh_token(&key, &returned_id) {
Ok((access_token, exp_dur)) => {
let login_result = icarus_models::login_result::LoginResult {
id,
id: returned_id,
token: access_token,
expiration: exp_dur,
token_type: String::from(icarus_models::token::TOKEN_TYPE),
username,
username: String::from(SERVICE_USERNAME),
};
response.message = String::from("Successful");
response.data.push(login_result);

View File

@@ -1,5 +1,3 @@
pub mod service;
pub mod user {
use sqlx::Row;
@@ -197,3 +195,56 @@ pub mod salt {
}
}
}
pub mod service {
use sqlx::Row;
pub async fn valid_passphrase(
pool: &sqlx::PgPool,
passphrase: &String,
) -> Result<(uuid::Uuid, String, time::OffsetDateTime), sqlx::Error> {
let result = sqlx::query(
r#"
SELECT * FROM "passphrase" WHERE passphrase = $1
"#,
)
.bind(passphrase)
.fetch_one(pool)
.await;
match result {
Ok(row) => {
let id: uuid::Uuid = row.try_get("id")?;
let passphrase: String = row.try_get("passphrase")?;
let date_created: Option<time::OffsetDateTime> = row.try_get("date_created")?;
Ok((id, passphrase, date_created.unwrap()))
}
Err(err) => Err(err),
}
}
pub async fn get_passphrase(
pool: &sqlx::PgPool,
id: &uuid::Uuid,
) -> Result<(uuid::Uuid, String, time::OffsetDateTime), sqlx::Error> {
let result = sqlx::query(
r#"
SELECT * FROM "passphrase" WHERE id = $1;
"#,
)
.bind(id)
.fetch_one(pool)
.await;
match result {
Ok(row) => {
let returned_id: uuid::Uuid = row.try_get("id")?;
let passphrase: String = row.try_get("passphrase")?;
let date_created: time::OffsetDateTime = row.try_get("date_created")?;
Ok((returned_id, passphrase, date_created))
}
Err(err) => Err(err),
}
}
}

View File

@@ -1,50 +0,0 @@
use sqlx::Row;
pub async fn valid_passphrase(
pool: &sqlx::PgPool,
passphrase: &String,
) -> Result<(uuid::Uuid, String, time::OffsetDateTime), sqlx::Error> {
let result = sqlx::query(
r#"
SELECT id, username, date_created FROM "passphrase" WHERE passphrase = $1
"#,
)
.bind(passphrase)
.fetch_one(pool)
.await;
match result {
Ok(row) => {
let id: uuid::Uuid = row.try_get("id")?;
let username: String = row.try_get("username")?;
let date_created: Option<time::OffsetDateTime> = row.try_get("date_created")?;
Ok((id, username, date_created.unwrap()))
}
Err(err) => Err(err),
}
}
pub async fn get_passphrase(
pool: &sqlx::PgPool,
id: &uuid::Uuid,
) -> Result<(String, String, time::OffsetDateTime), sqlx::Error> {
let result = sqlx::query(
r#"
SELECT username, passphrase, date_created FROM "passphrase" WHERE id = $1;
"#,
)
.bind(id)
.fetch_one(pool)
.await;
match result {
Ok(row) => {
let username: String = row.try_get("username")?;
let passphrase: String = row.try_get("passphrase")?;
let date_created: time::OffsetDateTime = row.try_get("date_created")?;
Ok((username, passphrase, date_created))
}
Err(err) => Err(err),
}
}