diff options
Diffstat (limited to 'backend/seckelapi')
| -rw-r--r-- | backend/seckelapi/Containerfile | 39 | ||||
| -rw-r--r-- | backend/seckelapi/config/basics.toml | 18 | ||||
| -rw-r--r-- | backend/seckelapi/config/functions.toml | 45 | ||||
| -rw-r--r-- | backend/seckelapi/config/logging.toml | 31 | ||||
| -rw-r--r-- | backend/seckelapi/config/security.toml | 210 |
5 files changed, 343 insertions, 0 deletions
diff --git a/backend/seckelapi/Containerfile b/backend/seckelapi/Containerfile new file mode 100644 index 0000000..d36a165 --- /dev/null +++ b/backend/seckelapi/Containerfile @@ -0,0 +1,39 @@ +# Multi-stage build for SeckelAPI +FROM docker.io/library/rust:1.92-slim-trixie AS builder + +WORKDIR /build + +# Install build dependencies +RUN apt-get update && \ + apt-get install -y pkg-config libssl-dev && \ + rm -rf /var/lib/apt/lists/* + +# Copy source code +COPY sources/ . + +# Build release binary +RUN cargo build --release + +# Runtime stage - minimal Debian image +FROM docker.io/library/debian:trixie-slim + +WORKDIR /app + +# Install runtime dependencies +RUN apt-get update && \ + apt-get install -y ca-certificates libssl3 && \ + rm -rf /var/lib/apt/lists/* + +# Copy binary and config from builder +COPY --from=builder /build/target/release/seckelapi /app/seckelapi +COPY sources/config/ /app/config/ + +# Expose API port +EXPOSE 5777 + +# Run as non-root user +RUN useradd -r -u 1000 seckelapi && \ + chown -R seckelapi:seckelapi /app +USER seckelapi + +CMD ["/app/seckelapi"] diff --git a/backend/seckelapi/config/basics.toml b/backend/seckelapi/config/basics.toml new file mode 100644 index 0000000..908504a --- /dev/null +++ b/backend/seckelapi/config/basics.toml @@ -0,0 +1,18 @@ +# Basic ahh configs + +[server] +host = "0.0.0.0" +port = 5777 +request_body_limit_mb = 10 + +[database] +host = "localhost" +port = 3306 +database = "beepzone" +username = "beepzone" +password = "changeme123" +min_connections = 1 +max_connections = 10 +connection_timeout_seconds = 2 +connection_timeout_wait = 2 +connection_check = 1
\ No newline at end of file diff --git a/backend/seckelapi/config/functions.toml b/backend/seckelapi/config/functions.toml new file mode 100644 index 0000000..deb487b --- /dev/null +++ b/backend/seckelapi/config/functions.toml @@ -0,0 +1,45 @@ +# auto generation of things +[auto_generation] + +[auto_generation.assets] +field = "asset_numeric_id" +type = "numeric" +length = 8 +range_min = 10000000 +range_max = 99999999 +max_attempts = 10 +# on what event seckel api schould try to generate auto gen value incaase client send empty value +on_action = "insert" + +[scheduled_queries] + +# Single idempotent task that sets the correct state atomically to avoid double-trigger inserts +[[scheduled_queries.tasks]] +name = "sync_overdue_and_stolen" +description = "Atomically set lending_status to Overdue (1-13 days late) or Stolen (>=14 days late) only if it changed" +query = """ + -- Use max lateness per asset to avoid flip-flopping due to multiple open lending rows + -- Removed issue_tracker check from WHERE clause to avoid MySQL trigger conflict + UPDATE assets a + INNER JOIN ( + SELECT lh.asset_id, MAX(DATEDIFF(CURDATE(), lh.due_date)) AS days_late + FROM lending_history lh + WHERE lh.return_date IS NULL + AND lh.due_date IS NOT NULL + GROUP BY lh.asset_id + ) late ON a.id = late.asset_id + SET a.lending_status = CASE + WHEN a.asset_type IN ('N','B') AND late.days_late >= 14 THEN 'Stolen' + WHEN a.asset_type IN ('N','B') AND late.days_late BETWEEN 1 AND 13 THEN 'Overdue' + ELSE a.lending_status + END + WHERE a.asset_type IN ('N','B') + AND ( + (late.days_late >= 14 AND a.lending_status <> 'Stolen') + OR + (late.days_late BETWEEN 1 AND 13 AND a.lending_status <> 'Overdue') + ) +""" +interval_minutes = 2 +run_on_startup = true +enabled = true
\ No newline at end of file diff --git a/backend/seckelapi/config/logging.toml b/backend/seckelapi/config/logging.toml new file mode 100644 index 0000000..fdfc08a --- /dev/null +++ b/backend/seckelapi/config/logging.toml @@ -0,0 +1,31 @@ +# Logging Configuration +[logging] +# all logs can be commented out to disable them if you want yk, because you probably dont need more than the combined log +request_log = "./logs/request.log" +query_log = "./logs/queries.log" +error_log = "./logs/error.log" +warning_log = "./logs/warning.log" +info_log = "./logs/info.log" +combined_log = "./logs/sequel.log" + +# Log levels: debug, info, warn, error +level = "info" + +# mask fields that are sensitive in logs (they are hashed anyways but why log bcrypt hashes in ur logs thats dumb) +mask_passwords = true + +# other values that we might not want in query logs (also applies to request logs) +sensitive_fields = ["login_string", "password_reset_token", "pin_code"] + +# Custom log filters, route specific log entries to separate files using regex ... yes I have autism why are you asking? +[[logging.custom_filters]] +name = "security_violations" +output_file = "./logs/security_violations.log" +pattern = "(Permission denied|Too many WHERE|Authentication failed|invalid credentials|invalid PIN|invalid token)" +enabled = true + +[[logging.custom_filters]] +name = "admin_transactions" +output_file = "./logs/admin_activity.log" +pattern = "user=admin|power=100" +enabled = true diff --git a/backend/seckelapi/config/security.toml b/backend/seckelapi/config/security.toml new file mode 100644 index 0000000..f72b765 --- /dev/null +++ b/backend/seckelapi/config/security.toml @@ -0,0 +1,210 @@ +# prepare for evil ass autism configs! +[security] +# Yk what this is, if not read the fkn readme +whitelisted_pin_ips = ["192.168.1.0/24", "127.0.0.1"] +whitelisted_string_ips = ["192.168.5.0/24", "127.0.0.1"] + +# session stuffs +session_timeout_minutes = 60 # def session timeout (makes session key go bye bye) +refresh_session_on_activity = true # most useless thing ever most likely as nobody will ever disable this but sure you can just kill a users session during active use right? +max_concurrent_sessions = 3 # how many gooning session to allow per user (you can set custom ones per powerlevel btw) +session_cleanup_interval_minutes = 5 # how often to actually check on the session timeout, we aint gotta spam it none stop tbh + +# PIN and Token Auth +hash_pins = false # weather or not to use bcrypt for pin field (left off for dev work) +hash_tokens = false # Same as above +pin_column = "pin_code" +token_column = "login_string" + +# Rate Limiting, need i say more? +enable_rate_limiting = true # Do yuo wahnt raten limitierung or not? + +# If i have to explain these to you just dont use this software +auth_rate_limit_per_minute = 10000 +auth_rate_limit_per_second = 50000 + +# api rape limitz +api_rate_limit_per_minute = 100000 +api_rate_limit_per_second = 100000 + +# default query limits to avoid someone spamming quieries on a table with 271k rows +default_max_limit = 10000 +default_max_where_conditions = 1000 + +# own user preferences level +# Determines what an user can do with their own little preference store +# - "read-own-only": kiosk ah ruling +# - "read-write-own": what you probably want for most users +# - "read-write-all": adminier maybe ? +default_user_settings_access = "read-write-own" + +# define what tables exist +# known tables for wildcard permissions (*:rw) and to prevent SQL injection via table names cuz thats a thing +known_tables = [ + "users", "roles", "assets", "categories", "zones", + "suppliers", "templates", "audit_tasks", "borrowers", + "lending_history", "audit_history", "maintenance_log", + "asset_change_log", "issue_tracker", "issue_tracker_change_log", + "physical_audits", "physical_audit_logs", + "label_templates", "printer_settings", "print_history" +] + +# tables you cant write or change using proxi in any way not even user overrides below +read_only_tables = ["asset_change_log", "issue_tracker_change_log", "print_history"] + +# column names banned from being written to by default (this is however overwritable on a per table per column per user type schizo settings below) +global_write_protected_columns = [ + "id", + "created_date", + "created_at", + "last_modified_date", + "updated_at", + "last_modified_at", +] + +# note to myself how the rbac system kinda works +# Format: role_power contains both basic table rules and advanced column rules +# Basic rules: "table:permission" (r = read, w = write, rw = read+write, * = all tables (for like admins or smth)) +# Advanced rules: "table.column:permission" for more granular column level control +# Column permissions: r = read, w = write, rw = read+write, block = blocked (obviously) +# Use "table.*:block" to block all columns, then "table.specific_column:r" to allow specific ones +# Use "table.*:r" to allow all columns, then "table.sensitive_column:block" to block specific ones + +# In the future even more advaned rules called schizo_rules will be implemented where you can define sql logic based rules +# like "only allow access to rows where user_id = current_user_id" or "only allow access to assets where status != 'Stolen'" + +# i let an llm comment on the crap below so i can understand what ive done in like 3 months when i forget everything + +[permissions] + +[permissions."100"] +# Admin - full access to everything +basic_rules = [ + "*:rw", # Example of wildcard full access to all known tables + "asset_change_log:r", # More or less redundant but whatever + "issue_tracker_change_log:r" # Same as above +] +advanced_rules = [ + # Further granularity wow! + "assets.asset_numeric_id:r", + "assets.created_by:r", + "assets.last_modified_by:r", + "users.password_hash:block", +] +max_limit = 500 +max_where_conditions = 50 +session_timeout_minutes = 120 # Admins get longer sessions (2 hours) +max_concurrent_sessions = 5 # Admins can have more concurrent sessions +rollback_on_error = true # Rollback batch operations on any error +allow_batch_operations = true # Admins can use batch operations +user_settings_access = "read-write-all" # Admins can modify any user's preferences + +[permissions."75"] +# Manager - full asset management, limited user access +rollback_on_error = true # Rollback batch operations on any error +allow_batch_operations = true # Managers can use batch operations +basic_rules = [ + "assets:rw", + "lending_history:rw", + "audit_history:rw", + "maintenance_log:rw", + "borrowers:rw", + "categories:rw", + "zones:rw", + "suppliers:rw", + "templates:rw", + "audit_tasks:rw", + "issue_tracker:rw", + "physical_audits:rw", + "physical_audit_logs:rw", + "label_templates:rw", + "printer_settings:rw", + "print_history:r", + "users:r", # Basic read access, then restricted by advanced rules below + "roles:r", + "asset_change_log:r", + "issue_tracker_change_log:r" +] +advanced_rules = [ + # Table-specific protected (same as admin) + "assets.asset_numeric_id:r", + "assets.created_by:r", + "assets.last_modified_by:r", + # Users table - can read most info but not sensitive auth data + "users.password:block", + "users.password_hash:block", + "users.pin_code:block", + "users.login_string:block", + "users.password_reset_token:block", + "users.password_reset_expiry:block", +] +# Query limits (moderate for managers) +max_limit = 200 +max_where_conditions = 20 +user_settings_access = "read-write-own" # Managers can only modify their own preferences + +[permissions."50"] +# Staff - asset and lending management, NO user access +rollback_on_error = false # Don't rollback batch operations on error (continue processing) +allow_batch_operations = true # Staff can use batch operations +basic_rules = [ + "assets:rw", + "lending_history:rw", + "audit_history:rw", + "maintenance_log:rw", + "borrowers:rw", + "categories:r", + "zones:r", + "suppliers:r", + "templates:r", + "audit_tasks:r", + "issue_tracker:r", + "physical_audits:r", + "physical_audit_logs:r", + "label_templates:r", + "printer_settings:r", + "print_history:r", + "asset_change_log:r", + "issue_tracker_change_log:r" +] +advanced_rules = [ + # Table-specific protected (same as admin/manager) + "assets.asset_numeric_id:r", + "assets.created_by:r", + "assets.last_modified_by:r", +] +# No users table access for staff - security requirement +# Query limits (standard for staff) +max_limit = 100 +max_where_conditions = 10 +user_settings_access = "read-write-own" # Staff can only modify their own preferences + +[permissions."25"] +# Student - read-only access, no financial data, no user access, no change logs +rollback_on_error = true # Rollback batch operations on any error +allow_batch_operations = false # Students cannot use batch operations +basic_rules = [ + "assets:r", + "lending_history:r", + "borrowers:r", + "categories:r", + "zones:r" +] +advanced_rules = [ + # Assets table - hide financial and sensitive info + "assets.price:block", + "assets.purchase_date:block", + "assets.supplier_id:block", + "assets.warranty_expiry:block", + # Borrowers table - hide personal contact info + "borrowers.email:block", + "borrowers.phone_number:block", + "borrowers.notes:block" +] + +# Query limits (restricted for students) +max_limit = 50 +max_where_conditions = 5 +user_settings_access = "read-own-only" # Students can only read their own preferences, not modify + + |
