mirror of
https://github.com/photoprism/photoprism.git
synced 2025-12-12 00:34:13 +01:00
Docs: Update /pkg/service/http/... -> /pkg/http/...
Signed-off-by: Michael Mayer <michael@photoprism.app>
This commit is contained in:
@@ -274,7 +274,7 @@ Note: Across our public documentation, official images, and in production, the c
|
||||
### HTTP Download — Security Checklist
|
||||
|
||||
- Use the shared safe HTTP helper instead of ad‑hoc `net/http` code:
|
||||
- Package: `pkg/service/http/safe` → `safe.Download(destPath, url, *safe.Options)`.
|
||||
- Package: `pkg/http/safe` → `safe.Download(destPath, url, *safe.Options)`.
|
||||
- Default policy in this repo: allow only `http/https`, enforce timeouts and max size, write to a `0600` temp file then rename.
|
||||
- SSRF protection (mandatory unless explicitly needed for tests):
|
||||
- Set `AllowPrivate=false` to block private/loopback/multicast/link‑local ranges.
|
||||
@@ -419,7 +419,7 @@ Note: Across our public documentation, official images, and in production, the c
|
||||
|
||||
- Keep bootstrap code decoupled: avoid importing `internal/service/cluster/node/*` from `internal/config` or the cluster root, let nodes talk to the Portal over HTTP(S), and rely on constants from `internal/service/cluster/const.go`.
|
||||
- Config init order: load `options.yml` (`c.initSettings()`), run `EarlyExt().InitEarly(c)`, connect/register the DB, then invoke `Ext().Init(c)`.
|
||||
- Theme endpoint: `GET /api/v1/cluster/theme` streams a zip from `conf.ThemePath()`; only reinstall when `app.js` is missing and always use the header helpers in `pkg/service/http/header`.
|
||||
- Theme endpoint: `GET /api/v1/cluster/theme` streams a zip from `conf.ThemePath()`; only reinstall when `app.js` is missing and always use the header helpers in `pkg/http/header`.
|
||||
- Registration flow: send `rotate=true` only for MySQL/MariaDB nodes without credentials, treat 401/403/404 as terminal, include `ClientID` + `ClientSecret` when renaming an existing node, and persist only newly generated secrets or DB settings.
|
||||
- Registry & DTOs: use the client-backed registry (`NewClientRegistryWithConfig`)—the file-backed version is legacy—and treat migration as complete only after swapping callsites, building, and running focused API/CLI tests. Nodes are keyed by UUID v7 (`/api/v1/cluster/nodes/{uuid}`), the registry interface stays UUID-first (`Get`, `FindByNodeUUID`, `FindByClientID`, `RotateSecret`, `DeleteAllByUUID`), CLI lookups resolve `uuid → ClientID → name`, and DTOs normalize `Database.{Name,User,Driver,RotatedAt}` while exposing `ClientSecret` only during creation/rotation. `nodes rm --all-ids` cleans duplicate client rows, admin responses may include `AdvertiseUrl`/`Database`, client/user sessions stay redacted, registry files live under `conf.PortalConfigPath()/nodes/` (mode 0600), and `ClientData` no longer stores `NodeUUID`.
|
||||
- Provisioner & DSN: database/user names use UUID-based HMACs (`photoprism_d<hmac11>`, `photoprism_u<hmac11>`); `BuildDSN` accepts a `driver` but falls back to MySQL format with a warning when unsupported.
|
||||
|
||||
10
CODEMAP.md
10
CODEMAP.md
@@ -40,7 +40,7 @@ High-Level Package Map (Go)
|
||||
- `internal/service` — cluster/portal, maps, hub, webdav
|
||||
- `internal/event` — logging, pub/sub, audit
|
||||
- `internal/ffmpeg`, `internal/thumb`, `internal/meta`, `internal/form`, `internal/mutex` — media, thumbs, metadata, forms, coordination
|
||||
- `pkg/*` — reusable utilities (must never import from `internal/*`), e.g. `pkg/clean`, `pkg/enum`, `pkg/fs`, `pkg/txt`, `pkg/service/http/header`
|
||||
- `pkg/*` — reusable utilities (must never import from `internal/*`), e.g. `pkg/clean`, `pkg/enum`, `pkg/fs`, `pkg/txt`, `pkg/http/header`
|
||||
|
||||
Templates & Static Assets
|
||||
- Entry HTML lives in `assets/templates/index.gohtml`, which includes the splash markup from `app.gohtml` and the SPA loader from `app.js.gohtml`.
|
||||
@@ -109,7 +109,7 @@ Cluster / Portal
|
||||
|
||||
Logging & Events
|
||||
- Logger and event hub: `internal/event/*`; `event.Log` is the shared logger.
|
||||
- HTTP headers/constants: `pkg/service/http/header/*` — always prefer these in handlers and tests.
|
||||
- HTTP headers/constants: `pkg/http/header/*` — always prefer these in handlers and tests.
|
||||
|
||||
Server Startup Flow (happy path)
|
||||
1) `photoprism start` (CLI) → `internal/commands/start.go`
|
||||
@@ -170,7 +170,7 @@ Security & Hot Spots (Where to Look)
|
||||
- Sizes & names: `internal/thumb/sizes.go`, `internal/thumb/names.go`, `internal/thumb/filter.go`; face/marker crop helpers live in `internal/thumb/crop` (e.g., `ParseThumb`, `IsCroppedThumb`).
|
||||
|
||||
- Safe HTTP downloader:
|
||||
- Shared utility: `pkg/service/http/safe` (`Download`, `Options`).
|
||||
- Shared utility: `pkg/http/safe` (`Download`, `Options`).
|
||||
- Protections: scheme allow‑list (http/https), pre‑DNS + per‑redirect hostname/IP validation, final peer IP check, size and timeout enforcement, temp file `0600` + rename.
|
||||
- Avatars: wrapper `internal/thumb/avatar.SafeDownload` applies stricter defaults (15s, 10 MiB, `AllowPrivate=false`, image‑focused `Accept`).
|
||||
- Tests: `go test ./pkg/http/safe -count=1` (includes redirect SSRF cases); avatars: `go test ./internal/thumb/avatar -count=1`.
|
||||
@@ -181,7 +181,7 @@ Performance & Limits
|
||||
|
||||
Conventions & Rules of Thumb
|
||||
- Respect package boundaries: code in `pkg/*` must not import `internal/*`.
|
||||
- Prefer constants/helpers from `pkg/service/http/header` over string literals.
|
||||
- Prefer constants/helpers from `pkg/http/header` over string literals.
|
||||
- Never log secrets; compare tokens constant‑time.
|
||||
- Don’t import Portal internals from cluster instance/service bootstraps; use HTTP.
|
||||
- Prefer small, hermetic unit tests; isolate filesystem paths with `t.TempDir()` and env like `PHOTOPRISM_STORAGE_PATH`.
|
||||
@@ -222,7 +222,7 @@ Frequently Touched Files (by topic)
|
||||
- Cluster: `internal/service/cluster/*`
|
||||
- Theme support: `internal/service/cluster/theme/version.go` exposes `DetectVersion`, used by bootstrap, CLI, and API handlers to compare portal vs node theme revisions (prefers `fs.VersionTxtFile`, falls back to `app.js` mtime).
|
||||
- Registration sanitizes `AppName`, `AppVersion`, and `Theme` with `clean.TypeUnicode`; defaults for app metadata come from `config.About()` / `config.Version()`. `cluster.RegisterResponse` now includes a `Theme` hint when the portal has a newer bundle so nodes can decide whether to download immediately.
|
||||
- Headers: `pkg/service/http/header/*`
|
||||
- Headers: `pkg/http/header/*`
|
||||
|
||||
Downloads (CLI) & yt-dlp helpers
|
||||
- CLI command & core:
|
||||
|
||||
@@ -39,7 +39,7 @@ The API package exposes PhotoPrism’s HTTP endpoints via Gin handlers. Each fil
|
||||
## Testing Strategy
|
||||
|
||||
- Build tests around the API harness (`NewApiTest`) to obtain a configured Gin router, config, and dependencies. This isolates filesystem paths and avoids polluting global state.
|
||||
- Wrap requests with helper functions (for example, `PerformRequestJSON`, `PerformAuthenticatedRequest`) to capture status codes, headers, and payloads. Assert headers using constants from `pkg/service/http/header`.
|
||||
- Wrap requests with helper functions (for example, `PerformRequestJSON`, `PerformAuthenticatedRequest`) to capture status codes, headers, and payloads. Assert headers using constants from `pkg/http/header`.
|
||||
- When handlers interact with the database, initialize fixtures through config helpers such as `config.NewTestConfig("api")` or `config.NewMinimalTestConfigWithDb("api", t.TempDir())` depending on fixture needs.
|
||||
- Stub external dependencies (`httptest.Server`) for remote calls and set `AllowPrivate=true` explicitly when the test server binds to loopback addresses.
|
||||
- Structure tests with table-driven subtests (`t.Run("CaseName", ...)`) and use PascalCase names. Provide cleanup functions (`t.Cleanup`) to remove temporary files or databases created during tests.
|
||||
|
||||
@@ -18,7 +18,7 @@ The `commands` package hosts the CLI implementation for the PhotoPrism binary. C
|
||||
- Follow the overwrite policy used by media helpers: require explicit confirmation (`force` flags) before replacing non-empty files. Where replacements are expected, open destinations with `O_WRONLY|O_CREATE|O_TRUNC`.
|
||||
- Use shared logging through `event.Log` rather than direct `fmt` printing. Sensitive information such as secrets or tokens must never be logged.
|
||||
- When integrating configuration options, call the accessors on `*config.Config` (for example, `conf.ClusterUUID()`) rather than mutating option structs directly.
|
||||
- For HTTP interactions, depend on the safe download helpers in `pkg/service/http/safe` or the specialized wrappers in `internal/thumb/avatar` to inherit timeout, size, and SSRF protection defaults.
|
||||
- For HTTP interactions, depend on the safe download helpers in `pkg/http/safe` or the specialized wrappers in `internal/thumb/avatar` to inherit timeout, size, and SSRF protection defaults.
|
||||
|
||||
## Configuration & Flags Integration
|
||||
|
||||
@@ -48,7 +48,7 @@ The `commands` package hosts the CLI implementation for the PhotoPrism binary. C
|
||||
|
||||
- Stub external binaries such as `yt-dlp` with lightweight shell scripts that honor `--dump-single-json` and `--print` requests. Support environment variables like `YTDLP_ARGS_LOG`, `YTDLP_OUTPUT_FILE`, and `YTDLP_DUMMY_CONTENT` to capture arguments, create deterministic artifacts, and avoid duplicate detection in importer flows.
|
||||
- Disable FFmpeg during tests that focus on command construction by setting `conf.Options().FFmpegBin = "/bin/false"` and `conf.Settings().Index.Convert = false`.
|
||||
- When asserting HTTP responses, rely on header constants from `pkg/service/http/header` (for example, `header.ContentTypeZip`) to keep expectations aligned with middleware.
|
||||
- When asserting HTTP responses, rely on header constants from `pkg/http/header` (for example, `header.ContentTypeZip`) to keep expectations aligned with middleware.
|
||||
- For role and scope checks, reuse helpers in `internal/auth/acl` such as `acl.ParseRole`, `acl.ScopePermits`, and `acl.ScopeAttrPermits` instead of duplicating logic inside commands.
|
||||
|
||||
## Preflight Checklist
|
||||
|
||||
Reference in New Issue
Block a user