diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..dc2cd5c --- /dev/null +++ b/.dockerignore @@ -0,0 +1,4 @@ +/target +/docker-data +/.vscode +.env \ No newline at end of file diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 0000000..dc8d8d6 --- /dev/null +++ b/.drone.yml @@ -0,0 +1,42 @@ +--- +kind: pipeline +type: docker +name: default + +services: + - name: docker + image: docker:dind + privileged: true + volumes: + - name: dockersock + path: /var/run + +steps: + - name: publish + image: plugins/docker + settings: + auto_tag: true + registry: + from_secret: docker_registry + repo: + from_secret: docker_repo + username: + from_secret: docker_username + password: + from_secret: docker_password + when: + event: + - push + - tag + volumes: + - name: dockersock + path: /var/run + +volumes: + - name: dockersock + temp: {} +--- +kind: signature +hmac: 1c614701422d8cf9b8d11a919f7e55cbefcc32ca38a22f809da38eff1dc2c119 + +... diff --git a/Cargo.lock b/Cargo.lock index 2140954..3470b3d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -354,6 +354,9 @@ name = "either" version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +dependencies = [ + "serde", +] [[package]] name = "event-listener" @@ -1307,9 +1310,11 @@ dependencies = [ "dotenvy", "either", "heck", + "hex", "once_cell", "proc-macro2", "quote", + "serde", "serde_json", "sha2", "sqlx-core", diff --git a/Cargo.toml b/Cargo.toml index d4c7053..327383b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ cookie = "0.17" tracing = "0.1" tracing-subscriber = "0.3" tokio = { version = "1.28", features = ["full"] } -sqlx = { version = "0.6", features = [ "runtime-tokio-rustls", "postgres", "uuid", "chrono", "macros", "migrate", "json" ] } +sqlx = { version = "0.6", features = [ "runtime-tokio-rustls", "postgres", "uuid", "chrono", "macros", "migrate", "json", "offline"] } uuid = { version = "1.3", features = ["v4", "fast-rng", "serde"] } serde = { version = "1" } serde_json = { version = "1", features = ["raw_value"] } diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..f07d52e --- /dev/null +++ b/Dockerfile @@ -0,0 +1,34 @@ +FROM rust:slim AS builder + +RUN update-ca-certificates + +ENV USER=mabel +ENV UID=10001 + +RUN adduser \ + --disabled-password \ + --gecos "" \ + --home "/nonexistent" \ + --shell "/sbin/nologin" \ + --no-create-home \ + --uid "${UID}" \ + "${USER}" + +WORKDIR /mabel + +COPY ./ . + +RUN cargo build --release + +FROM gcr.io/distroless/cc + +COPY --from=builder /etc/passwd /etc/passwd +COPY --from=builder /etc/group /etc/group + +WORKDIR /mabel + +COPY --from=builder /mabel/target/release/mabel ./ + +USER mabel:mabel + +CMD ["/mabel/mabel"] \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml index cc93ca8..6cac6f3 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -8,4 +8,4 @@ services: ports: - 5432:5432 volumes: - - ./docker-data/database:/var/lib/postgresql \ No newline at end of file + - ./docker-data/database:/var/lib/postgresql/data \ No newline at end of file diff --git a/sqlx-data.json b/sqlx-data.json new file mode 100644 index 0000000..e83eb22 --- /dev/null +++ b/sqlx-data.json @@ -0,0 +1,215 @@ +{ + "db": "PostgreSQL", + "0e89d76bdba2178afc2fb2c2a5eba0404e68e7a1d26d9fd5f1161f055dad92df": { + "describe": { + "columns": [ + { + "name": "id", + "ordinal": 0, + "type_info": "Uuid" + } + ], + "nullable": [ + false + ], + "parameters": { + "Left": [ + "Uuid", + "Varchar", + "Timestamp", + "Timestamp" + ] + } + }, + "query": "INSERT INTO sessions (actor, secret, created_at, expires_at) VALUES ($1, $2, $3, $4) RETURNING id" + }, + "11e96cfd8c2736f13ce55975ea910dd68640f6f14e38a4b3342d514804e3de27": { + "describe": { + "columns": [], + "nullable": [], + "parameters": { + "Left": [ + "Uuid" + ] + } + }, + "query": "DELETE FROM sessions WHERE id = $1" + }, + "35deaad55b84124dcba02c555718fe815003e3f50b1c8ee2fc7e540009fa5aef": { + "describe": { + "columns": [ + { + "name": "empty", + "ordinal": 0, + "type_info": "Bool" + } + ], + "nullable": [ + null + ], + "parameters": { + "Left": [] + } + }, + "query": "SELECT CASE WHEN EXISTS(SELECT 1 FROM users) THEN false ELSE true END AS empty;" + }, + "742b9eef92ad404b3b1ec285ce8b99e945b1b910f25bff376466c704a79fc9c8": { + "describe": { + "columns": [], + "nullable": [], + "parameters": { + "Left": [ + "Timestamp" + ] + } + }, + "query": "DELETE FROM sessions WHERE expires_at < $1" + }, + "9f37c6f3929ca1bf2a6ec55291d652b216419fd13e27b3d61d23c9cf900c501e": { + "describe": { + "columns": [ + { + "name": "id", + "ordinal": 0, + "type_info": "Uuid" + } + ], + "nullable": [ + false + ], + "parameters": { + "Left": [ + "Timestamp", + "Uuid" + ] + } + }, + "query": "UPDATE sessions SET expires_at = $1 WHERE id = $2 RETURNING id" + }, + "c567d96c92638902bc90f5fc0aa5bbbe0b6d26607767720a87fdbe67335a0180": { + "describe": { + "columns": [ + { + "name": "session_id", + "ordinal": 0, + "type_info": "Uuid" + }, + { + "name": "session_actor", + "ordinal": 1, + "type_info": "Uuid" + }, + { + "name": "secret", + "ordinal": 2, + "type_info": "Varchar" + }, + { + "name": "session_created_at", + "ordinal": 3, + "type_info": "Timestamp" + }, + { + "name": "expires_at", + "ordinal": 4, + "type_info": "Timestamp" + }, + { + "name": "user_id", + "ordinal": 5, + "type_info": "Uuid" + }, + { + "name": "name", + "ordinal": 6, + "type_info": "Varchar" + }, + { + "name": "email", + "ordinal": 7, + "type_info": "Varchar" + }, + { + "name": "display_name", + "ordinal": 8, + "type_info": "Varchar" + }, + { + "name": "bio", + "ordinal": 9, + "type_info": "Text" + }, + { + "name": "roles", + "ordinal": 10, + "type_info": "UuidArray" + }, + { + "name": "user_created_at", + "ordinal": 11, + "type_info": "Timestamp" + }, + { + "name": "modified_at", + "ordinal": 12, + "type_info": "Timestamp" + }, + { + "name": "deleted_at", + "ordinal": 13, + "type_info": "Timestamp" + } + ], + "nullable": [ + false, + false, + false, + false, + false, + false, + false, + true, + true, + true, + false, + false, + true, + true + ], + "parameters": { + "Left": [ + "Uuid" + ] + } + }, + "query": "SELECT\n sessions.id AS session_id,\n sessions.actor AS session_actor,\n sessions.secret,\n sessions.created_at AS session_created_at,\n sessions.expires_at,\n users.id AS user_id,\n users.name,\n users.email,\n users.display_name,\n users.bio,\n users.roles,\n users.created_at AS user_created_at,\n users.modified_at,\n users.deleted_at\n FROM\n sessions\n JOIN\n users ON sessions.actor = users.id\n WHERE\n sessions.id = $1" + }, + "f054746ab3092a8671604c9388e02220d62d337e9d199fa9102c0363a72f6940": { + "describe": { + "columns": [ + { + "name": "id", + "ordinal": 0, + "type_info": "Uuid" + }, + { + "name": "created_at", + "ordinal": 1, + "type_info": "Timestamp" + } + ], + "nullable": [ + false, + false + ], + "parameters": { + "Left": [ + "Varchar", + "Varchar", + "UuidArray" + ] + } + }, + "query": "INSERT INTO users ( name, password, roles ) VALUES ( $1,$2,$3 ) RETURNING id, created_at" + } +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index fda920c..800f035 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,11 +7,7 @@ mod state; use crate::{auth::http::refresh_sessions, state::Config}; use anyhow::Result; -use axum::{ - middleware, - routing::{get, post}, - Router, Server, -}; +use axum::{middleware, Router, Server}; use figment::{ providers::{Env, Format, Serialized, Toml}, Figment, @@ -42,7 +38,7 @@ async fn main() -> Result<()> { let app = Router::new() .nest("/auth", routes::auth::router()) .nest("/admin", routes::admin::router()) - .nest("/pages", routes::content::router()) + .nest("/posts", routes::posts::router()) .route_layer(middleware::from_fn_with_state( shared_state.clone(), refresh_sessions, diff --git a/src/routes/mod.rs b/src/routes/mod.rs index e0cc12a..90fd44d 100644 --- a/src/routes/mod.rs +++ b/src/routes/mod.rs @@ -1,3 +1,3 @@ pub mod admin; pub mod auth; -pub mod content; +pub mod posts; diff --git a/src/routes/content.rs b/src/routes/posts.rs similarity index 100% rename from src/routes/content.rs rename to src/routes/posts.rs