mirror of
https://github.com/penpot/penpot.git
synced 2026-11-05 17:40:39 +00:00
🔧 Normalize the tenant to lowercase (#12843)
An operator writing `PENPOT_TENANT=ACME` and one writing `acme` name the same tenant: the value is compared as an exact string in the keys and rows it lands in, and one uppercase letter would otherwise split one tenant into two. The value is normalized when the configuration is read, so nothing downstream has to care about case, and the validated form accepts only lowercase labels from then on. AI-assisted-by: deepseek-v4.1-flash
This commit is contained in:
parent
eb9594a614
commit
9d898b8b31
@ -111,8 +111,14 @@
|
||||
:ssrf-extra-blocked-cidrs #{}})
|
||||
|
||||
(def schema:tenant
|
||||
"Tenant identifier: hostname-label-style (letters, digits and
|
||||
hyphens). It is interpolated into Redis keys separated by dots (msgbus
|
||||
"Tenant identifier: hostname-label-style, lowercase (letters, digits
|
||||
and hyphens). The value is normalized to lowercase when the
|
||||
configuration is read, so an operator writing `PENPOT_TENANT=ACME` and
|
||||
one writing `acme` name the same tenant: the value is compared as an
|
||||
exact string in the keys and rows it lands in, and one uppercase
|
||||
letter would otherwise split one tenant into two.
|
||||
|
||||
It is interpolated into Redis keys separated by dots (msgbus
|
||||
topics, rate-limit buckets, exporter job keys, which are also matched
|
||||
with a glob pattern), so `.` and whitespace are rejected at startup
|
||||
because one tenant would then be able to read or overwrite another's
|
||||
@ -125,7 +131,14 @@
|
||||
tenant asking for it, and a tenant that has one would have to be
|
||||
renamed. Tenants using those characters must be renamed before
|
||||
upgrading."
|
||||
[:re #"^[A-Za-z0-9-]+$"])
|
||||
[:re #"^[a-z0-9-]+$"])
|
||||
|
||||
(defn- normalize-tenant
|
||||
"Lowercase the configured tenant before it is validated, so
|
||||
`PENPOT_TENANT=ACME` and `acme` mean the same tenant everywhere."
|
||||
[config]
|
||||
(cond-> config
|
||||
(string? (:tenant config)) (update :tenant str/lower)))
|
||||
|
||||
(def schema:config
|
||||
(do #_sm/optional-keys
|
||||
@ -401,6 +414,7 @@
|
||||
[& {:keys [prefix default] :or {prefix "penpot"}}]
|
||||
(->> (read-env prefix)
|
||||
(merge default)
|
||||
(normalize-tenant)
|
||||
(decode-config)))
|
||||
|
||||
(def version
|
||||
|
||||
@ -6,10 +6,21 @@
|
||||
|
||||
(ns backend-tests.config-test
|
||||
(:require
|
||||
[app.common.schema :as sm]
|
||||
[app.common.time :as ct]
|
||||
[app.config :as cf]
|
||||
[clojure.test :as t]))
|
||||
|
||||
(t/deftest tenant-is-normalized-to-lowercase
|
||||
(t/testing "an uppercase tenant names the same tenant"
|
||||
(t/is (= "acme" (:tenant (#'cf/normalize-tenant {:tenant "ACME"}))))
|
||||
(t/is (= "acme" (:tenant (#'cf/normalize-tenant {:tenant "acme"})))))
|
||||
(t/testing "a config without a tenant is left untouched"
|
||||
(t/is (= {:x 1} (#'cf/normalize-tenant {:x 1}))))
|
||||
(t/testing "the validated form is lowercase-only"
|
||||
(t/is (not (sm/validate cf/schema:tenant "ACME")))
|
||||
(t/is (sm/validate cf/schema:tenant "acme"))))
|
||||
|
||||
(t/deftest get-public-uri-normalizes-base
|
||||
(t/testing "trailing slash is ensured with and without subpath"
|
||||
(doseq [[base expected] [["http://localhost:3449" "http://localhost:3449/"]
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user