Skip to content

Centralize file access validation with FileAccess capability token#1327

Merged
lovasoa merged 1 commit into
mainfrom
refactor-file-access-validation-structure
Jun 12, 2026
Merged

Centralize file access validation with FileAccess capability token#1327
lovasoa merged 1 commit into
mainfrom
refactor-file-access-validation-structure

Conversation

@lovasoa

@lovasoa lovasoa commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator

Motivation

  • The code enforced the same unprivileged-path guard in multiple places and threaded a misspelled priviledged boolean through several APIs, creating a maintenance and security footgun.
  • The goal is to make the untrusted-path validation a single, type-level decision so new resolution paths cannot forget the guard.

Description

  • Introduce a Copy capability token FileAccess<'a> with FileAccess::unprivileged(path) that runs the guard at construction and FileAccess::privileged(path) for trusted callers, and make the validator module-private.
  • Refactor FileSystem APIs to accept FileAccess instead of a privileged boolean, make safe_local_path return an infallible PathBuf, and derive the path via access.path().
  • Update FileCache and the FileStore::contains signature to accept FileAccess, change get to take FileAccess, and remove ad-hoc pre-checks so the guard is enforced once at token creation.
  • Update call sites so HTTP routing and request handlers build FileAccess::unprivileged(...) and templates, run_sql, and internal read_file build FileAccess::privileged(...); also let-bind derived candidate paths before await points where needed.

Testing

  • Ran cargo fmt --all which completed successfully.
  • Ran cargo +1.95.0 clippy --all-targets --all-features -- -D warnings which succeeded (linting performed with the newer toolchain).
  • Ran the full test suite with cargo +1.95.0 test and all tests passed (147 unit tests and 70 integration tests reported).
  • Note: the environment default Rust toolchain (1.92.0) cannot compile a locked dependency's build script (libsqlite3-sys) due to an unstable cfg_select usage, so linting and tests were executed with the installed Rust 1.95.0 toolchain as recorded in the PR notes.

Codex Task

@lovasoa lovasoa merged commit ebb8a1d into main Jun 12, 2026
51 checks passed
@lovasoa lovasoa deleted the refactor-file-access-validation-structure branch June 12, 2026 13:23
lovasoa added a commit that referenced this pull request Jun 12, 2026
Each built-in `sqlpage.*` function is now a plain `async fn` in its own
file under `sqlpage_functions/functions/`, with an ordinary Rust signature
and no marker comments or macros inside it.

Registration is automatic: `build.rs` lists the files in `functions/` into a
`sqlpage_functions!` call (the only generated code, one line per function),
and that macro declares the modules and builds the `SqlPageFunctionName`
enum the SQL engine dispatches on. There is no marker-comment parsing and no
per-argument codegen. Argument extraction, dispatch and return-value
conversion are ordinary generic code in function_traits.rs (`Extract`,
`Handler`, `IntoCowResult`), using the same `Fn`-arity trick axum uses for
handlers, so a function's argument and return types are read straight from
its signature.

Also folds in main's FileAccess centralization (#1327) for the file-reading
functions.

Verified: `cargo test` passes (148 lib + 70 integration tests, including
run_all_sql_test_files, the hmac webhook tests, the upload tests and
test_file_upload_through_runsql which exercises the &mut DbConn path).
`cargo clippy` and `cargo fmt --check` are clean.
lovasoa added a commit that referenced this pull request Jun 12, 2026
* refactor: split SQLPage functions into one module each

Each built-in `sqlpage.*` function is now a plain `async fn` in its own
file under `sqlpage_functions/functions/`, with an ordinary Rust signature
and no marker comments or macros inside it.

Registration is automatic: `build.rs` lists the files in `functions/` into a
`sqlpage_functions!` call (the only generated code, one line per function),
and that macro declares the modules and builds the `SqlPageFunctionName`
enum the SQL engine dispatches on. There is no marker-comment parsing and no
per-argument codegen. Argument extraction, dispatch and return-value
conversion are ordinary generic code in function_traits.rs (`Extract`,
`Handler`, `IntoCowResult`), using the same `Fn`-arity trick axum uses for
handlers, so a function's argument and return types are read straight from
its signature.

Also folds in main's FileAccess centralization (#1327) for the file-reading
functions.

Verified: `cargo test` passes (148 lib + 70 integration tests, including
run_all_sql_test_files, the hmac webhook tests, the upload tests and
test_file_upload_through_runsql which exercises the &mut DbConn path).
`cargo clippy` and `cargo fmt --check` are clean.

* less magic
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Centralize unprivileged-path validation behind a single FileAccess type

1 participant