Skip to content
Snippets Groups Projects
Verified Commit e1b75074 authored by Nicolas Werner's avatar Nicolas Werner
Browse files

Support explicit IDPs

parent 3010d63d
No related branches found
No related tags found
No related merge requests found
Pipeline #2767 passed
......@@ -40,11 +40,46 @@ struct Login
void
from_json(const nlohmann::json &obj, Login &response);
//! Identity provider for SSO
struct IdentityProvider
{
//! Optional UI hint for what kind of common SSO provider is being described in this IdP. Matrix
//! maintains a registry of identifiers in the matrix-doc repo to ensure clients and servers are
//! aligned on major/common brands.
//!
//! Clients should prefer the brand over the icon, when both are provided. Clients are not
//! required to support any particular brand, including those in the registry, though are
//! expected to be able to present any IdP based off the name/icon to the user regardless.
//!
//! Unregistered brands are permitted using the Common Namespaced Identifier Grammar, though
//! excluding the namespace requirements. For example, examplesso is a valid brand which is not
//! in the registry but still permitted. Servers should be mindful that clients might not
//! support their unregistered brand usage as intended by the server.
std::string brand;
//! Optional MXC URI to provide an image/icon representing the IdP. Intended to be shown
//! alongside the name if provided.
std::string icon;
//! Required: Opaque string chosen by the homeserver, uniquely identifying the IdP from other
//! IdPs the homeserver might support. Should be between 1 and 255 characters in length,
//! containing unreserved characters under RFC 3986 (ALPHA DIGIT "-" / "." / "_" / "~"). Clients
//! are not intended to parse or infer meaning from opaque strings.
std::string id;
//! Required: Human readable description for the IdP, intended to be shown to the user.
std::string name;
};
void
from_json(const nlohmann::json &obj, IdentityProvider &response);
//! One supported login flow.
struct LoginFlow
{
//! The authentication used for this flow.
mtx::user_interactive::AuthType type;
//! Optional identity providers (IdPs) to present to the user. These would appear (typically) as
//! distinct buttons for the user to interact with, and would map to the appropriate
//! IdP-dependent redirect endpoint for that IdP.
std::vector<IdentityProvider> identity_providers;
};
void
from_json(const nlohmann::json &obj, LoginFlow &response);
......
......@@ -255,9 +255,9 @@ public:
//! Get the supported login flows
void get_login(Callback<mtx::responses::LoginFlows> cb);
//! Get url to navigate to for sso login flow
//! Get url to navigate to for sso login flow, optionally preselecting an identity provider
//! Open this in a browser
std::string login_sso_redirect(std::string redirectUrl);
std::string login_sso_redirect(std::string redirectUrl, const std::string &idp = "");
//! Lookup real server to connect to.
//! Call set_server with the returned homeserver url after this
void well_known(Callback<mtx::responses::WellKnown> cb);
......
......@@ -258,10 +258,11 @@ Client::get_login(Callback<mtx::responses::LoginFlows> cb)
}
std::string
Client::login_sso_redirect(std::string redirectUrl)
Client::login_sso_redirect(std::string redirectUrl, const std::string &idp)
{
const std::string idp_suffix = idp.empty() ? idp : ("/" + mtx::client::utils::url_encode(idp));
return protocol_ + "://" + server() + ":" + std::to_string(port()) +
"/_matrix/client/r0/login/sso/redirect?" +
"/_matrix/client/r0/login/sso/redirect" + idp_suffix + "?" +
mtx::client::utils::query_params({{"redirectUrl", redirectUrl}});
}
......
......@@ -20,10 +20,20 @@ from_json(const nlohmann::json &obj, Login &response)
response.well_known = obj.at("well_known").get<WellKnown>();
}
void
from_json(const nlohmann::json &obj, IdentityProvider &response)
{
response.brand = obj.value("brand", "");
response.icon = obj.value("icon", "");
response.id = obj.at("id").get<std::string>();
response.name = obj.at("name").get<std::string>();
}
void
from_json(const nlohmann::json &obj, LoginFlow &response)
{
response.type = obj.at("type").get<std::string>();
response.type = obj.at("type").get<std::string>();
response.identity_providers = obj.value("identity_providers", std::vector<IdentityProvider>{});
}
void
from_json(const nlohmann::json &obj, LoginFlows &response)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment