From ad45a34cf3c1c626b49786a237148cad8ea0d402 Mon Sep 17 00:00:00 2001 From: Mika Date: Wed, 9 Apr 2025 20:32:13 +0200 Subject: [PATCH 1/4] feat: add AlreadyLoggedIn error and prevent duplicate logins --- crates/backend/src/controller/auth.rs | 4 ++++ crates/backend/src/error.rs | 5 ++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/crates/backend/src/controller/auth.rs b/crates/backend/src/controller/auth.rs index a24ce35..ebd00ea 100644 --- a/crates/backend/src/controller/auth.rs +++ b/crates/backend/src/controller/auth.rs @@ -30,6 +30,10 @@ async fn login( .verify_local_user(&login_request.username, &login_request.password) .await?; + if session.get::("user").is_ok() { + return Err(ApiError::AlreadyLoggedIn); + } + session.insert("user", user_id)?; Ok(HttpResponse::Ok()) diff --git a/crates/backend/src/error.rs b/crates/backend/src/error.rs index dd52cb2..e24b0a5 100644 --- a/crates/backend/src/error.rs +++ b/crates/backend/src/error.rs @@ -1,4 +1,4 @@ -use actix_web::{cookie::time::error, http::StatusCode, HttpResponse, ResponseError}; +use actix_web::{HttpResponse, ResponseError, cookie::time::error, http::StatusCode}; use sea_orm::TransactionError; use thiserror::Error; @@ -18,6 +18,8 @@ pub enum ApiError { Argon2Error(String), #[error("Session insert error: {0}")] SessionInsertError(#[from] actix_session::SessionInsertError), + #[error("Already logged in")] + AlreadyLoggedIn, } impl ResponseError for ApiError { @@ -30,6 +32,7 @@ impl ResponseError for ApiError { ApiError::ValidationError(..) => StatusCode::BAD_REQUEST, ApiError::Argon2Error(..) => StatusCode::INTERNAL_SERVER_ERROR, ApiError::SessionInsertError(..) => StatusCode::INTERNAL_SERVER_ERROR, + ApiError::AlreadyLoggedIn => StatusCode::BAD_REQUEST, } } From 0ca4c56b0d9b78d0e0b2256f82f9ad390ac8944c Mon Sep 17 00:00:00 2001 From: Mika Date: Wed, 9 Apr 2025 21:35:52 +0200 Subject: [PATCH 2/4] feat: update workspace members, add backend service to docker-compose, and create Dockerfile for static linking --- .woodpecker/deployment.yaml | 0 Cargo.lock | 30 --------------------- Cargo.toml | 2 +- backend.Dockerfile | 52 +++++++++++++++++++++++++++++++++++++ crates/backend/Cargo.toml | 5 +++- dev-compose.yml | 20 ++++++++++++++ 6 files changed, 77 insertions(+), 32 deletions(-) create mode 100644 .woodpecker/deployment.yaml create mode 100644 backend.Dockerfile diff --git a/.woodpecker/deployment.yaml b/.woodpecker/deployment.yaml new file mode 100644 index 0000000..e69de29 diff --git a/Cargo.lock b/Cargo.lock index 682fa20..c504bc1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1045,16 +1045,6 @@ dependencies = [ "cipher", ] -[[package]] -name = "ctrlc" -version = "3.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90eeab0aa92f3f9b4e87f258c72b139c207d251f9cbc1080a0086b86a8870dd3" -dependencies = [ - "nix", - "windows-sys 0.59.0", -] - [[package]] name = "darling" version = "0.20.10" @@ -2088,18 +2078,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e94e1e6445d314f972ff7395df2de295fe51b71821694f0b0e1e79c4f12c8577" -[[package]] -name = "nix" -version = "0.29.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" -dependencies = [ - "bitflags", - "cfg-if", - "cfg_aliases", - "libc", -] - [[package]] name = "num-bigint" version = "0.4.6" @@ -4178,14 +4156,6 @@ dependencies = [ "tap", ] -[[package]] -name = "xtask" -version = "0.1.0" -dependencies = [ - "clap", - "ctrlc", -] - [[package]] name = "yansi" version = "1.0.1" diff --git a/Cargo.toml b/Cargo.toml index 45dc1a4..279ac56 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace] -members = ["crates/backend", "crates/migration", "crates/xtask"] +members = ["crates/backend", "crates/migration"] resolver = "3" [workspace.package] diff --git a/backend.Dockerfile b/backend.Dockerfile new file mode 100644 index 0000000..41c741a --- /dev/null +++ b/backend.Dockerfile @@ -0,0 +1,52 @@ +# ---- Stage 1: Build (Static Linking) ---- +FROM rust:latest as builder + +WORKDIR /usr/src/app + +# Install the musl target and musl-tools +RUN rustup target add x86_64-unknown-linux-musl +RUN apt-get update && apt-get install -y musl-tools + +# Create a .cargo directory and configure for static linking with musl +RUN mkdir -p .cargo +RUN echo '[target.x86_64-unknown-linux-musl]' > .cargo/config.toml +RUN echo 'linker = "rust-lld"' >> .cargo/config.toml + +# Copy configuration and lock files needed to resolve dependencies +COPY Cargo.toml ./Cargo.toml +COPY Cargo.lock ./Cargo.lock +COPY crates/backend/Cargo.toml crates/backend/Cargo.toml +COPY crates/migration/Cargo.toml crates/migration/Cargo.toml + +# Fetch dependencies based on the lock file. +RUN cargo fetch + +# Copy the actual source code for all workspace members +COPY crates/backend/ crates/backend/ +COPY crates/migration/ crates/migration/ + +# Build the release binary for the musl target +RUN cargo build --release --target x86_64-unknown-linux-musl + +# Debug: List the built binaries to verify what we have +RUN ls -la /usr/src/app/target/x86_64-unknown-linux-musl/release/ + +# ---- Stage 2: Runtime ---- +FROM alpine:latest + +# Install minimal runtime dependencies (ca-certificates is often needed) +RUN apk add --no-cache ca-certificates + +WORKDIR /app + +# Copy only the statically linked compiled binary from the builder stage +COPY --from=builder /usr/src/app/target/x86_64-unknown-linux-musl/release/backend /app/backend + +# Verify the binary exists and is executable +RUN ls -la /app && chmod +x /app/backend + +# Expose the port the application listens on +EXPOSE 8080 + +# Set the command to run the application +CMD ["/app/backend"] \ No newline at end of file diff --git a/crates/backend/Cargo.toml b/crates/backend/Cargo.toml index f6da6fd..b9b3a92 100644 --- a/crates/backend/Cargo.toml +++ b/crates/backend/Cargo.toml @@ -32,6 +32,9 @@ dotenvy = "0.15" [dev-dependencies] temp-env = "*" - [features] serve = [] + +[[bin]] +name = "backend" +path = "src/main.rs" diff --git a/dev-compose.yml b/dev-compose.yml index 5384b24..017b13c 100644 --- a/dev-compose.yml +++ b/dev-compose.yml @@ -52,6 +52,26 @@ services: interval: 30s retries: 3 + backend: + build: + context: . + dockerfile: ./backend.Dockerfile + image: peer-group-grading:latest + restart: unless-stopped + environment: + DB_NAME: ${DB_NAME} + DB_USER: ${DB_USER} + DB_PASSWORD: ${DB_PASSWORD} + DB_HOST: db + DB_PORT: 5432 + REDIS_HOST: redis + REDIS_PORT: 6379 + ports: + - "8080:8080" + depends_on: + - db + - redis + volumes: postgres_data: redis: From 5c1d9a2935f6e28f5e17d2f7a981c890fe5b15f6 Mon Sep 17 00:00:00 2001 From: Mika Date: Wed, 9 Apr 2025 21:43:53 +0200 Subject: [PATCH 3/4] feat: add deployment steps for Docker build, login, and publish to Forgejo --- .woodpecker/deployment.yaml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/.woodpecker/deployment.yaml b/.woodpecker/deployment.yaml index e69de29..0d8958a 100644 --- a/.woodpecker/deployment.yaml +++ b/.woodpecker/deployment.yaml @@ -0,0 +1,20 @@ +steps: + - name: build-docker + image: docker:latest + commands: + - docker build -f backend.Dockerfile -t backend . + + - name: login-forgejo + image: docker:latest + commands: + - docker login -u $$FORGEJO_USERNAME -p $$FORGEJO_PASSWORD git.mixel.cloud + secrets: + - FORGEJO_USERNAME + - FORGEJO_PASSWORD + + - name: publish-forgejo + image: docker:latest + commands: + - export IMAGE_NAME=git.mixel.cloud/Turbo/peer-group-grading:$${CI_COMMIT_SHA:0:8} + - docker tag backend $$IMAGE_NAME + - docker push $$IMAGE_NAME \ No newline at end of file From 1f17ee13d087c466b0f3cd7a120263122074f8ea Mon Sep 17 00:00:00 2001 From: Mika Date: Wed, 9 Apr 2025 21:51:35 +0200 Subject: [PATCH 4/4] fix pipeline --- .woodpecker/deployment.yaml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/.woodpecker/deployment.yaml b/.woodpecker/deployment.yaml index 0d8958a..a93b6e8 100644 --- a/.woodpecker/deployment.yaml +++ b/.woodpecker/deployment.yaml @@ -7,10 +7,13 @@ steps: - name: login-forgejo image: docker:latest commands: - - docker login -u $$FORGEJO_USERNAME -p $$FORGEJO_PASSWORD git.mixel.cloud - secrets: - - FORGEJO_USERNAME - - FORGEJO_PASSWORD + - docker login -u $$FORGEJO_USERNAME -p $$FORGEJO_PASSWORD + environment: + FORGEJO_USERNAME: + from_secret: FORGEJO_USERNAME + FORGEJO_PASSWORD: + from_secret: FORGEJO_PASSWORD + - name: publish-forgejo image: docker:latest