mirror of
https://github.com/zulip/zulip.git
synced 2025-11-02 21:13:36 +00:00
scripts: Make generate_secrets.py idempotent.
Now, generate_secrets.py will never overwrite existing secrets. In addition to being a safer model in generate, this fixes 2 significant issues: (1) It makes it much easier to preserve secrets like Oauth tokens in a development environment (previously, provision would destroy them). (2) It makes it possible to automatically add new secrets as part of the upgrade process. In particular, this is useful for the zulip_org_id settings. Fixes #4797.
This commit is contained in:
@@ -61,14 +61,7 @@ def get_old_conf(output_filename):
|
||||
secrets_file = six.moves.configparser.RawConfigParser() # type: ignore # https://github.com/python/typeshed/issues/307
|
||||
secrets_file.read(output_filename)
|
||||
|
||||
def get_secret(key):
|
||||
# type: (str) -> Optional[Text]
|
||||
if secrets_file.has_option('secrets', key):
|
||||
return secrets_file.get('secrets', key)
|
||||
return None
|
||||
|
||||
fields = AUTOGENERATED_SETTINGS + ['secret_key', 'camo_key']
|
||||
return {name: get_secret(name) for name in fields}
|
||||
return dict(secrets_file.items("secrets"))
|
||||
|
||||
def generate_secrets(development=False):
|
||||
# type: (bool) -> None
|
||||
@@ -76,38 +69,49 @@ def generate_secrets(development=False):
|
||||
OUTPUT_SETTINGS_FILENAME = "zproject/dev-secrets.conf"
|
||||
else:
|
||||
OUTPUT_SETTINGS_FILENAME = "/etc/zulip/zulip-secrets.conf"
|
||||
current_conf = get_old_conf(OUTPUT_SETTINGS_FILENAME)
|
||||
|
||||
lines = [u'[secrets]\n']
|
||||
lines = []
|
||||
if len(current_conf) == 0:
|
||||
lines = [u'[secrets]\n']
|
||||
|
||||
def config_line(var, value):
|
||||
# type: (Text, Text) -> Text
|
||||
return "%s = %s\n" % (var, value)
|
||||
def need_secret(name):
|
||||
# type: (Text) -> bool
|
||||
return name not in current_conf
|
||||
|
||||
def add_secret(name, value):
|
||||
# type: (Text, Text) -> None
|
||||
lines.append("%s = %s\n" % (name, value))
|
||||
current_conf[name] = value
|
||||
|
||||
old_conf = get_old_conf(OUTPUT_SETTINGS_FILENAME)
|
||||
for name in AUTOGENERATED_SETTINGS:
|
||||
lines.append(config_line(name, old_conf.get(name, generate_random_token(64))))
|
||||
if need_secret(name):
|
||||
add_secret(name, generate_random_token(64))
|
||||
|
||||
secret_key = old_conf.get('secret_key', generate_django_secretkey())
|
||||
lines.append(config_line('secret_key', secret_key))
|
||||
if need_secret('secret_key'):
|
||||
add_secret('secret_key', generate_django_secretkey())
|
||||
|
||||
camo_key = old_conf.get('camo_key', get_random_string(64))
|
||||
lines.append(config_line('camo_key', camo_key))
|
||||
if need_secret('camo_key'):
|
||||
add_secret('camo_key', get_random_string(64))
|
||||
|
||||
zulip_org_key = old_conf.get('zulip_org_key', get_random_string(64))
|
||||
lines.append(config_line('zulip_org_key', zulip_org_key))
|
||||
|
||||
zulip_org_id = old_conf.get('zulip_org_id', str(uuid.uuid4()))
|
||||
lines.append(config_line('zulip_org_id', zulip_org_id))
|
||||
if need_secret('zulip_org_key'):
|
||||
add_secret('zulip_org_key', get_random_string(64))
|
||||
if need_secret('zulip_org_id'):
|
||||
add_secret('zulip_org_id', str(uuid.uuid4()))
|
||||
|
||||
if not development:
|
||||
# Write the Camo config file directly
|
||||
generate_camo_config_file(camo_key)
|
||||
generate_camo_config_file(current_conf['camo_key'])
|
||||
|
||||
out = open(OUTPUT_SETTINGS_FILENAME, 'w')
|
||||
if len(lines) == 0:
|
||||
print("generate_secrets: No new secrets to generate.")
|
||||
return
|
||||
|
||||
out = open(OUTPUT_SETTINGS_FILENAME, 'a')
|
||||
out.write(force_str("".join(lines)))
|
||||
out.close()
|
||||
|
||||
print("Generated %s with auto-generated secrets!" % (OUTPUT_SETTINGS_FILENAME,))
|
||||
print("Generated new secrets in %s." % (OUTPUT_SETTINGS_FILENAME,))
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
|
||||
Reference in New Issue
Block a user