You've already forked authentication-service
mirror of
https://github.com/matrix-org/matrix-authentication-service.git
synced 2025-07-29 22:01:14 +03:00
WIP: Provider list on the login page
This commit is contained in:
@ -60,8 +60,9 @@ pub(crate) async fn get(
|
||||
let reply = query.go_next();
|
||||
Ok((cookie_jar, reply).into_response())
|
||||
} else {
|
||||
let providers = mas_storage::upstream_oauth2::get_providers(&mut conn).await?;
|
||||
let content = render(
|
||||
LoginContext::default(),
|
||||
LoginContext::default().with_upstrem_providers(providers),
|
||||
query,
|
||||
csrf_token,
|
||||
&mut conn,
|
||||
@ -103,8 +104,11 @@ pub(crate) async fn post(
|
||||
};
|
||||
|
||||
if !state.is_valid() {
|
||||
let providers = mas_storage::upstream_oauth2::get_providers(&mut conn).await?;
|
||||
let content = render(
|
||||
LoginContext::default().with_form_state(state),
|
||||
LoginContext::default()
|
||||
.with_form_state(state)
|
||||
.with_upstrem_providers(providers),
|
||||
query,
|
||||
csrf_token,
|
||||
&mut conn,
|
||||
|
@ -2559,6 +2559,66 @@
|
||||
},
|
||||
"query": "\n INSERT INTO oauth2_clients\n (oauth2_client_id,\n encrypted_client_secret,\n grant_type_authorization_code,\n grant_type_refresh_token,\n client_name,\n logo_uri,\n client_uri,\n policy_uri,\n tos_uri,\n jwks_uri,\n jwks,\n id_token_signed_response_alg,\n userinfo_signed_response_alg,\n token_endpoint_auth_method,\n token_endpoint_auth_signing_alg,\n initiate_login_uri)\n VALUES\n ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16)\n "
|
||||
},
|
||||
"cf00e0ad529bcb5c0640adcfe0880a3560d9739f355b90ca3ba88dd1eaf26565": {
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "upstream_oauth_provider_id",
|
||||
"ordinal": 0,
|
||||
"type_info": "Uuid"
|
||||
},
|
||||
{
|
||||
"name": "issuer",
|
||||
"ordinal": 1,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "scope",
|
||||
"ordinal": 2,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "client_id",
|
||||
"ordinal": 3,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "encrypted_client_secret",
|
||||
"ordinal": 4,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "token_endpoint_signing_alg",
|
||||
"ordinal": 5,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "token_endpoint_auth_method",
|
||||
"ordinal": 6,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "created_at",
|
||||
"ordinal": 7,
|
||||
"type_info": "Timestamptz"
|
||||
}
|
||||
],
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false
|
||||
],
|
||||
"parameters": {
|
||||
"Left": []
|
||||
}
|
||||
},
|
||||
"query": "\n SELECT\n upstream_oauth_provider_id,\n issuer,\n scope,\n client_id,\n encrypted_client_secret,\n token_endpoint_signing_alg,\n token_endpoint_auth_method,\n created_at\n FROM upstream_oauth_providers\n "
|
||||
},
|
||||
"d1738c27339b81f0844da4bd9b040b9b07a91aa4d9b199b98f24c9cee5709b2b": {
|
||||
"describe": {
|
||||
"columns": [],
|
||||
|
@ -18,7 +18,9 @@ mod session;
|
||||
|
||||
pub use self::{
|
||||
link::{add_link, associate_link_to_user, lookup_link, lookup_link_by_subject},
|
||||
provider::{add_provider, get_paginated_providers, lookup_provider, ProviderLookupError},
|
||||
provider::{
|
||||
add_provider, get_paginated_providers, get_providers, lookup_provider, ProviderLookupError,
|
||||
},
|
||||
session::{
|
||||
add_session, complete_session, consume_session, lookup_session, lookup_session_on_link,
|
||||
SessionLookupError,
|
||||
|
@ -219,3 +219,29 @@ pub async fn get_paginated_providers(
|
||||
let page: Result<Vec<_>, _> = page.into_iter().map(TryInto::try_into).collect();
|
||||
Ok((has_previous_page, has_next_page, page?))
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip_all, err)]
|
||||
pub async fn get_providers(
|
||||
executor: impl PgExecutor<'_>,
|
||||
) -> Result<Vec<UpstreamOAuthProvider>, anyhow::Error> {
|
||||
let res = sqlx::query_as!(
|
||||
ProviderLookup,
|
||||
r#"
|
||||
SELECT
|
||||
upstream_oauth_provider_id,
|
||||
issuer,
|
||||
scope,
|
||||
client_id,
|
||||
encrypted_client_secret,
|
||||
token_endpoint_signing_alg,
|
||||
token_endpoint_auth_method,
|
||||
created_at
|
||||
FROM upstream_oauth_providers
|
||||
"#,
|
||||
)
|
||||
.fetch_all(executor)
|
||||
.await?;
|
||||
|
||||
let res: Result<Vec<_>, _> = res.into_iter().map(TryInto::try_into).collect();
|
||||
Ok(res?)
|
||||
}
|
||||
|
@ -279,6 +279,7 @@ pub enum PostAuthContext {
|
||||
pub struct LoginContext {
|
||||
form: FormState<LoginFormField>,
|
||||
next: Option<PostAuthContext>,
|
||||
providers: Vec<UpstreamOAuthProvider>,
|
||||
register_link: String,
|
||||
}
|
||||
|
||||
@ -291,6 +292,7 @@ impl TemplateContext for LoginContext {
|
||||
vec![LoginContext {
|
||||
form: FormState::default(),
|
||||
next: None,
|
||||
providers: Vec::new(),
|
||||
register_link: "/register".to_owned(),
|
||||
}]
|
||||
}
|
||||
@ -303,6 +305,12 @@ impl LoginContext {
|
||||
Self { form, ..self }
|
||||
}
|
||||
|
||||
/// Set the upstream OAuth 2.0 providers
|
||||
#[must_use]
|
||||
pub fn with_upstrem_providers(self, providers: Vec<UpstreamOAuthProvider>) -> Self {
|
||||
Self { providers, ..self }
|
||||
}
|
||||
|
||||
/// Add a post authentication action to the context
|
||||
#[must_use]
|
||||
pub fn with_post_action(self, next: PostAuthContext) -> Self {
|
||||
|
@ -65,6 +65,18 @@ limitations under the License.
|
||||
{{ button::link_text(text="Create an account", href=register_link) }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if providers %}
|
||||
<div class="flex items-center">
|
||||
<hr class="flex-1" />
|
||||
<div class="mx-2">Or</div>
|
||||
<hr class="flex-1" />
|
||||
</div>
|
||||
|
||||
{% for provider in providers %}
|
||||
{{ button::link(text="Continue with " ~ provider.issuer, href="/upstream/authorize/" ~ provider.id) }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</form>
|
||||
</section>
|
||||
{% endblock content %}
|
||||
|
Reference in New Issue
Block a user