# photos A photo bucket management suite. ## Bucket Format - `photo/[filename]` - Original photo. Name conflict resolution (excluding extension) must be handled client-side. - `preview/[filename]_h[height]q[quality].[format]` - Preview photos at lower resolutions and quality. - Generator: preview - `photometadata/[filename]/size` - Original photo size, JSON - Generator: preview - `photometadata/[filename]/date` - Original photo date taken, unix timestamp - Generator: preview - `photometadata/[filename]/title` - Photo title - `photometadata/[filename]/tags` - Photo tags - `metadata/title` - Photo album title - `metadata/description` - Photo album description, markdown - `metadata/ordering` - Manual sort ordering, newline separated - `internal/control` - Access control settings, JSON ## `admin` - Standalone tool to manage an S3-like account - In-browser handling of: - ListBuckets - MakeBucket - RemoveBucket - Setup photo bucket - Uploads initial metadata - SetBucketPolicy that matches - Adds credentials to database. - Disconnect photo bucket - Removes credentials from database ### Operations #### `PUT /credential?bucket=BUCKET` 1. Ensure credentials work on BUCKET 2. Write credentials to KV store #### `DELETE /credential?bucket=BUCKET` 1. Ensure credentials work on BUCKET 2. Write credentials to KV store ### Data Credentials must be passed as: ``` { "access_key": string, "secret_key": string, "region": string } ``` ## `control` Implement access controls by signing requests, using credentials in database. ### Operations #### `GET /sign?bucket=BUCKET&token=TOKEN&request=REQUEST` 1. Consult the bucket for `metadata/control` with credentials 2. Get read access method for the bucket 3. Validate the token against the access method 4. Validate REQUEST is an acceptable request - ListObjectsV2, GetObject - Not `internal/` 5. If necessary, presign an object URL for 4 days - Cache presigned URLs for 2 days in memory/Redis 6. 307 redirect to presigned URL #### `PUT /sign?bucket=BUCKET&token=TOKEN&request=REQUEST` 1. Consult the bucket for `metadata/control` with credentials 2. Get write access method for the bucket 3. Validate the token against the access method 4. Validate REQUEST is an acceptable request - PutObject - Not `internal/` 5. If necessary, presign an object URL for 30 minutes 6. 307 redirect to presigned URL #### `DELETE /sign?bucket=BUCKET&token=TOKEN&request=REQUEST` 1. Consult the bucket for `metadata/control` with credentials 2. Get write access method for the bucket 3. Validate the token against the access method 4. Validate REQUEST is an acceptable request - RemoveObject - Not `internal/` 5. If necessary, presign an object URL for 30 minutes 6. 307 redirect to presigned URL ### Authentication #### Token The read/write token is checked against a simple string defined in the bucket. #### OpenID Connect Recommended IDP: [dex](https://github.com/dexidp/dex) The read/write operation is gated by a signed key corresponding to allowed users defined in the bucket. ## `web` Generates the web interface for a photo bucket. Also serves up the shared assets. ### Operations #### `POST /update?bucket=BUCKET` Regenerate and upload `index.html` and `manage/index.html` to bucket. ## `preview` Generate previews from photo buckets. ### Operations #### `POST /update?bucket=BUCKET&photo=OBJECT` 1. Perform preview generation using libvips (maybe limit?) 2. Block until done ## `proxy` Reverse proxies buckets to the MinIO endpoint, as a substitute for AWS S3 website hosting features. Serves up `index.html` when URLs end in a slash. In production, [replace this with Nginx](https://docs.min.io/docs/setup-nginx-proxy-with-minio).