the-custodian/docs/changes/netkingdom-target-2026-10-17/apps-chart-projection-r1/apps-source.patch

96 lines
4 KiB
Diff
Raw Normal View History

--- a/helm/forgejo-values.yaml
+++ b/helm/forgejo-values.yaml
@@ -122,6 +122,9 @@
DISABLE_SSH: false
service:
DISABLE_REGISTRATION: true
+ oauth2_client:
+ ENABLE_AUTO_REGISTRATION: false
+ ACCOUNT_LINKING: login
security:
INSTALL_LOCK: true
session:
--- /dev/null
+++ b/tools/forgejo_chart_projection.py
@@ -0,0 +1,80 @@
+"""Public source preparation only. No I/O, native tools, credentials or dispatch.
+
+The actual three-group case is refused on Forgejo 11.0.3. A single-group test
+control proves the real chart secret-reference seam, never case admission.
+"""
+from copy import deepcopy
+import hashlib
+import re
+import yaml
+
+APPS = '944b30ad63ab054cc24617e374e177d34cd572da'
+BASE_SHA256 = 'cf87a3dccd666bf8870619755afac4af64fc0bee77b0f0ea54718d6384b70d4f'
+CASE_GROUPS = ('forge-admins', 'forge-coulomb-owners', 'forge-coulomb-readers')
+
+class Refused(ValueError):
+ pass
+
+
+def policy_only(base):
+ """Incomplete preparatory policy delta; does not add an OAuth source."""
+ result = deepcopy(base)
+ config = result['gitea']['config']
+ if config.get('service', {}).get('DISABLE_REGISTRATION') is not True:
+ raise Refused('existing registration policy differs')
+ # No supported local-form switch in 11.0.3: retain existing settings.
+ oauth = config.setdefault('oauth2_client', {})
+ oauth.update(ENABLE_AUTO_REGISTRATION=False, ACCOUNT_LINKING='login')
+ return result
+
+
+def chart_projection(base, groups):
+ """Chart-compatible PUBLIC values for one literal gate, or fail closed.
+
+ groups must be the authoritative reviewed case set, never a selected subset.
+ This function authenticates neither case/source acceptance nor permission.
+ It is not suitable for rendering arbitrary live/private Helm values.
+ """
+ if not isinstance(groups, tuple) or not groups or len(set(groups)) != len(groups):
+ raise Refused('explicit unique group tuple required')
+ if any(not isinstance(g, str) or not re.fullmatch(r'[a-z][a-z0-9-]{1,62}', g) for g in groups):
+ raise Refused('group literal invalid')
+ if len(groups) != 1:
+ raise Refused('Forgejo 11.0.3 supports one literal required claim; any-of unavailable')
+ result = policy_only(base)
+ sources = result['gitea'].setdefault('oauth', [])
+ if not isinstance(sources, list) or any(not isinstance(s, dict) for s in sources):
+ raise Refused('OAuth source list required')
+ names = [s.get('name') for s in sources]
+ if len(names) != len(set(names)) or 'netkingdom' in names:
+ raise Refused('existing target requires exact owner reconciliation')
+ idx = len(sources)
+ env = result.setdefault('deployment', {}).setdefault('env', [])
+ if not isinstance(env, list):
+ raise Refused('deployment env list required')
+ var = f'GITEA_OAUTH_SECRET_{idx}'
+ if any(e.get('name') == var for e in env):
+ raise Refused('indexed secret environment collision')
+ sources.append({
+ 'name': 'netkingdom', 'provider': 'openidConnect', 'key': 'forgejo',
+ 'autoDiscoverUrl': 'https://kc.coulomb.social/.well-known/openid-configuration',
+ 'scopes': 'openid,profile,email,groups', 'groupClaimName': 'groups',
+ 'requiredClaimName': 'groups', 'requiredClaimValue': groups[0],
+ })
+ env.append({'name': var, 'valueFrom': {'secretKeyRef': {
+ 'name': 'forgejo-netkingdom-oidc-client', 'key': 'CLIENT_SECRET'}}})
+ return result
+
+
+def prepare_first_case(base_bytes, base):
+ """Pin the public baseline and keep exact case any-of semantics."""
+ if hashlib.sha256(base_bytes).hexdigest() != BASE_SHA256:
+ raise Refused('frozen Apps public values bytes differ')
+ if base != yaml.safe_load(base_bytes):
+ raise Refused('decoded public baseline differs from frozen bytes')
+ # This entry never returns while the actual case has an unsupported gate.
+ return chart_projection(base, CASE_GROUPS)
+
+
+def activate(*args, **kwargs):
+ raise Refused('source preparation has no operational backend or admission')