Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Continued authz #81

Open
wants to merge 19 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ EXPOSE 4000

# Default command starts an interactive bash shell
# Set ENTRYPOINT to default to run the Rust binary with arguments
ENTRYPOINT ["/bin/bash", "-c", "/usr/local/bin/refactor_platform_rs -l DEBUG -i \"$SERVICE_INTERFACE\" -p \"$SERVICE_PORT\" -d \"$DATABASE_URL\""]
ENTRYPOINT ["/bin/bash", "-c", "/usr/local/bin/refactor_platform_rs -l \"$BACKEND_LOG_FILTER_LEVEL\" -i \"$BACKEND_INTERFACE\" -p \"$BACKEND_PORT\" -d \"$DATABASE_URL\" --allowed-origins=$BACKEND_ALLOWED_ORIGINS"]

# Default CMD allows overriding with custom commands
CMD ["bash"]
22 changes: 18 additions & 4 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,12 @@ services:
POSTGRES_HOST: postgres # Set PostgreSQL host to "postgres" service
POSTGRES_PORT: ${POSTGRES_PORT} # Set PostgreSQL port from environment variable
DATABASE_URL: postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:${POSTGRES_PORT}/${POSTGRES_DB} # Configure database URL
SERVICE_PORT: ${SERVICE_PORT} # Set service port from environment variable
SERVICE_INTERFACE: ${SERVICE_INTERFACE} # Set service interface from environment variable
BACKEND_PORT: ${BACKEND_PORT} # Set service port from environment variable
BACKEND_INTERFACE: ${BACKEND_INTERFACE} # Set service interface from environment variable
BACKEND_ALLOWED_ORIGINS: ${BACKEND_ALLOWED_ORIGINS}
BACKEND_LOG_FILTER_LEVEL: ${BACKEND_LOG_FILTER_LEVEL}
ports:
- "${SERVICE_PORT}:${SERVICE_PORT}" # Map host port to container's service port
- "${BACKEND_PORT}:${BACKEND_PORT}" # Map host port to container's service port
depends_on:
- postgres # Ensure postgres service starts before rust-app
networks:
Expand All @@ -49,8 +51,20 @@ services:
context: https://github.com/refactor-group/refactor-platform-fe.git#main # change to fs directory to run locally
dockerfile: Dockerfile
target: runner # Use runner target
args:
NEXT_PUBLIC_BACKEND_SERVICE_PROTOCOL: ${BACKEND_SERVICE_PROTOCOL}
NEXT_PUBLIC_BACKEND_SERVICE_PORT: ${BACKEND_PORT}
NEXT_PUBLIC_BACKEND_SERVICE_HOST: ${BACKEND_SERVICE_HOST}
NEXT_PUBLIC_BACKEND_API_VERSION: ${BACKEND_API_VERSION}
FRONTEND_SERVICE_PORT: ${FRONTEND_SERVICE_PORT}
FRONTEND_SERVICE_INTERFACE: ${FRONTEND_SERVICE_INTERFACE}
environment:
NEXT_PUBLIC_BACKEND_SERVICE_PROTOCOL: ${BACKEND_SERVICE_PROTOCOL}
NEXT_PUBLIC_BACKEND_SERVICE_PORT: ${BACKEND_PORT}
NEXT_PUBLIC_BACKEND_SERVICE_HOST: ${BACKEND_SERVICE_HOST}
NEXT_PUBLIC_BACKEND_API_VERSION: ${BACKEND_API_VERSION}
ports:
- "${NEXTJS_FRONTEND_PORT}:${NEXTJS_FRONTEND_PORT}" # Map host port to frontend container's service port
- "${FRONTEND_SERVICE_PORT}:${FRONTEND_SERVICE_PORT}" # Map host port to frontend container's service port
depends_on:
- rust-app # Ensure postgres service starts before rust-app

Expand Down
6 changes: 3 additions & 3 deletions docs/db/refactor_platform_rs.dbml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ Table refactor_platform.overarching_goals {
coaching_session_id uuid [note: 'The coaching session that an overarching goal is associated with']
title varchar [note: 'A short description of an overarching goal']
body varchar [note: 'Main text of the overarching goal supporting Markdown']
status status [not null]
status refactor_platform.status [not null]
status_changed_at timestamptz
completed_at timestamptz [note: 'The date and time an overarching goal was completed']
created_at timestamptz [not null, default: `now()`]
Expand Down Expand Up @@ -82,13 +82,13 @@ Table refactor_platform.actions {
body varchar [note: 'Main text of the action supporting Markdown']
user_id uuid [not null, note: 'User that created (owns) the action']
due_by timestamptz
status status [not null]
status refactor_platform.status [not null]
status_changed_at timestamptz [not null, default: `now()`]
created_at timestamptz [not null, default: `now()`]
updated_at timestamptz [not null, default: `now()`]
}

enum status {
enum refactor_platform.status {
not_started
in_progress
completed
Expand Down
125 changes: 99 additions & 26 deletions docs/runbooks/Container-README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,7 @@ Decide whether you're connecting to a **local PostgreSQL container** (using Dock

- Create a `.env.local` file based on the template below and specify `POSTGRES_HOST=postgres`.

#### **For Remote PostgreSQL**

- Create a `.env.remote-db` file and set `POSTGRES_HOST` to the external IP or hostname of the remote PostgreSQL instance.

Example `.env.local`:
**Example** `.env.local`:

```env
POSTGRES_USER=refactor
Expand All @@ -44,40 +40,76 @@ POSTGRES_HOST=postgres
POSTGRES_PORT=5432
POSTGRES_SCHEMA=refactor_platform
DATABASE_URL=postgres://$POSTGRES_USER:$POSTGRES_PASSWORD@$POSTGRES_HOST:$POSTGRES_PORT/$POSTGRES_DB
SERVICE_PORT=4000
SERVICE_INTERFACE=0.0.0.0

BACKEND_LOG_FILTER_LEVEL="DEBUG"
BACKEND_PORT=4000
BACKEND_INTERFACE=0.0.0.0
BACKEND_ALLOWED_ORIGINS="http://localhost:3000,https://localhost:3000"

BACKEND_SERVICE_PROTOCOL="http"
BACKEND_SERVICE_PORT=${BACKEND_PORT}
BACKEND_SERVICE_HOST="localhost"
BACKEND_API_VERSION="0.0.1"
FRONTEND_SERVICE_INTERFACE=0.0.0.0
FRONTEND_SERVICE_PORT=3000

USERNAME=appuser
USER_UID=1000
USER_GID=1000
CONTAINER_NAME=refactor-platform
PLATFORM=linux/arm64
```

#### **For Remote PostgreSQL**

- Create a `.env.remote-db` file and set `POSTGRES_HOST` to the external IP or hostname of the remote PostgreSQL instance.

**Example** `.env.remote-db`:

```env
POSTGRES_USER=remote_refactor
POSTGRES_PASSWORD=remote_password
POSTGRES_DB=refactor
POSTGRES_HOST=postgres.example.com
POSTGRES_SCHEMA=refactor_platform
DATABASE_URL=postgres://$POSTGRES_USER:$POSTGRES_PASSWORD@$POSTGRES_HOST:$POSTGRES_PORT/$POSTGRES_DB
POSTGRES_PORT=5432
SERVICE_PORT=4000
SERVICE_INTERFACE=0.0.0.0
USERNAME=remote_appuser
USER_UID=1001
USER_GID=1001
PLATFORM=linux/arm64
# PostgreSQL environment variables for local development
POSTGRES_USER=refactor # Default PostgreSQL user for local development
POSTGRES_PASSWORD=password # Default PostgreSQL password for local development
POSTGRES_DB=refactor # Default PostgreSQL database for local development
POSTGRES_HOST=postgres # The local Docker Compose PostgreSQL container hostname
POSTGRES_PORT=5432 # PostgreSQL default port for local development
POSTGRES_SCHEMA=refactor_platform # PostgreSQL schema for the application
# Database connection URL for the Rust application
DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}

# Rust application environment variables
BACKEND_LOG_FILTER_LEVEL="DEBUG"
BACKEND_ALLOWED_ORIGINS="http://localhost:3000,https://localhost:3000"
BACKEND_PORT=4000
BACKEND_INTERFACE=0.0.0.0

# Next.js application build & environment variables
BACKEND_SERVICE_PROTOCOL="http"
BACKEND_SERVICE_PORT=${BACKEND_PORT}
BACKEND_SERVICE_HOST="localhost"
BACKEND_API_VERSION="0.0.1"
FRONTEND_SERVICE_INTERFACE=0.0.0.0
FRONTEND_SERVICE_PORT=3000

PLATFORM=linux/arm64 # For Raspberry Pi 5 or Apple Silicon
CONTAINER_NAME="refactor-platform"

# App user configuration
USERNAME=appuser # Username for the non-root user in the container
USER_UID=1000 # User ID for the appuser
USER_GID=1000 # Group ID for the appuser
```

### 3. **Review `docker-compose.yaml`**

The `docker-compose.yaml` file uses environment variables defined in your `.env` files.
The `docker-compose.yaml` file uses environment variables defined in your `.env` file setting important
configuration variables for both the Rust backend and the Next.js frontend applications.

```yaml
services:
postgres:
image: postgres:17
container_name: postgres
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
Expand All @@ -86,27 +118,68 @@ services:
- "${POSTGRES_PORT}:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
- ./migration/src/setup.sql:/docker-entrypoint-initdb.d/0-setup.sql
- ./migration/src/refactor_platform_rs.sql:/docker-entrypoint-initdb.d/1-refactor_plaform_rs.sql
- ./migration/src/setup_default_user.sql:/docker-entrypoint-initdb.d/2-setup_default_user.sql
networks:
- backend_network

rust-app:
image: rust-backend
build:
context: .
dockerfile: Dockerfile
target: runtime
platform: ${PLATFORM}
container_name: ${CONTAINER_NAME}
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_HOST: ${POSTGRES_HOST}
POSTGRES_SCHEMA: ${POSTGRES_SCHEMA}
POSTGRES_HOST: postgres
POSTGRES_PORT: ${POSTGRES_PORT}
DATABASE_URL: ${POSTGRES_HOST}://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}
SERVICE_PORT: ${SERVICE_PORT}
DATABASE_URL: postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:${POSTGRES_PORT}/${POSTGRES_DB}
BACKEND_PORT: ${BACKEND_PORT}
BACKEND_INTERFACE: ${BACKEND_INTERFACE}
BACKEND_ALLOWED_ORIGINS: ${BACKEND_ALLOWED_ORIGINS}
BACKEND_LOG_FILTER_LEVEL: ${BACKEND_LOG_FILTER_LEVEL}
ports:
- "${SERVICE_PORT}:4000"
- "${BACKEND_PORT}:${BACKEND_PORT}"
depends_on:
- postgres
networks:
- backend_network
command: ["sh", "-c", "sleep 5 && /usr/local/bin/refactor_platform_rs"]

nextjs-app:
build:
context: https://github.com/refactor-group/refactor-platform-fe.git#main
dockerfile: Dockerfile
target: runner
args:
NEXT_PUBLIC_BACKEND_SERVICE_PROTOCOL: ${BACKEND_SERVICE_PROTOCOL}
NEXT_PUBLIC_BACKEND_SERVICE_PORT: ${BACKEND_PORT}
NEXT_PUBLIC_BACKEND_SERVICE_HOST: ${BACKEND_SERVICE_HOST}
NEXT_PUBLIC_BACKEND_API_VERSION: ${BACKEND_API_VERSION}
FRONTEND_SERVICE_PORT: ${FRONTEND_SERVICE_PORT}
FRONTEND_SERVICE_INTERFACE: ${FRONTEND_SERVICE_INTERFACE}
environment:
NEXT_PUBLIC_BACKEND_SERVICE_PROTOCOL: ${BACKEND_SERVICE_PROTOCOL}
NEXT_PUBLIC_BACKEND_SERVICE_PORT: ${BACKEND_PORT}
NEXT_PUBLIC_BACKEND_SERVICE_HOST: ${BACKEND_SERVICE_HOST}
NEXT_PUBLIC_BACKEND_API_VERSION: ${BACKEND_API_VERSION}
ports:
- "${FRONTEND_SERVICE_PORT}:${FRONTEND_SERVICE_PORT}"
depends_on:
- rust-app

networks:
backend_network:
driver: bridge

volumes:
postgres_data:
postgres_data
```

---
Expand Down
3 changes: 2 additions & 1 deletion entity/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ serde = { version = "1.0.210", features = ["derive"] }
sqlx = { version = "0.8.2", features = ["time", "runtime-tokio"] }
sqlx-sqlite = { version = "0.8.2" }
utoipa = { version = "4.2.0", features = ["axum_extras", "uuid"] }
uuid = { version = "1.11.0", features = ["v4"] }

uuid = { version = "1.11.0", features = ["v4", "serde"] }

[dependencies.sea-orm]
version = "1.1.0"
Expand Down
26 changes: 26 additions & 0 deletions entity_api/src/coaching_relationship.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ pub async fn create(
Ok(coaching_relationship_active_model.insert(db).await?)
}

pub async fn find_by_id(db: &DatabaseConnection, id: Id) -> Result<Option<Model>, Error> {
Ok(Entity::find_by_id(id).one(db).await?)
}

pub async fn find_by_user(db: &DatabaseConnection, user_id: Id) -> Result<Vec<Model>, Error> {
let coaching_relationships: Vec<coaching_relationships::Model> =
coaching_relationships::Entity::find()
Expand Down Expand Up @@ -227,6 +231,28 @@ mod tests {
use super::*;
use sea_orm::{DatabaseBackend, MockDatabase, Transaction};

#[tokio::test]
async fn find_by_id_returns_record_when_present() -> Result<(), Error> {
let db = MockDatabase::new(DatabaseBackend::Postgres).into_connection();

let coaching_relationship_id = Id::new_v4();
let _ = find_by_id(&db, coaching_relationship_id).await;

assert_eq!(
db.into_transaction_log(),
[Transaction::from_sql_and_values(
DatabaseBackend::Postgres,
r#"SELECT "coaching_relationships"."id", "coaching_relationships"."organization_id", "coaching_relationships"."coach_id", "coaching_relationships"."coachee_id", "coaching_relationships"."created_at", "coaching_relationships"."updated_at" FROM "refactor_platform"."coaching_relationships" WHERE "coaching_relationships"."id" = $1 LIMIT $2"#,
[
coaching_relationship_id.into(),
sea_orm::Value::BigUnsigned(Some(1))
]
)]
);

Ok(())
}

#[tokio::test]
async fn find_by_user_returns_all_records_associated_with_user() -> Result<(), Error> {
let db = MockDatabase::new(DatabaseBackend::Postgres).into_connection();
Expand Down
Loading