Skip to content

Commit c65ea2f

Browse files
committed
Fix cached random tokens potentially not persisting on first start.
The "var/run" directory was not being created prior to the random tokens being trying to be written. So if this directory didn't already exist (on initial startup), this could lead to the random tokens changing on subsequent runs. To fix this, ensure the directory exists, but also better optimize this process so new tokens are only generated if needed, and the file is only written if needed (rather than rewriting it on every startup).
1 parent a0dbf8c commit c65ea2f

File tree

1 file changed

+44
-37
lines changed

1 file changed

+44
-37
lines changed

src/api-umbrella/cli/read_config.lua

Lines changed: 44 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -114,41 +114,6 @@ local function read_default_config()
114114
nillify_yaml_nulls(config)
115115
end
116116

117-
-- Handle setup of random secret tokens that should be be unique for API
118-
-- Umbrella installations, but should be persisted across restarts.
119-
--
120-
-- In a multi-server setup, these secret tokens will likely need to be
121-
-- explicitly given in the server's /etc/api-umbrella/api-umbrella.yml file so
122-
-- the secrets match across servers, but this provides defaults for a
123-
-- single-server installation.
124-
local function set_cached_random_tokens()
125-
-- Generate random tokens for this server.
126-
local cached = {
127-
web = {
128-
rails_secret_token = random_token(128),
129-
},
130-
static_site = {
131-
api_key = random_token(40),
132-
},
133-
}
134-
135-
-- See if there were any previous values for these random tokens on this
136-
-- server. If so, use any of those values that might be present instead.
137-
local file_path = path.join(os.getenv("API_UMBRELLA_ROOT") or "/opt/api-umbrella", "var/run/cached_random_config_values.yml")
138-
local content = file.read(file_path, true)
139-
if content then
140-
deep_merge_overwrite_arrays(cached, lyaml.load(content))
141-
end
142-
143-
-- Persist whatever the state of the tokens is now.
144-
file.write(file_path, lyaml.dump({cached}))
145-
146-
-- Merge these random tokens onto the config. Note that this happens before
147-
-- we read the system config (/etc/api-umbrella/api-umbrella.yml), so if
148-
-- these values are defined there, these random values will be overwritten.
149-
deep_merge_overwrite_arrays(config, cached)
150-
end
151-
152117
-- Read the /etc/api-umbrella/api-umbrella.yml config file that provides
153118
-- server-specific overrides for API Umbrella configuration.
154119
local function read_system_config()
@@ -393,14 +358,56 @@ local function set_computed_config()
393358
end
394359
end
395360

361+
-- Handle setup of random secret tokens that should be be unique for API
362+
-- Umbrella installations, but should be persisted across restarts.
363+
--
364+
-- In a multi-server setup, these secret tokens will likely need to be
365+
-- explicitly given in the server's /etc/api-umbrella/api-umbrella.yml file so
366+
-- the secrets match across servers, but this provides defaults for a
367+
-- single-server installation.
368+
local function set_cached_random_tokens()
369+
-- Only generate new new tokens if they haven't been explicitly set in the
370+
-- config files.
371+
if not config["web"]["rails_secret_token"] or not config["static_site"]["api_key"] then
372+
-- See if there were any previous values for these random tokens on this
373+
-- server. If so, use any of those values that might be present instead.
374+
local cached_path = path.join(config["run_dir"], "cached_random_config_values.yml")
375+
local content = file.read(cached_path, true)
376+
local cached = {}
377+
if content then
378+
cached = lyaml.load(content)
379+
deep_merge_overwrite_arrays(config, cached)
380+
end
381+
382+
-- If the tokens haven't already been written to the cache, generate them.
383+
if not config["web"]["rails_secret_token"] or not config["static_site"]["api_key"] then
384+
if not config["web"]["rails_secret_token"] then
385+
cached["web"]["rails_secret_token"] = random_token(128)
386+
end
387+
388+
if not config["static_site"]["api_key"] then
389+
cached["static_site"] = {
390+
api_key = random_token(40),
391+
}
392+
end
393+
394+
-- Persist the cached tokens.
395+
dir.makepath(config["run_dir"])
396+
file.write(cached_path, lyaml.dump({ cached }))
397+
398+
deep_merge_overwrite_arrays(config, cached)
399+
end
400+
end
401+
end
402+
396403
-- Write out the combined and merged config to the runtime file.
397404
--
398405
-- This runtime config reflects the full state of the available config and can
399406
-- be used by other API Umbrella processes for reading the config (without
400407
-- having to actually merge and combine again).
401408
local function write_runtime_config()
402409
local runtime_config_path = path.join(config["run_dir"], "runtime_config.yml")
403-
dir.makepath(path.dirname(runtime_config_path))
410+
dir.makepath(config["run_dir"])
404411
file.write(runtime_config_path, lyaml.dump({config}))
405412
end
406413

@@ -416,9 +423,9 @@ return function(options)
416423
-- writing the runtime config.
417424
if not config or (options and options["write"]) then
418425
read_default_config()
419-
set_cached_random_tokens()
420426
read_system_config()
421427
set_computed_config()
428+
set_cached_random_tokens()
422429

423430
if options and options["write"] then
424431
write_runtime_config()

0 commit comments

Comments
 (0)