Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Add 'brand' field to MSC2858 response #9242

Merged
merged 4 commits into from
Jan 27, 2021
Merged
Show file tree
Hide file tree
Changes from 3 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
2 changes: 1 addition & 1 deletion changelog.d/9183.feature
Original file line number Diff line number Diff line change
@@ -1 +1 @@
Add experimental support for allowing clients to pick an SSO Identity Provider ([MSC2858](https://github.com/matrix-org/matrix-doc/pull/2858).
Add experimental support for allowing clients to pick an SSO Identity Provider ([MSC2858](https://github.com/matrix-org/matrix-doc/pull/2858)).
1 change: 1 addition & 0 deletions changelog.d/9242.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add experimental support for allowing clients to pick an SSO Identity Provider ([MSC2858](https://github.com/matrix-org/matrix-doc/pull/2858)).
3 changes: 3 additions & 0 deletions docs/openid.md
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ Synapse config:
oidc_providers:
- idp_id: github
idp_name: Github
idp_brand: "org.matrix.github" # optional: styling hint for clients
discover: false
issuer: "https://github.com/"
client_id: "your-client-id" # TO BE FILLED
Expand All @@ -250,6 +251,7 @@ oidc_providers:
oidc_providers:
- idp_id: google
idp_name: Google
idp_brand: "org.matrix.google" # optional: styling hint for clients
issuer: "https://accounts.google.com/"
client_id: "your-client-id" # TO BE FILLED
client_secret: "your-client-secret" # TO BE FILLED
Expand Down Expand Up @@ -296,6 +298,7 @@ Synapse config:
oidc_providers:
- idp_id: gitlab
idp_name: Gitlab
idp_brand: "org.matrix.gitlab" # optional: styling hint for clients
issuer: "https://gitlab.com/"
client_id: "your-client-id" # TO BE FILLED
client_secret: "your-client-secret" # TO BE FILLED
Expand Down
13 changes: 9 additions & 4 deletions docs/sample_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1727,10 +1727,14 @@ saml2_config:
# offer the user a choice of login mechanisms.
#
# idp_icon: An optional icon for this identity provider, which is presented
# by identity picker pages. If given, must be an MXC URI of the format
# mxc://<server-name>/<media-id>. (An easy way to obtain such an MXC URI
# is to upload an image to an (unencrypted) room and then copy the "url"
# from the source of the event.)
# by clients and Synapse's own IdP picker page. If given, must be an
# MXC URI of the format mxc://<server-name>/<media-id>. (An easy way to
# obtain such an MXC URI is to upload an image to an (unencrypted) room
# and then copy the "url" from the source of the event.)
#
# idp_brand: An optional brand for this identity provider, allowing clients
# to style the login flow according to the identity provider in question.
# See the spec for possible options here.
#
# discover: set to 'false' to disable the use of the OIDC discovery mechanism
# to discover endpoints. Defaults to true.
Expand Down Expand Up @@ -1851,6 +1855,7 @@ oidc_providers:
#
#- idp_id: github
# idp_name: Github
# idp_brand: org.matrix.github
# discover: false
# issuer: "https://github.com/"
# client_id: "your-client-id" # TO BE FILLED
Expand Down
52 changes: 27 additions & 25 deletions synapse/config/oidc_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.

import string
from collections import Counter
from typing import Iterable, Optional, Tuple, Type

Expand Down Expand Up @@ -79,10 +78,14 @@ def generate_config_section(self, config_dir_path, server_name, **kwargs):
# offer the user a choice of login mechanisms.
#
# idp_icon: An optional icon for this identity provider, which is presented
# by identity picker pages. If given, must be an MXC URI of the format
# mxc://<server-name>/<media-id>. (An easy way to obtain such an MXC URI
# is to upload an image to an (unencrypted) room and then copy the "url"
# from the source of the event.)
# by clients and Synapse's own IdP picker page. If given, must be an
# MXC URI of the format mxc://<server-name>/<media-id>. (An easy way to
# obtain such an MXC URI is to upload an image to an (unencrypted) room
# and then copy the "url" from the source of the event.)
#
# idp_brand: An optional brand for this identity provider, allowing clients
# to style the login flow according to the identity provider in question.
# See the spec for possible options here.
#
# discover: set to 'false' to disable the use of the OIDC discovery mechanism
# to discover endpoints. Defaults to true.
Expand Down Expand Up @@ -203,6 +206,7 @@ def generate_config_section(self, config_dir_path, server_name, **kwargs):
#
#- idp_id: github
# idp_name: Github
# idp_brand: org.matrix.github
# discover: false
# issuer: "https://github.com/"
# client_id: "your-client-id" # TO BE FILLED
Expand All @@ -226,11 +230,22 @@ def generate_config_section(self, config_dir_path, server_name, **kwargs):
"type": "object",
"required": ["issuer", "client_id", "client_secret"],
"properties": {
# TODO: fix the maxLength here depending on what MSC2528 decides
# remember that we prefix the ID given here with `oidc-`
"idp_id": {"type": "string", "minLength": 1, "maxLength": 128},
"idp_id": {
"type": "string",
"minLength": 1,
# MSC2858 allows a maxlen of 255, but we prefix with "oidc-"
"maxLength": 251,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be 250: len("oidc-") == 5

"pattern": "^[A-Za-z0-9._~-]+$",
},
"idp_name": {"type": "string"},
"idp_icon": {"type": "string"},
"idp_brand": {
"type": "string",
# MSC2758-style namespaced identifier
"minLength": 1,
"maxLength": 255,
"pattern": "^[a-z][a-z0-9_.-]*$",
},
"discover": {"type": "boolean"},
"issuer": {"type": "string"},
"client_id": {"type": "string"},
Expand Down Expand Up @@ -349,25 +364,8 @@ def _parse_oidc_config_dict(
config_path + ("user_mapping_provider", "module"),
)

# MSC2858 will apply certain limits in what can be used as an IdP id, so let's
# enforce those limits now.
# TODO: factor out this stuff to a generic function
idp_id = oidc_config.get("idp_id", "oidc")

# TODO: update this validity check based on what MSC2858 decides.
valid_idp_chars = set(string.ascii_lowercase + string.digits + "-._")

if any(c not in valid_idp_chars for c in idp_id):
raise ConfigError(
'idp_id may only contain a-z, 0-9, "-", ".", "_"',
config_path + ("idp_id",),
)

if idp_id[0] not in string.ascii_lowercase:
raise ConfigError(
"idp_id must start with a-z", config_path + ("idp_id",),
)

# prefix the given IDP with a prefix specific to the SSO mechanism, to avoid
# clashes with other mechs (such as SAML, CAS).
#
Expand All @@ -393,6 +391,7 @@ def _parse_oidc_config_dict(
idp_id=idp_id,
idp_name=oidc_config.get("idp_name", "OIDC"),
idp_icon=idp_icon,
idp_brand=oidc_config.get("idp_brand"),
discover=oidc_config.get("discover", True),
issuer=oidc_config["issuer"],
client_id=oidc_config["client_id"],
Expand Down Expand Up @@ -423,6 +422,9 @@ class OidcProviderConfig:
# Optional MXC URI for icon for this IdP.
idp_icon = attr.ib(type=Optional[str])

# Optional brand identifier for this IdP.
idp_brand = attr.ib(type=Optional[str])

# whether the OIDC discovery mechanism is used to discover endpoints
discover = attr.ib(type=bool)

Expand Down
3 changes: 2 additions & 1 deletion synapse/handlers/cas_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,10 @@ def __init__(self, hs: "HomeServer"):
# user-facing name of this auth provider
self.idp_name = "CAS"

# we do not currently support icons for CAS auth, but this is required by
# we do not currently support brands/icons for CAS auth, but this is required by
# the SsoIdentityProvider protocol type.
self.idp_icon = None
self.idp_brand = None

self._sso_handler = hs.get_sso_handler()

Expand Down
3 changes: 3 additions & 0 deletions synapse/handlers/oidc_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,9 @@ def __init__(
# MXC URI for icon for this auth provider
self.idp_icon = provider.idp_icon

# optional brand identifier for this auth provider
self.idp_brand = provider.idp_brand

self._sso_handler = hs.get_sso_handler()

self._sso_handler.register_identity_provider(self)
Expand Down
3 changes: 2 additions & 1 deletion synapse/handlers/saml_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,10 @@ def __init__(self, hs: "HomeServer"):
# user-facing name of this auth provider
self.idp_name = "SAML"

# we do not currently support icons for SAML auth, but this is required by
# we do not currently support icons/brands for SAML auth, but this is required by
# the SsoIdentityProvider protocol type.
self.idp_icon = None
self.idp_brand = None

# a map from saml session id to Saml2SessionData object
self._outstanding_requests_dict = {} # type: Dict[str, Saml2SessionData]
Expand Down
5 changes: 5 additions & 0 deletions synapse/handlers/sso.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,11 @@ def idp_icon(self) -> Optional[str]:
"""Optional MXC URI for user-facing icon"""
return None

@property
def idp_brand(self) -> Optional[str]:
"""Optional branding identifier"""
return None

@abc.abstractmethod
async def handle_redirect_request(
self,
Expand Down
2 changes: 2 additions & 0 deletions synapse/rest/client/v1/login.py
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,8 @@ def _get_auth_flow_dict_for_idp(idp: SsoIdentityProvider) -> JsonDict:
e = {"id": idp.idp_id, "name": idp.idp_name} # type: JsonDict
if idp.idp_icon:
e["icon"] = idp.idp_icon
if idp.idp_brand:
e["brand"] = idp.idp_brand
return e


Expand Down