Skip to content

feat(file-manager): add download URLs with file access policy - #116

Merged
PANiXiDA merged 10 commits into
developmentfrom
feature/personal-file-download-url
Oct 27, 2026
Merged

PANiXiDA merged 10 commits into
developmentfrom
feature/personal-file-download-url

Conversation

@PANiXiDA

@PANiXiDA PANiXiDA commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

Add GET /api/v1/files/{id}/download-url, returning url and expiresAt for an accessible Ready file. The handler loads the aggregate and checks Files/Policies/FileAccessPolicy before generating a signed URL.

Access rules:

  • Personal: file-manager.personal-files.read.all allows any owner; file-manager.personal-files.read.own requires the current user to own the file.
  • Avatar: file-manager.avatars.read.
  • Unauthenticated callers, unsupported file types and the former unscoped personal read permission are denied.

Register Create/Read/Update/Delete for avatars and both .own and .all variants for personal files: 12 FileManager permissions in total. The Identity data migration GrantFileManagerPermissions grants all 12 to the existing administrative role Developer; Player receives personal CRUD .own and avatar Read. Resolve roles by normalized name, preserve existing assignments and avoid duplicate claims. Rollback preserves granted assignments, following the existing role-seeding convention. CRUD permissions are catalog entries; this change applies the file policy only to download URL retrieval.

Core's normal soft-delete filter hides deleted aggregates. Missing or inaccessible files return 404; unavailable user accounts return 401; empty identifiers return 400; accessible uploads that are not Ready return 409. The aggregate's GetDownloadContentType() validates readiness and a non-null content type; the handler propagates domain errors. Sign URLs using the persisted storage key, file name and validated content type. Clients download directly from S3. URL lifetime comes from FileManager:S3Storage:PresignedUrlLifetime (15 minutes by default). Signing does not inspect or change S3 content.

Application query handlers may return either an IReadModel or a payload declared by the PANiXiDA.Core.Application assembly. Wrapper and collection payloads are checked recursively; read-repository result rules stay unchanged. Return Core's PresignedDownloadUrl directly and preserve the HTTP response shape through the presentation mapper.

Manual mediator reconciliation uses a separate test collection and host with its recurring schedule disabled. Scheduled reconciliation keeps a separate host with the five-second schedule enabled; its real background processing checks are preserved.

Validation:

  • Full solution build: zero warnings/errors; full formatting verification passed.
  • Common: 15 unit tests. FileManager: 259 unit tests and the full 50-test functional suite passed.
  • Identity unit, integration and permission-catalog functional tests passed; 251 integration tests passed after merging development.
  • Architecture tests passed; 34 naming, display-name, arrange/act/assert and member-order convention checks passed after isolating the reconciliation fixture.
  • PostgreSQL migration tests verify exact role grants, pre-existing grants, repeated execution, custom role IDs and preservation of unrelated claims.
  • Policy, handler and HTTP tests cover own/all access to the same and different owners, obsolete unscoped permissions, authentication, soft deletion and upload state. Existing real S3 download tests cover both file types, original bytes, attachment headers and Unicode names.

CI #769 passed for 0d0c6c2: all test projects, formatting, Helm, coverage/report aggregation and SonarQube quality checks are green.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review 🔄 Running since 2026-10-27T19:13:04.880676Z 0d0c6c2 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@PANiXiDA PANiXiDA changed the title feat(file-manager): add personal file download URLs feat(file-manager): add download URLs with file access policy Oct 27, 2026
@PANiXiDA

Copy link
Copy Markdown
Contributor Author

@codex

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🎉

Reviewed commit: 2e3cb421a7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@panixida-sonarqube

Copy link
Copy Markdown

@PANiXiDA

Copy link
Copy Markdown
Contributor Author

@codex

@PANiXiDA
PANiXiDA merged commit abf5953 into development Oct 27, 2026
39 checks passed
@PANiXiDA
PANiXiDA deleted the feature/personal-file-download-url branch October 27, 2026 19:22
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