Merge pull request !2791 from rhodecode-enterprise-ce feature/RCCE-259_Additional-check-for-service_api.token

feature: moves logic of dumping default values to ini file
This commit is contained in:
Andrii Verbytskyi 2025-08-08 09:19:35 +00:00
commit 71e102275d
4 changed files with 47 additions and 38 deletions

View file

@ -22,40 +22,12 @@ import logging
from pyramid.settings import asbool
from rhodecode.config.settings_maker import SettingsMaker
from rhodecode.config.settings_maker import SettingsMaker, generate_token
from rhodecode.config import utils as config_utils
log = logging.getLogger(__name__)
def initialize_ini_config_default_values_if_not_present(ini_path: str):
from configupdater import ConfigUpdater # use configupdater to not break comments and formatting's
def dump_config():
with open(ini_path, "w") as configfile:
updater.write(configfile)
if not ini_path or not os.path.exists(ini_path):
log.warning("Config file %s not found.", ini_path)
return
updater = ConfigUpdater()
updater.read(ini_path)
section = "app:main"
option = "app.service_api.token"
if not updater[section][option].value.strip():
updater[section][option] = generate_token()
dump_config()
def generate_token(length: int = 32) -> str:
import secrets
return secrets.token_urlsafe(length)
def sanitize_settings_and_apply_defaults(global_config, settings):
"""
Applies settings defaults and does all type conversion.
@ -184,8 +156,8 @@ def sanitize_settings_and_apply_defaults(global_config, settings):
settings_maker.make_setting(
"exception_tracker.store_path",
default=jn(default_cache_dir, "exc_store"),
default_when_empty=True,
parser="dir:ensured",
default_when_empty=True,
)
settings_maker.make_setting(
@ -283,11 +255,11 @@ def sanitize_settings_and_apply_defaults(global_config, settings):
settings_maker.make_setting("archive_cache.objectstore.retry_backoff", 1, parser="int")
settings_maker.make_setting("archive_cache.objectstore.retry_attempts", 10, parser="int")
settings_maker.make_setting("app.service_api.token", generate_token(), parser="string", write_default_to_ini=True)
settings_maker.env_expand()
# configure instance id
config_utils.set_instance_id(settings)
initialize_ini_config_default_values_if_not_present(global_config.get("__file__"))
return settings

View file

@ -33,6 +33,33 @@ log = logging.getLogger(__name__)
set_keys = {"__file__": ""}
def initialize_ini_config_default_values_if_not_present(
ini_path: str, option: str, default_val: object, section: str = "app:main"
):
from configupdater import ConfigUpdater # use configupdater to not break comments and formatting's
def dump_config():
with open(ini_path, "w") as configfile:
updater.write(configfile)
if not ini_path or not os.path.exists(ini_path):
log.warning("Config file %s not found.", ini_path)
return
updater = ConfigUpdater()
updater.read(ini_path)
if option not in updater[section] or not updater[section][option].value.strip():
updater[section][option] = default_val
dump_config()
def generate_token(length: int = 32) -> str:
import secrets
return secrets.token_urlsafe(length)
class SettingsMaker:
def __init__(self, app_settings):
self.settings = app_settings
@ -154,9 +181,16 @@ class SettingsMaker:
logging.config.fileConfig(f.name)
os.remove(f.name)
def make_setting(self, key, default, lower=False, default_when_empty=False, parser=None):
def make_setting(
self, key, default, lower=False, default_when_empty=False, parser=None, write_default_to_ini=False
):
input_val = self.settings.get(key, default)
if write_default_to_ini:
initialize_ini_config_default_values_if_not_present(
ini_path=self.settings.get("__file__"), option=key, default_val=default
)
if default_when_empty and not input_val:
# use default value when value is set in the config but it is empty
input_val = default

View file

@ -19,7 +19,7 @@
import time
import logging
from rhodecode.config.config_maker import initialize_ini_config_default_values_if_not_present
from rhodecode.config.settings_maker import initialize_ini_config_default_values_if_not_present, generate_token
from rhodecode.lib.config_utils import get_app_config_lightweight
from rhodecode.lib.hook_daemon.base import Hooks
@ -34,7 +34,9 @@ def prepare_callback_daemon(extras, protocol: str, txn_id=None):
hooks_config = {}
match protocol:
case "celery":
initialize_ini_config_default_values_if_not_present(extras["config"])
initialize_ini_config_default_values_if_not_present(
ini_path=extras["config"], option="app.service_api.token", default_val=generate_token()
)
config = get_app_config_lightweight(extras["config"])
broker_url = config.get("celery.broker_url")

View file

@ -21,19 +21,20 @@ import os
from pyramid.paster import bootstrap as pyramid_bootstrap, setup_logging # pragma: no cover
from pyramid.threadlocal import get_current_request as pyramid_current_request
from rhodecode.config.config_maker import initialize_ini_config_default_values_if_not_present
def bootstrap(config_uri, options=None, env=None):
from rhodecode.config.utils import DEFAULT_USER
from rhodecode.lib.config_utils import get_app_config_lightweight
from rhodecode.lib.utils2 import AttributeDict
from rhodecode.lib.request import Request
from rhodecode.config.settings_maker import initialize_ini_config_default_values_if_not_present, generate_token
if env:
os.environ.update(env)
initialize_ini_config_default_values_if_not_present(config_uri)
initialize_ini_config_default_values_if_not_present(
ini_path=config_uri, option="app.service_api.token", default_val=generate_token()
)
config = get_app_config_lightweight(config_uri)
base_url = config["app.base_url"]