Skip to content

feat(config): grant and revoke user permissions on objects - #26

Open
s31teg wants to merge 1 commit into
eisber:mainfrom
s31teg:feat/config-user-grant
Open

s31teg wants to merge 1 commit into
eisber:mainfrom
s31teg:feat/config-user-grant

Conversation

@s31teg

@s31teg s31teg commented Oct 12, 2026

Copy link
Copy Markdown

Summary

When an API user calls /dev/sps/io/<input>/pulse on an object it has no permission entry for, for example a virtual input just added for a webhook, the Miniserver answers Code="403". lox-cli can add users but can't edit their object permissions. This PR adds that.

Commands

lox config user-grant  <FILE> <USER> <OBJECT> [--group] [--act <N>] [--save-as <PATH>]
lox config user-revoke <FILE> <USER> <OBJECT> [--group] [--save-as <PATH>]
lox config user-perms  <FILE> <USER> [--group]
lox config add --type virtual-input --title T <FILE> --grant <USER>
lox config add-virtual-in <FILE> T --grant <USER>
  • user-grant appends <PRM REF="<uuid>" ACT="3"/> to the user's <PH> block and updates NUM. It creates the block if needed. --act changes the access value of an existing entry.
  • user-revoke removes the entry and drops an emptied <PH>, so a grant followed by a revoke gives a byte-identical file. uuid:<uuid> also revokes entries whose object no longer exists.
  • --group edits a user group (same <PH>/<PRM> structure).
  • user-perms lists the permitted objects (title, type, ACT, uuid). config users gains a permission count and, with -o json, each user's uuid and resolved permissions.
  • --grant <USER> on the two virtual-input commands. add_virtual_in now also returns the VirtualIn's own UUID, which is what PRM REF points at.

Safety

  • Users are matched only by exact (case-insensitive) title or uuid:, never fuzzily, so the wrong account can't be edited by accident.
  • Objects use the existing element selector and must match exactly one element.
  • Repeated grants and revokes are no-ops that leave the file untouched.
  • Password hashes (<HP>) and TIM attributes are never touched.

Notes

Testing

  • Unit tests in permissions.rs: grant, idempotent grant, --act update, revoke, revoking a missing object, group grant, ambiguous-object rejection, and grant-then-revoke byte identity on a BOM/CRLF fixture.
  • Integration and smoke tests in tests/config_integration.rs and tests/cli_smoke.rs.
  • COMMANDS.md, README.md and CHANGELOG.md are updated.
  • cargo fmt --check, cargo clippy -- -D warnings, cargo build --release and cargo test pass.
  • On a copy of a real 2.4 MB project:
    • granting an API user access to a virtual input changed only <PH NUM> and added one <PRM> line;
    • repeating the grant left the file unchanged, and revoking restored the original bytes;
    • an unknown user and an ambiguous object were rejected without touching the file.

An API user calling /dev/sps/io/<input>/... gets HTTP 403 when it has no
permission entry for that object (e.g. a newly added virtual input).

- lox config user-grant <file> <user> <object> [--group] [--act N]
  appends <PRM REF="<uuid>" ACT="3"/> to the user's (or user group's)
  <PH> block, creating it if needed, and updates NUM. Idempotent;
  --act updates the access value of an existing entry.
- lox config user-revoke <file> <user> <object> [--group] removes the
  entry and drops an emptied <PH>, so grant + revoke is byte-identical.
  uuid:<uuid> also revokes entries whose object no longer exists.
- lox config user-perms <file> <user> [--group] lists permitted objects
  (title, type, ACT, uuid); `config users` gains a permission count and,
  with -o json, each user's uuid and resolved permissions.
- --grant <user> on `config add --type virtual-input` and
  `config add-virtual-in`; add_virtual_in now also returns the
  VirtualIn's own UUID, which is what PRM REF points at.

Users are matched by exact (case-insensitive) title or uuid:, never
fuzzily; objects use the element selector and must match one element.
No-op grants/revokes leave the file untouched. Cmd::Config boxes its
ConfigCmd to keep clippy's large_enum_variant quiet.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant