Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion docs/how-to/configure-saml.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,15 @@

To configure Discourse's SAML integration you'll have to set the following configuration options with the appropriate values for your SAML server by running `juju config [charm_name] [configuration]=[value]`.

The SAML URL needs to be scpecified in `saml_target_url`. If you wish to force the login to go through SAML, enable `force_saml_login`.
If you wish to force the login to go through SAML, enable `force_saml_login`.
The groups to be synced from the provider can be defined in `saml_sync_groups` as a comma-separated list of values.
In order to implement the relation discourse has to be related with the [saml-integrator](https://charmhub.io/saml-integrator):
```
juju deploy saml-integrator --channel=edge
#Set the SAML integrator configs
juju config saml-integrator metadata_url=https://login.staging.ubuntu.com/saml/metadata
juju config saml-integrator entity_id=https://login.staging.ubuntu.com
juju integrate discourse-k8s saml-integrator
```

For more details on the configuration options and their default values see the [configuration reference](https://charmhub.io/discourse-k8s/configure).
25 changes: 19 additions & 6 deletions src/charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@
from charms.prometheus_k8s.v0.prometheus_scrape import MetricsEndpointProvider
from charms.redis_k8s.v0.redis import RedisRelationCharmEvents, RedisRequires
from charms.rolling_ops.v0.rollingops import RollingOpsManager
from charms.saml_integrator.v0.saml import SamlDataAvailableEvent, SamlRequires
from charms.saml_integrator.v0.saml import (
DEFAULT_RELATION_NAME,
SamlDataAvailableEvent,
SamlRequires,
)
from ops.charm import ActionEvent, CharmBase, HookEvent, RelationBrokenEvent
from ops.framework import StoredState
from ops.main import main
Expand Down Expand Up @@ -205,7 +209,7 @@ def _on_saml_data_available(self, event: SamlDataAvailableEvent) -> None:
fingerprint = hashlib.sha1(
base64.b64decode(event.certificates[0])
).hexdigest() # nosec
relation = self.model.get_relation("saml")
relation = self.model.get_relation(DEFAULT_RELATION_NAME)
# Will ignore union-attr since asserting the relation type will make bandit complain.
relation.data[self.app].update( # type: ignore[union-attr]
{
Expand Down Expand Up @@ -279,13 +283,22 @@ def _is_config_valid(self) -> bool:
if self.config["throttle_level"] not in THROTTLE_LEVELS:
errors.append(f"throttle_level must be one of: {' '.join(THROTTLE_LEVELS.keys())}")

if self.config["force_saml_login"] and self.model.get_relation("saml") is None:
if (
self.config["force_saml_login"]
and self.model.get_relation(DEFAULT_RELATION_NAME) is None
):
errors.append("force_saml_login cannot be true without a saml relation")

if self.config["saml_sync_groups"] and self.model.get_relation("saml") is None:
if (
self.config["saml_sync_groups"]
and self.model.get_relation(DEFAULT_RELATION_NAME) is None
):
errors.append("'saml_sync_groups' cannot be specified without a saml relation")

if self.model.get_relation("saml") is not None and not self.config["force_https"]:
if (
self.model.get_relation(DEFAULT_RELATION_NAME) is not None
and not self.config["force_https"]
):
errors.append("A saml relation cannot be specified without 'force_https' being true")

if self.config.get("s3_enabled"):
Expand All @@ -307,7 +320,7 @@ def _get_saml_config(self) -> typing.Dict[str, typing.Any]:
"""
saml_config = {}

relation = self.model.get_relation("saml")
relation = self.model.get_relation(DEFAULT_RELATION_NAME)
if (
relation is not None
and relation.data[self.app]
Expand Down