Commit Graph

1474 Commits

Author SHA1 Message Date
Edouard Vanbelle 0fcd617fd1 feat(calendar,addressbook): migrate share to authz engine
migrate DB entries to authz engine
    and wire authz engine to caldav and carddav
2026-07-08 01:03:25 +02:00
Edouard Vanbelle b5881c7114 feat(calendar,addressbook): prepare authz engine 2026-07-08 01:03:25 +02:00
Edouard Vanbelle 484f933f77 security: bump crossbeam-epoch to fix security audit
RUSTSEC-2026-0204
2026-07-08 01:01:27 +02:00
Edouard Vanbelle ddb6cf3f5d chore: bump OxiCloud to 0.8.2 to reflect git tag 2026-07-08 01:01:27 +02:00
Dionisio Pozo b9d0b569ba Merge pull request #561 from EdouardVanbelle/fix/front-user-change 2026-07-07 22:06:24 +02:00
Edouard Vanbelle 3108fed228 fix(front): clean localStorage on user change
- fix issue with selected drive and user logout/login via another user
    (was raising a "404 not found")
    - normalize all localStorage to "oxi-" prefix
    - add a specific frontend/AGENTS.md for frontend part (stop increasing the global AGENTS.md)
2026-07-07 21:37:00 +02:00
Dionisio Pozo 4fb2acf160 Merge pull request #557 from EdouardVanbelle/fix/webdav-drive 2026-07-06 23:40:52 +02:00
Edouard Vanbelle f7deb7aaf4 fix(authz): invalidate role cache on change 2026-07-06 23:07:49 +02:00
Edouard Vanbelle 79f4792709 fix(quota): pre-check quota for COPY/MOVE
check qouta for a cross drive MOVE
    check quota for a COPY
2026-07-06 22:14:50 +02:00
Edouard Vanbelle 7e34045ff8 feat(drive): fix webdav back-compat
add env variable `OXICLOUD_WEBDAV_DRIVE_LISTING_PREFIX`
    which is by default:
    `OXICLOUD_WEBDAV_DRIVE_LISTING_PREFIX="@drive"`

    so `/webdav/` -> points to user's personal drive (**backward compatibilit**y)
    `/web/dav/@drive/{uuid|drive name}/` points to the respective drive

    if admins want directly `/webdav/` pointing to list of drives they need to:
    `OXICLOUD_WEBDAV_DRIVE_LISTING_PREFIX=""`

    + ensure lock is per user (RFC 4918 §9.11)

    fix: #554
2026-07-06 22:14:50 +02:00
Dionisio Pozo 3d74bed326 Merge pull request #549 from Candinya/fix/docker-publish-ci-fail
fix(ci): workflow fail caused by uppercase of image name
2026-07-06 18:12:04 +02:00
Dionisio Pozo ed61dc08aa Merge pull request #552 from steel97/fix/ui
fix(ui): token revoke buttons on light theme, nextcloud login page
2026-07-06 08:58:41 +02:00
Ivan Yv 0b33ed7b2b fix(ui): token revoke buttons on light theme, nextcloud login page 2026-07-06 07:25:00 +03:00
Dionisio Pozo 1f35200b15 Merge pull request #551 from EdouardVanbelle/security/authz 2026-07-06 00:03:03 +02:00
Edouard Vanbelle 0870990e1b fix(locale): correct IT i18n 2026-07-05 23:31:48 +02:00
Edouard Vanbelle 75601beb43 security(wopi): add authz to Wopi 2026-07-05 23:31:44 +02:00
Edouard Vanbelle 1786fe4111 security(nextcloud): chroot-aware display paths + recent race fix
strip_chroot_prefix replaces the hardcoded "Personal/" strip
    in NC trashbin PROPFIND, OCS unified search, and REPORT
    (favorites + search). Handles composed chroots, drops
    cross-chroot items instead of surfacing malformed paths, and
    fixes the leading-slash mismatch (FolderDto path has '/', DB
    paths don't) that silently dropped every NC trashbin item
    post-D3. OCS keeps a first-segment fallback (results
    legitimately span drives, no single chroot).

    uploads_handler switches to nc_to_internal_path(chroot, …)
    for the two remaining hardcoded "Personal/" sites, closing
    the D1 TODO markers.

    RecentService::record_item_access is split from a new
    record_item_access_internal (no authz) used by
    RecentRecordingHook. Round 1's authz.require widened the
    tokio::spawn race past tests/api/recent.hurl step 7; the
    internal path skips the redundant Read gate — upstream
    _with_perms already enforced it.

    Tests: 8 unit tests pin strip_chroot_prefix (leading slash,
    composed chroots, sibling-leak rejection, partial-prefix,
    empty-chroot). drives_membership.hurl step 21b/22b cover
    Editor upload → 201 / Viewer upload → 404 fresh + overwrite
    with fixture cleanup at 30c. test_nc_move_copy_delete_trash
    K1 pins the actual original-location value.
2026-07-05 22:53:05 +02:00
Edouard Vanbelle 0342bae300 security(nextcloud): add authz to PUT verb 2026-07-05 22:53:05 +02:00
Edouard Vanbelle b95e740b2f security(music): ensure read permission via authz 2026-07-05 22:53:05 +02:00
Edouard Vanbelle 2cda8e7e22 security(favorite,recent): ensure read permission 2026-07-05 22:53:05 +02:00
Edouard Vanbelle cf5423b723 security(public link): require share permission
issue was: a user can reshare publicly a resource
    on owner revocation, the attacker keep it's own share
    request now share permission
2026-07-05 22:53:05 +02:00
Edouard Vanbelle f115fed5a6 feat(drive): cleanup of useless owner_id 2026-07-05 22:53:05 +02:00
Nya Candy ce10b83b64 chore: add quote to prevent possible yaml parse error 2026-07-05 23:36:06 +08:00
Nya Candy 3fdd2eaf1c fix: workflow fail caused by uppercase of image name 2026-07-05 23:18:01 +08:00
Dionisio Pozo 025045e4af Merge pull request #547 from albanobattistella/main 2026-07-05 13:58:59 +02:00
albanobattistella bde40c6042 Update Italian translation 2026-07-05 13:49:59 +02:00
Dionisio Pozo af07cab673 Merge pull request #546 from Candinya/feat/publish-to-ghcr
feat(ci): also publish docker image to ghcr
2026-07-05 08:10:30 +02:00
Nya Candy 7e586e92be feat: also publish docker image to ghcr 2026-07-04 10:13:19 +08:00
Dionisio Pozo 6a430d4e15 Merge pull request #543 from EdouardVanbelle/feat/drive 2026-07-03 04:20:51 +02:00
Edouard Vanbelle 0a6368e1bf feat(plugins): annotation to allow panic 2026-07-03 02:27:48 +02:00
Edouard Vanbelle 92d1a10d45 security(quick-xml): bump version to 0.41.0
- and protect amount of properties
 - azure_core 0.21.0 is using quick-xml 0.31.0  which is Dos-able
   azure_core is no more maintained, would migrte to official azure lib
   later
2026-07-03 02:12:36 +02:00
Edouard Vanbelle dff0e7365e feat(drive): remove all user_id ref in file or folder 2026-07-03 02:12:32 +02:00
Edouard Vanbelle 37467ed9d3 feat(drive): remove all owner_id from {File,Folder}Dto 2026-07-03 01:13:53 +02:00
Edouard Vanbelle 29bcf48eb7 feat(drive): move UI to {created,updated}_by 2026-07-03 00:31:36 +02:00
Edouard Vanbelle 206a780494 feat(drive): stop writing in {file,folder}.user_id
plan:

    ```
    What step 5 is actually doing

    Goal: stop writing to storage.files.user_id / storage.folders.user_id on new INSERTs. This is a prerequisite for step 6 (dropping the column entirely). The column has existed since the pre-D0 single-owner era; every read that used to key on it has already been migrated to drive-membership grants over the last N days.

    What has to change together for this to be safe:

    ┌──────────────┬─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┬───────────────────────────────────────────────────────────────────────────────────────────────────────┐
    │    Piece     │                                                          What changes                                                           │                                                  Why                                                  │
    ├──────────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────┤
    │ Migration    │ Swap storage.files uniqueness indexes from (folder_id, name, user_id) to (drive_id, folder_id, name)                            │ Otherwise, two new rows with user_id = NULL would both be allowed (PG treats NULLs as distinct) —     │
    │ (a)          │                                                                                                                                 │ uniqueness silently breaks                                                                            │
    ├──────────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────┤
    │ Migration    │ ALTER user_id DROP NOT NULL on both tables                                                                                      │ Otherwise, dropping the INSERT bind violates NOT NULL and every write 500s                            │
    │ (b)          │                                                                                                                                 │                                                                                                       │
    ├──────────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────┤
    │ Migration    │ Drop dead user_id-leading indexes                                                                                               │ Cheap cleanup — nothing scans them anymore                                                            │
    │ (c)          │                                                                                                                                 │                                                                                                       │
    ├──────────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────┤
    │ PL/pgSQL (d) │ Rewrite storage.copy_folder_tree without user_id in the INSERT column list                                                      │ Cross-drive copy runs entirely in SQL, needs the same treatment                                       │
    ├──────────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────┤
    │ Rust (e)     │ ~12 INSERT column-list drops across folder_db_repository, file_blob_write_repository, drive_pg_repository, dedup_service,       │ Actual write path                                                                                     │
    │              │ folder_service, load-seed.rs                                                                                                    │                                                                                                       │
    ├──────────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────┤
    │ Rust (f)     │ Simplify folder_db_repository::create_folder's parent lookup to only fetch drive_id (was fetching (user_id, drive_id))          │ It's fetching a value it no longer needs                                                              │
    └──────────────┴─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┴───────────────────────────────────────────────────────────────────────────────────────────────────────┘
    ```
2026-07-03 00:23:35 +02:00
Edouard Vanbelle 25dcab8e85 feat(drive): dedup service move user_id to authz 2026-07-02 21:10:12 +02:00
Edouard Vanbelle a0e5c34950 feat(webdav): impl if header RFC 4918 §10.4
this fix an issue raised by webdav litmus test
2026-07-02 20:59:18 +02:00
Edouard Vanbelle 91435e6be1 feat(drive): webdav handler based on drive
and add authz
2026-07-02 20:41:33 +02:00
Edouard Vanbelle f5f5b1167f feat(drive): remove _for_owner() and use authz
remove related IDOR protection as Hurl tests are covering this surface
2026-07-02 01:14:02 +02:00
Edouard Vanbelle 09790644f3 feat(drive): repl user_id by caller has read access
repl user_id by caller has read access in readonly functions
    using CALLER_CAN_READ_DRIVE constant

    ensure webdav preview is using the permission handler
2026-07-02 01:03:39 +02:00
Edouard Vanbelle 79bc60899b feat(drive): improvepermission check and simplify functions 2026-07-02 00:29:33 +02:00
Edouard Vanbelle 858139ef3b feat(drive): prepare removal of user_id
this commit changes GET /api/<resources> to return resource caller has access to
    this is not anymmore resources users is owner of
2026-07-02 00:01:20 +02:00
Edouard Vanbelle 09339ea63f feat(drive): UI: show policiesto drive's members
and add tests
2026-07-01 22:35:08 +02:00
Edouard Vanbelle 01ff7dab0b feat(drive): impl policy photo + music policies
add `include_in_photo_index` and `include_in_music_index` policies
    both true for default personal drive

    photo is implemented
    music is not yet implemented
2026-07-01 21:57:37 +02:00
Edouard Vanbelle 20e5ef0ef2 feat(drive): personal drive are photo + music indexed by default 2026-07-01 21:28:00 +02:00
Edouard Vanbelle 473c126291 doc(drive.md): face recognition cluster per drive 2026-07-01 21:09:56 +02:00
Dionisio Pozo e7e7218e9b Merge pull request #540 from EdouardVanbelle/chore/git-hash-in-docker-build 2026-07-01 07:53:36 +02:00
Dionisio Pozo fba7b67a1f Merge pull request #539 from EdouardVanbelle/feat/metadata-binded-to-resource-id 2026-07-01 07:53:19 +02:00
Edouard Vanbelle 0567082ad5 chore(docker): add git branch in docker build 2026-07-01 00:35:40 +02:00
Edouard Vanbelle d134fc889d doc(metadata): bride dead props to API metadata
what about exposing dead props into rest API

    let user to store preferences, labels on resources

    | Use case | What it looks like | Why dead-props help |
    |---|---|---|
    | Photo annotations | captions, ratings (1-5), notes per photo | already keyed by `file_id`; round-trips via WebDAV without re-implementing |
    | Web-UI tags / labels | `oxi:user:tag/project=alpha`, color flags, "archived" markers | per-resource user metadata without new tables |
    | Folder UI preferences | default sort, default view mode, "favourite" flag | persistent per-folder, shared across users on shared drives |
    | Cross-protocol bridge | Thunderbird sets `oxi:lastsync=...` via PROPPATCH → web UI reads it via REST | one store, two surfaces — visibility goes both ways |
    | Workflow / approval state | `reviewed_by=alice`, `due=2026-09-15` | ad-hoc state per resource without schema sprawl |
    | Third-party integrations | external apps store scratch space per resource | lower barrier than implementing WebDAV |
2026-07-01 00:29:33 +02:00