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
OIDC account linking and login
This commit is contained in:
@ -13,13 +13,13 @@
|
||||
// limitations under the License.
|
||||
|
||||
use chrono::{DateTime, Utc};
|
||||
use mas_data_model::{UpstreamOAuthLink, UpstreamOAuthProvider};
|
||||
use mas_data_model::{UpstreamOAuthLink, UpstreamOAuthProvider, User};
|
||||
use rand::Rng;
|
||||
use sqlx::PgExecutor;
|
||||
use ulid::Ulid;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::{Clock, GenericLookupError};
|
||||
use crate::{Clock, GenericLookupError, PostgresqlBackend};
|
||||
|
||||
struct LinkLookup {
|
||||
upstream_oauth_link_id: Uuid,
|
||||
@ -158,3 +158,33 @@ pub async fn add_link(
|
||||
created_at,
|
||||
})
|
||||
}
|
||||
|
||||
#[tracing::instrument(
|
||||
skip_all,
|
||||
fields(
|
||||
%upstream_oauth_link.id,
|
||||
%upstream_oauth_link.subject,
|
||||
user.id = %user.data,
|
||||
%user.username,
|
||||
),
|
||||
err,
|
||||
)]
|
||||
pub async fn associate_link_to_user(
|
||||
executor: impl PgExecutor<'_>,
|
||||
upstream_oauth_link: &UpstreamOAuthLink,
|
||||
user: &User<PostgresqlBackend>,
|
||||
) -> Result<(), sqlx::Error> {
|
||||
sqlx::query!(
|
||||
r#"
|
||||
UPDATE upstream_oauth_links
|
||||
SET user_id = $1
|
||||
WHERE upstream_oauth_link_id = $2
|
||||
"#,
|
||||
Uuid::from(user.data),
|
||||
Uuid::from(upstream_oauth_link.id),
|
||||
)
|
||||
.execute(executor)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -17,9 +17,10 @@ mod provider;
|
||||
mod session;
|
||||
|
||||
pub use self::{
|
||||
link::{add_link, lookup_link, lookup_link_by_subject},
|
||||
link::{add_link, associate_link_to_user, lookup_link, lookup_link_by_subject},
|
||||
provider::{add_provider, lookup_provider, ProviderLookupError},
|
||||
session::{
|
||||
add_session, complete_session, lookup_session, lookup_session_on_link, SessionLookupError,
|
||||
add_session, complete_session, consume_session, lookup_session, lookup_session_on_link,
|
||||
SessionLookupError,
|
||||
},
|
||||
};
|
||||
|
@ -43,6 +43,7 @@ struct SessionAndProviderLookup {
|
||||
nonce: String,
|
||||
created_at: DateTime<Utc>,
|
||||
completed_at: Option<DateTime<Utc>>,
|
||||
consumed_at: Option<DateTime<Utc>>,
|
||||
provider_issuer: String,
|
||||
provider_scope: String,
|
||||
provider_client_id: String,
|
||||
@ -73,6 +74,7 @@ pub async fn lookup_session(
|
||||
ua.nonce,
|
||||
ua.created_at,
|
||||
ua.completed_at,
|
||||
ua.consumed_at,
|
||||
up.issuer AS "provider_issuer",
|
||||
up.scope AS "provider_scope",
|
||||
up.client_id AS "provider_client_id",
|
||||
@ -121,6 +123,7 @@ pub async fn lookup_session(
|
||||
nonce: res.nonce,
|
||||
created_at: res.created_at,
|
||||
completed_at: res.completed_at,
|
||||
consumed_at: res.consumed_at,
|
||||
};
|
||||
|
||||
Ok((provider, session))
|
||||
@ -162,8 +165,9 @@ pub async fn add_session(
|
||||
code_challenge_verifier,
|
||||
nonce,
|
||||
created_at,
|
||||
completed_at
|
||||
) VALUES ($1, $2, $3, $4, $5, $6, NULL)
|
||||
completed_at,
|
||||
consumed_at
|
||||
) VALUES ($1, $2, $3, $4, $5, $6, NULL, NULL)
|
||||
"#,
|
||||
Uuid::from(id),
|
||||
Uuid::from(upstream_oauth_provider.id),
|
||||
@ -182,6 +186,7 @@ pub async fn add_session(
|
||||
nonce,
|
||||
created_at,
|
||||
completed_at: None,
|
||||
consumed_at: None,
|
||||
})
|
||||
}
|
||||
|
||||
@ -206,9 +211,11 @@ pub async fn complete_session(
|
||||
UPDATE upstream_oauth_authorization_sessions
|
||||
SET upstream_oauth_link_id = $1,
|
||||
completed_at = $2
|
||||
WHERE upstream_oauth_authorization_session_id = $3
|
||||
"#,
|
||||
Uuid::from(upstream_oauth_link.id),
|
||||
completed_at,
|
||||
Uuid::from(upstream_oauth_authorization_session.id),
|
||||
)
|
||||
.execute(executor)
|
||||
.await?;
|
||||
@ -218,6 +225,37 @@ pub async fn complete_session(
|
||||
Ok(upstream_oauth_authorization_session)
|
||||
}
|
||||
|
||||
/// Mark a session as consumed
|
||||
#[tracing::instrument(
|
||||
skip_all,
|
||||
fields(
|
||||
%upstream_oauth_authorization_session.id,
|
||||
),
|
||||
err,
|
||||
)]
|
||||
pub async fn consume_session(
|
||||
executor: impl PgExecutor<'_>,
|
||||
clock: &Clock,
|
||||
mut upstream_oauth_authorization_session: UpstreamOAuthAuthorizationSession,
|
||||
) -> Result<UpstreamOAuthAuthorizationSession, sqlx::Error> {
|
||||
let consumed_at = clock.now();
|
||||
sqlx::query!(
|
||||
r#"
|
||||
UPDATE upstream_oauth_authorization_sessions
|
||||
SET consumed_at = $1
|
||||
WHERE upstream_oauth_authorization_session_id = $2
|
||||
"#,
|
||||
consumed_at,
|
||||
Uuid::from(upstream_oauth_authorization_session.id),
|
||||
)
|
||||
.execute(executor)
|
||||
.await?;
|
||||
|
||||
upstream_oauth_authorization_session.consumed_at = Some(consumed_at);
|
||||
|
||||
Ok(upstream_oauth_authorization_session)
|
||||
}
|
||||
|
||||
struct SessionLookup {
|
||||
upstream_oauth_authorization_session_id: Uuid,
|
||||
state: String,
|
||||
@ -225,6 +263,7 @@ struct SessionLookup {
|
||||
nonce: String,
|
||||
created_at: DateTime<Utc>,
|
||||
completed_at: Option<DateTime<Utc>>,
|
||||
consumed_at: Option<DateTime<Utc>>,
|
||||
}
|
||||
|
||||
/// Lookup a session, which belongs to a link, by its ID
|
||||
@ -250,7 +289,8 @@ pub async fn lookup_session_on_link(
|
||||
code_challenge_verifier,
|
||||
nonce,
|
||||
created_at,
|
||||
completed_at
|
||||
completed_at,
|
||||
consumed_at
|
||||
FROM upstream_oauth_authorization_sessions
|
||||
WHERE upstream_oauth_authorization_session_id = $1
|
||||
AND upstream_oauth_link_id = $2
|
||||
@ -271,5 +311,6 @@ pub async fn lookup_session_on_link(
|
||||
nonce: res.nonce,
|
||||
created_at: res.created_at,
|
||||
completed_at: res.completed_at,
|
||||
consumed_at: res.consumed_at,
|
||||
})
|
||||
}
|
||||
|
Reference in New Issue
Block a user