Skip to content

Commit

Permalink
fix(docker-jans): add test client with all scopes to CN-based setup (#…
Browse files Browse the repository at this point in the history
…5682)

* fix(docker-jans): add test client with all scopes to CN-based setup

* docs: add documentation

---------

Co-authored-by: moabu <47318409+moabu@users.noreply.github.com>
  • Loading branch information
iromli and moabu committed Jul 31, 2023
1 parent 0795df2 commit a81d301
Show file tree
Hide file tree
Showing 5 changed files with 167 additions and 67 deletions.
20 changes: 19 additions & 1 deletion docker-jans-config-api/scripts/bootstrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,24 @@ def ctx(self) -> dict[str, _t.Any]:
).decode()
self.manager.secret.set("jca_client_encoded_pw", ctx["jca_client_encoded_pw"])

# test client
ctx["test_client_id"] = self.manager.config.get("test_client_id")
if not ctx["test_client_id"]:
ctx["test_client_id"] = f"{uuid4()}"
self.manager.config.set("test_client_id", ctx["test_client_id"])

ctx["test_client_pw"] = self.manager.secret.get("test_client_pw")
if not ctx["test_client_pw"]:
ctx["test_client_pw"] = get_random_chars()
self.manager.secret.set("test_client_pw", ctx["test_client_pw"])

ctx["test_client_encoded_pw"] = self.manager.secret.get("test_client_encoded_pw")
if not ctx["test_client_encoded_pw"]:
ctx["test_client_encoded_pw"] = encode_text(
ctx["test_client_pw"], self.manager.secret.get("encoded_salt"),
).decode()
self.manager.secret.set("test_client_encoded_pw", ctx["test_client_encoded_pw"])

# pre-populate config_api_dynamic_conf_base64
with open("/app/templates/jans-config-api/dynamic-conf.json") as f:
tmpl = Template(f.read())
Expand Down Expand Up @@ -468,7 +486,7 @@ def import_ldif_files(self) -> None:
logger.info("Missing scopes creation is enabled!")
self.generate_scopes_ldif()

files = ["config.ldif", "scopes.ldif", "clients.ldif", "scim-scopes.ldif"]
files = ["config.ldif", "scopes.ldif", "clients.ldif", "scim-scopes.ldif", "testing-clients.ldif"]
ldif_files = [f"/app/templates/jans-config-api/{file_}" for file_ in files]

for file_ in ldif_files:
Expand Down
57 changes: 55 additions & 2 deletions docker-jans-config-api/scripts/upgrade.py
Original file line number Diff line number Diff line change
Expand Up @@ -297,8 +297,9 @@ def invoke(self):
self.update_api_dynamic_config()

# add missing scopes into internal config-api client (if enabled)
if as_boolean(os.environ.get("CN_CONFIG_API_CREATE_SCOPES")):
self.update_client_scopes()
# if as_boolean(os.environ.get("CN_CONFIG_API_CREATE_SCOPES")):
self.update_client_scopes()
self.update_test_client_scopes()

def update_client_redirect_uri(self):
kwargs = {}
Expand Down Expand Up @@ -400,6 +401,58 @@ def update_client_scopes(self):
entry.attrs["jansScope"] = client_scopes + diff
self.backend.modify_entry(entry.id, entry.attrs, **kwargs)

def update_test_client_scopes(self):
test_client_id = self.manager.config.get("test_client_id")
id_ = f"inum={test_client_id},ou=clients,o=jans"
kwargs = {}

# search_entries(self, key, filter_="", attrs=None, **kwargs)
if self.backend.type in ("sql", "spanner"):
id_ = doc_id_from_dn(id_)
kwargs = {"table_name": "jansClnt"}
elif self.backend.type == "couchbase":
id_ = id_from_dn(id_)
kwargs = {"bucket": os.environ.get("CN_COUCHBASE_BUCKET_PREFIX", "jans")}

entry = self.backend.get_entry(id_, **kwargs)

if not entry:
return

if self.backend.type == "sql" and self.backend.client.dialect == "mysql":
client_scopes = entry.attrs["jansScope"]["v"]
else:
client_scopes = entry.attrs["jansScope"]

if not isinstance(client_scopes, list):
client_scopes = [client_scopes]

if self.backend.type in ("sql", "spanner"):
scopes = [
scope_entry.attrs["dn"]
for scope_entry in self.backend.search_entries("", **{"table_name": "jansScope"})
]
elif self.backend.type == "couchbase":
bucket = os.environ.get("CN_COUCHBASE_BUCKET_PREFIX", "jans")
scopes = [
scope_entry.attrs["dn"]
for scope_entry in self.backend.search_entries("", filter_="WHERE objectClass='jansScope'", **{"bucket": bucket})
]
else:
scopes = [
scope_entry.id
for scope_entry in self.backend.search_entries("ou=scopes,o=jans")
]

# find missing scopes from the client
diff = list(set(scopes).difference(client_scopes))
if diff:
if self.backend.type == "sql" and self.backend.client.dialect == "mysql":
entry.attrs["jansScope"]["v"] = client_scopes + diff
else:
entry.attrs["jansScope"] = client_scopes + diff
self.backend.modify_entry(entry.id, entry.attrs, **kwargs)


def main():
manager = get_manager()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
dn: inum=%(test_client_id)s,ou=clients,o=jans
del: false
displayName: Jans Test Client with all scopes
inum: %(test_client_id)s
jansAccessTknAsJwt: false
jansAccessTknSigAlg: RS256
jansAppTyp: web
jansAttrs: {"tlsClientAuthSubjectDn": "", "runIntrospectionScriptBeforeJwtCreation": false, "keepClientAuthorizationAfterExpiration": false, "allowSpontaneousScopes": false, "spontaneousScopes": [], "spontaneousScopeScriptDns": [], "backchannelLogoutUri": [], "backchannelLogoutSessionRequired": false, "additionalAudience": [], "postAuthnScripts": [], "consentGatheringScripts": [], "introspectionScripts": [], "rptClaimsScripts": []}
jansClntSecret: %(test_client_encoded_pw)s
jansDisabled: false
jansGrantTyp: authorization_code
jansGrantTyp: refresh_token
jansGrantTyp: client_credentials
jansIdTknSignedRespAlg: RS256
jansInclClaimsInIdTkn: false
jansLogoutSessRequired: false
jansPersistClntAuthzs: true
jansRespTyp: code
jansRptAsJwt: false
# the remaining scopes will be pre-populated on upgrade script
jansScope: inum=C4F7,ou=scopes,o=jans
jansSubjectTyp: pairwise
jansTknEndpointAuthMethod: client_secret_basic
jansTrustedClnt: false
objectClass: top
objectClass: jansClnt
127 changes: 65 additions & 62 deletions docs/admin/reference/kubernetes/config-secret-keys.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,71 +25,74 @@ kubectl get secret -n jans -o yaml

## Jans Configmaps

| Key | Example Values |
| --------------------------------------------- | -------------------------------------------------- |
| `admin_email` | `support@jans.io` |
| `admin_inum` | `631e2b84-1d3d-4f28-9a9a-026a25febf44` |
| `auth_enc_keys` | `RSA1_5 RSA-OAEP` |
| `auth_key_rotated_at` | `1669143906` |
| `auth_legacyIdTokenClaims` | `false` |
| `auth_openid_jks_fn` | `/etc/certs/auth-keys.jks` |
| `auth_openid_jwks_fn` | `/etc/certs/auth-keys.json` |
| `auth_openidScopeBackwardCompatibility` | `false` |
| `auth_sig_keys` | `RS256 RS384 RS512 ES256 ES384 ES512 PS256 PS384 PS512`|
| `city` | `Austin` |
| `couchbaseTrustStoreFn` | `/etc/certs/couchbase.pkcs12` |
| `country_code` | `US` |
| `default_openid_jks_dn_name` | `CN=Janssen Auth CA Certificates` |
| `hostname` | `demoexample.jans.io` |
| `jca_client_id` | `1800.ca41fad2-6ab6-46b1-b4a9-3387992a8cb0` |
| `ldap_binddn` | `cn=directory manager` |
| `ldap_init_host` | `localhost` |
| `ldap_init_port` | `1636` |
| `ldap_port` | `1389` |
| `ldap_site_binddn` | `cn=directory manager` |
| `ldapTrustStoreFn` | `/etc/certs/opendj.pkcs12` |
| `ldaps_port` | `1636` |
| `optional_scopes` | `["fido2", "scim", "sql"]` |
| `orgName` | `Janssen` |
| `tui_client_id` | `2000.4a8f3e8b-96b0-435a-8427-a287c242f4d9` |
| `scim_client_id` | `12` |
| `state` | `TX` |
| Key | Example Values |
|-----------------------------------------|---------------------------------------------------------|
| `admin_email` | `support@jans.io` |
| `admin_inum` | `631e2b84-1d3d-4f28-9a9a-026a25febf44` |
| `auth_enc_keys` | `RSA1_5 RSA-OAEP` |
| `auth_key_rotated_at` | `1669143906` |
| `auth_legacyIdTokenClaims` | `false` |
| `auth_openid_jks_fn` | `/etc/certs/auth-keys.jks` |
| `auth_openid_jwks_fn` | `/etc/certs/auth-keys.json` |
| `auth_openidScopeBackwardCompatibility` | `false` |
| `auth_sig_keys` | `RS256 RS384 RS512 ES256 ES384 ES512 PS256 PS384 PS512` |
| `city` | `Austin` |
| `couchbaseTrustStoreFn` | `/etc/certs/couchbase.pkcs12` |
| `country_code` | `US` |
| `default_openid_jks_dn_name` | `CN=Janssen Auth CA Certificates` |
| `hostname` | `demoexample.jans.io` |
| `jca_client_id` | `1800.ca41fad2-6ab6-46b1-b4a9-3387992a8cb0` |
| `ldap_binddn` | `cn=directory manager` |
| `ldap_init_host` | `localhost` |
| `ldap_init_port` | `1636` |
| `ldap_port` | `1389` |
| `ldap_site_binddn` | `cn=directory manager` |
| `ldapTrustStoreFn` | `/etc/certs/opendj.pkcs12` |
| `ldaps_port` | `1636` |
| `optional_scopes` | `["fido2", "scim", "sql"]` |
| `orgName` | `Janssen` |
| `test_client_id` | `2000.4a8f3e8b-96b0-435a-8427-a287c242f4d9` |
| `tui_client_id` | `2000.4a8f3e8b-96b0-435a-8427-a287c242f4d9` |
| `scim_client_id` | `12` |
| `state` | `TX` |

## Jans Secrets

| Key | Encode/Decode | File |
| ----------------------------------------- | ----------------------- | --------------------------------- |
| `auth_jks_base64` | base64 | |
| `auth_openid_jks_pass` | base64 | |
| `auth_openid_key_base64` | base64 | |
| `couchbase_password` | base64 | |
| `couchbase_shib_user_password` | base64 | |
| `couchbase_superuser_password` | base64 | |
| `encoded_admin_password` | ldap_encode + base64 | |
| `encoded_ldapTrustStorePass` | pyDes + base64 | |
| `encoded_ox_ldap_pw` | pyDes + base64 | |
| `encoded_salt` | base64 | |
| `jca_client_encoded_pw` | pyDes + base64 | |
| `jca_client_pw` | pyDes + base64 | |
| `ldap_pkcs12_base64` | pyDes + base64 | /etc/certs/opendj.pkcs12 |
| `ldap_ssl_cacert` | pyDes + base64 | /etc/certs/opendj.pem |
| `ldap_ssl_cert` | pyDes + base64 | /etc/certs/opendj.crt |
| `ldap_ssl_key` | pyDes + base64 | /etc/certs/opendj.key |
| `ldap_truststore_pass` | base64 | |
| `otp_configuration` | base64 | |
| `pairwiseCalculationKey` | base64 | |
| `pairwiseCalculationSalt` | base64 | |
| `tui_client_encoded_pw` | pyDes + base64 | |
| `tui_client_pw` | pyDes + base64 | |
| `scim_client_encoded_pw` | pyDes + base64 | |
| `scim_client_pw` | pyDes + base64 | |
| `sql_password` | base64 | |
| `ssl_ca_cert` | base64 | /etc/certs/ca.crt |
| `ssl_ca_key` | base64 | /etc/certs/ca.key |
| `ssl_cert` | base64 | /etc/certs/web_https.crt |
| `ssl_csr` | base64 | /etc/certs/web_https.csr |
| `ssl_key` | base64 | /etc/certs/web_https.key |
| `super_gluu_creds` | base64 | |
| Key | Encode/Decode | File |
|--------------------------------|----------------------|--------------------------|
| `auth_jks_base64` | base64 | |
| `auth_openid_jks_pass` | base64 | |
| `auth_openid_key_base64` | base64 | |
| `couchbase_password` | base64 | |
| `couchbase_shib_user_password` | base64 | |
| `couchbase_superuser_password` | base64 | |
| `encoded_admin_password` | ldap_encode + base64 | |
| `encoded_ldapTrustStorePass` | pyDes + base64 | |
| `encoded_ox_ldap_pw` | pyDes + base64 | |
| `encoded_salt` | base64 | |
| `jca_client_encoded_pw` | pyDes + base64 | |
| `jca_client_pw` | pyDes + base64 | |
| `ldap_pkcs12_base64` | pyDes + base64 | /etc/certs/opendj.pkcs12 |
| `ldap_ssl_cacert` | pyDes + base64 | /etc/certs/opendj.pem |
| `ldap_ssl_cert` | pyDes + base64 | /etc/certs/opendj.crt |
| `ldap_ssl_key` | pyDes + base64 | /etc/certs/opendj.key |
| `ldap_truststore_pass` | base64 | |
| `otp_configuration` | base64 | |
| `pairwiseCalculationKey` | base64 | |
| `pairwiseCalculationSalt` | base64 | |
| `tui_client_encoded_pw` | pyDes + base64 | |
| `test_client_pw` | base64 | |
| `tui_client_encoded_pw` | pyDes + base64 | |
| `tui_client_pw` | base64 | |
| `scim_client_encoded_pw` | pyDes + base64 | |
| `scim_client_pw` | base64 | |
| `sql_password` | base64 | |
| `ssl_ca_cert` | base64 | /etc/certs/ca.crt |
| `ssl_ca_key` | base64 | /etc/certs/ca.key |
| `ssl_cert` | base64 | /etc/certs/web_https.crt |
| `ssl_csr` | base64 | /etc/certs/web_https.csr |
| `ssl_key` | base64 | /etc/certs/web_https.key |
| `super_gluu_creds` | base64 | |

## Example decoding secrets

Expand Down
4 changes: 2 additions & 2 deletions docs/admin/terraform/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,9 @@ Let's have an example on `importing` the current `logging level` of a deployment
- **VM:** grab `client_id` and `client_pw` from `/opt/jans/jans-setup/setup.properties.last` file.

- **K8s:**
1. client_id: `kubectl get cm cn -n <namespace> -o yaml | grep jca_client_id`
1. client_id: `kubectl get cm cn -n <namespace> -o yaml | grep test_client_id`

2. Get client_secret: `kubectl get secret cn -n <namespace> -o yaml | grep jca_client_pw`. This client secret has to be decoded before use.
2. Get client_secret: `kubectl get secret cn -n <namespace> -o yaml | grep test_client_pw`. This client secret has to be decoded before use.

3. Decode the client_secret: `echo "client_secret" | base64 -d`

Expand Down

0 comments on commit a81d301

Please sign in to comment.