Skip to content

fix: overall cleanup of the docs, CI, docker images and several bugs - #1833

Draft
fclairamb wants to merge 4 commits into
mainfrom
chore/cleanup
Draft

fclairamb wants to merge 4 commits into
mainfrom
chore/cleanup

Conversation

@fclairamb

Copy link
Copy Markdown
Owner

An overall cleanup, starting with the README. Along the way I found and fixed a few real bugs. They're split into three commits (fixes, CI, docs) to make review easier.

Bug fixes

  • keycloak: concurrent logins could share credentials. GetAccess wrote each user's name and password into the shared keycloak access. With two logins at the same time, one user could get the other user's credentials and land in their directory. A new test (TestGetAccessKeycloakDoesNotShareState) reproduces the data race on the old code. The fix also:
    • rejects user names that would escape base_path
    • accepts KEYCLOAK_CLIENT_SECRET (the misspelled KEYCLAOK_CLIENT_SECRET still works)
  • webhook: logins always failed without a timeout. An unset timeout gave the request a deadline of 0, so every login timed out. It now defaults to 30s, and the response size is capped.
  • max_clients was documented but never enforced. It is now.
  • gcs: the bucket parameter was ignored. gcsfs treats the first path component as the bucket, so the FTP root couldn't be listed. Each access is now scoped to its bucket.
  • s3: endpoints without a scheme got the wrong one. The old check treated any endpoint starting with "h" (e.g. host.example.com) as already having a scheme. Endpoints without one now get http:// or https:// depending on disable_ssl.
  • main: startup failures exited with status 0. A bad config or a busy port now exits with 1. A failed listen also no longer waits a minute before exiting.
  • TLS: a missing key file was reported as a cert file error, with the wrong error.
  • config:
    • hashing plain-text passwords rewrote the file with 0644 permissions; it now keeps the original ones
    • plain-text passwords are compared in constant time
    • the 8 copies of the hash-checking code are replaced by one helper
  • server:
    • fixed a data race in WaitGracefully
    • shared file systems are dropped on SIGHUP so they pick up the new config
  • mail: the shipped example couldn't load. SSL, StartTLSPolicy and Port were mandatory, and the example wasn't valid JSON. They're now optional with sensible defaults.

CI

  • Lint never ran. It depended on an undefined matrix.lint, and .golangci.yml used the v1 format, which golangci-lint v2 rejects. It's migrated to a v2 config with a reasonable set of linters, and the code passes it.
  • Removed the apt-get install gcc step: it fails every run (no root) and only passed because gcc is already on the runner.
  • CodeQL only ran on its weekly schedule: its push and pull request triggers targeted master. They now target main.
  • Docker images haven't been published since v0.15.1. On Docker Hub, latest dates from 2023. Release-please tags don't trigger workflows (same cause as 最新版还是没有二进制文件下载 #1738), and the QEMU builds were slow and failing. The images are now:
    • built from release-please (like the binaries)
    • cross-compiled instead of emulated
    • given their version info through build args, which replaces the ci-info / build.go.tpl templating
    • built on PRs that touch them (without pushing)
  • The daily docker test fails because placekitten.com is gone. It now uses a random file, tests both images, and builds them locally on PRs.
  • The scratch image now includes /tmp, which the default config serves.
  • The JSON schema rejected valid configs: it was missing tls_required, extensions, accesses_webhook and per-access logging. Those are added, and the backend examples are now validated too.

Docs

  • README rewritten:
    • working badges and a table of all backends
    • the command line and signals
    • every config option, password hashing, webhook auth, and the docker tags
    • a valid sample config
  • Backend docs fixed:
    • Dropbox (it was a copy of the Google Drive doc)
    • gdrive (base_path, not basePath)
    • GCS
  • New docs for keycloak, SFTP and mail.
  • fs/README.md samples are now valid JSON.
  • Updated CONTRIBUTING and CLAUDE.md.

Testing

  • go test -race ./...: new tests for password checking/hashing, keycloak isolation, the webhook, max_clients and S3 endpoints.
  • golangci-lint run (v2.15.0): 0 issues. actionlint: clean, apart from not knowing the ubuntu-26.04 runner label.
  • Cross-builds for linux amd64/arm64/armv6/armv7, darwin and windows.
  • Every JSON sample and doc snippet is validated against the schema.
  • Manual smoke test: upload and download, wrong-password rejection, SIGHUP reload, graceful SIGTERM, exit codes.
  • Docker builds weren't run locally (no daemon). This PR touches the Dockerfiles, so the docker and docker-test workflows will run on it.

🤖 Generated with Claude Code

fclairamb and others added 4 commits October 22, 2026 07:57
- keycloak: work on a copy of the shared access instead of writing each user's
  credentials into it (concurrent logins could end up in another user's
  directory), reject user names that would escape base_path, accept the
  KEYCLOAK_CLIENT_SECRET env var (KEYCLAOK_CLIENT_SECRET still works)
- config: deduplicate the password hash handling, compare plain-text passwords
  in constant time, keep the config file permissions when hashing passwords and
  don't hash keycloak accesses
- server: enforce max_clients, default the accesses webhook timeout to 30s (an
  unset timeout made every login fail), limit the webhook response size, report
  the right file when the TLS key can't be read, drop shared file systems on
  config reload, fix a data race in WaitGracefully
- main: exit with a non-zero status on startup errors, don't wait a minute when
  the server couldn't listen
- s3: add the right scheme to endpoints without one (hosts starting with an
  "h" were considered to already have one)
- gcs: restrict the access to the configured bucket, which was ignored
- mail: SSL, StartTLSPolicy and Port are now optional

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- build: golangci-lint never ran (it depended on an undefined matrix value) and
  its config was in the v1 format rejected by golangci-lint v2: migrate it to a
  v2 config, run it after setting up go, and drop the apt-get call that always
  failed (gcc is already installed on the runners)
- codeql: analyze pushes and pull requests on main instead of master
- docker: cross-compile the binary instead of building it under QEMU, publish
  the images from release-please (tags pushed with the default GITHUB_TOKEN
  don't trigger workflows, images weren't published since v0.15.1), pass the
  version info as build args instead of templating build.go with ci-info, and
  build the images on pull requests touching them
- docker test: placekitten.com is gone, use a random file, test both images,
  and build them locally on pull requests touching them
- scratch image: provide the /tmp directory served by the default config
- schema: document tls_required, extensions, accesses_webhook and the access
  logging options, which were rejected by the schema, and validate the
  backend examples too (the mail one wasn't valid JSON)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- README: fix the badges (some workflows didn't exist anymore), list every
  backend with its documentation, document the command line, the signals, all
  the config options, password hashing, webhook authentication and the docker
  image tags, use a valid sample config, and replace the dead placekitten.com
  test file
- dropbox: the documentation was a copy of the Google Drive one
- gdrive: the base path parameter is base_path, not basePath
- keycloak, sftp, mail: write a proper documentation
- gcs: document the bucket as the root directory, project_id is unused
- fs: the samples weren't valid JSON, explain what each option does
- CONTRIBUTING, CLAUDE.md: development workflow and conventions

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
To be removed before merging.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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