Three-tier project visibility & admin role editing #38

Merged
qwc merged 9 commits from feature/project-visibility-global-access into main 2026-02-04 14:14:47 +01:00
Owner

Summary

Implements issue #37: Replace the binary public/private project model with a three-tier visibility system and add admin role editing.

Visibility Model

Visibility Who can view Governed by
public Anyone, including anonymous
private Authenticated users in the global access list access.private config + admin UI
custom Only users with explicit per-project access Per-project access grants

Migration: is_public=truepublic, is_public=falsecustom (preserves current behavior exactly).

Key Changes

  • DB migration: Add visibility column, migrate from is_public (all 3 dialects)
  • Global access system: New global_access and global_access_grants tables for private visibility
  • Config: New access.private section with users, LDAP groups, and OAuth2 groups
  • Auth sync: LDAP/OAuth2 group membership resolved into global access grants at login
  • Admin UI: Visibility dropdown replaces checkbox; inline role editing on users page
  • Built-in docs: Updated for the new visibility model

Commits (9)

  1. f18f495 — DB migration for visibility column
  2. 1a9fea9 — Model & store changes (IsPublic → Visibility)
  3. 6b67af5 — Global access tables and store
  4. ef0a882 — Config section & startup sync
  5. ab21dbb — Access check logic for three-tier model
  6. f26aba9 — LDAP/OAuth2 global access sync at login
  7. e74e209 — Admin UI updates
  8. 5c1d5da — Built-in documentation updates
  9. 9bef19e — Cleanup (.gitignore)

Test plan

  • go test ./... passes
  • Existing public projects remain publicly accessible
  • Existing non-public projects remain accessible only to assigned users (migrated as custom)
  • New project with private visibility: only users/groups in global access list can view
  • Admin can change user's global role from the users page
  • LDAP/OAuth2 users get global access resolved at login from group membership
  • API returns visibility field instead of is_public

Closes #37

🤖 Generated with Claude Code

## Summary Implements issue #37: Replace the binary public/private project model with a three-tier visibility system and add admin role editing. ### Visibility Model | Visibility | Who can view | Governed by | |---|---|---| | `public` | Anyone, including anonymous | — | | `private` | Authenticated users in the global access list | `access.private` config + admin UI | | `custom` | Only users with explicit per-project access | Per-project access grants | **Migration**: `is_public=true` → `public`, `is_public=false` → `custom` (preserves current behavior exactly). ### Key Changes - **DB migration**: Add `visibility` column, migrate from `is_public` (all 3 dialects) - **Global access system**: New `global_access` and `global_access_grants` tables for private visibility - **Config**: New `access.private` section with users, LDAP groups, and OAuth2 groups - **Auth sync**: LDAP/OAuth2 group membership resolved into global access grants at login - **Admin UI**: Visibility dropdown replaces checkbox; inline role editing on users page - **Built-in docs**: Updated for the new visibility model ### Commits (9) 1. `f18f495` — DB migration for visibility column 2. `1a9fea9` — Model & store changes (IsPublic → Visibility) 3. `6b67af5` — Global access tables and store 4. `ef0a882` — Config section & startup sync 5. `ab21dbb` — Access check logic for three-tier model 6. `f26aba9` — LDAP/OAuth2 global access sync at login 7. `e74e209` — Admin UI updates 8. `5c1d5da` — Built-in documentation updates 9. `9bef19e` — Cleanup (.gitignore) ## Test plan - [ ] `go test ./...` passes - [ ] Existing public projects remain publicly accessible - [ ] Existing non-public projects remain accessible only to assigned users (migrated as `custom`) - [ ] New project with `private` visibility: only users/groups in global access list can view - [ ] Admin can change user's global role from the users page - [ ] LDAP/OAuth2 users get global access resolved at login from group membership - [ ] API returns `visibility` field instead of `is_public` Closes #37 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Introduces a three-tier visibility model (public/private/custom)
for projects. Existing is_public=true projects migrate to 'public',
is_public=false to 'custom', preserving current behavior exactly.

SQLite keeps is_public in place (no DROP COLUMN support) but code
will stop referencing it. Postgres and MySQL drop the old column.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Changes Project model from bool IsPublic to string Visibility with
three constants: public, private, custom. Updates store interface
(ListPublic → ListByVisibility), SQL queries, all handlers, and
tests. The API JSON field changes from is_public to visibility.

Adds GlobalAccess/GlobalAccessGrant models and GlobalAccessStore
interface (implementation comes next commit). Wires globalAccess
field into Handler/Deps structs.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Creates global_access table for rules (config/UI-sourced) and
global_access_grants table for resolved per-user grants. These
support the "private" visibility tier where access is governed
by global rules rather than per-project assignments.

Includes SQL implementation with upsert support, config sync,
and migration files for all three database dialects.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Introduces AccessConfig structs for configuring who can access
projects with "private" visibility. Config rules are synced to
the global_access table on startup, following the same pattern
as syncConfigGroupMappings.

Updates config.yaml.example with documented access.private section.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Updates canUpload to check global access grants for private
visibility projects. The canViewProject function (updated in
commit 2) handles the three-tier logic: public allows all,
private checks global grants, custom checks per-project access.

Project and version handlers now use canViewProject instead of
inline IsPublic checks.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
At login, resolve user's group membership against global_access rules
and upsert/delete global_access_grants accordingly. This enables the
private visibility tier for federated users.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace is_public checkbox with visibility select (public/private/custom)
in project create and edit forms. Show per-project access section only
for custom visibility. Add inline role dropdown on users page.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Document the public/private/custom visibility model, global access
config section, and LDAP/OAuth2 global access sync in the self-
deployable documentation.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Remove accidentally committed files, update .gitignore
All checks were successful
CI / test (pull_request) Successful in 1m10s
CI / build (pull_request) Successful in 54s
CI / docker (pull_request) Has been skipped
9bef19e8cb
Remove .mcp.json and main binary that were accidentally committed.
Add them to .gitignore to prevent future accidents.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
qwc merged commit 3490ea2d96 into main 2026-02-04 14:14:47 +01:00
qwc deleted branch feature/project-visibility-global-access 2026-02-04 14:14:47 +01:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
qwc-open/asiakirjat!38
No description provided.