simple_oauth/common/
oidc.rs1use crate::{
2 SimpleOAuthError, SimpleOAuthProvider,
3 types::{OidcDiscovery, OidcUserInfo, UserInfo},
4};
5
6#[derive(Debug, Clone)]
7pub struct Oidc {
8 auth_endpoint: String,
9 token_endpoint: String,
10 userinfo_endpoint: String,
11}
12
13impl Oidc {
14 pub fn from_config(config: OidcDiscovery) -> Self {
15 Self {
16 auth_endpoint: config.authorization_endpoint,
17 token_endpoint: config.token_endpoint,
18 userinfo_endpoint: config.userinfo_endpoint,
19 }
20 }
21
22 pub async fn discover(
25 http_client: &reqwest::Client,
26 discovery_url: &str,
27 ) -> Result<Self, SimpleOAuthError> {
28 let discovery = http_client
29 .get(discovery_url)
30 .send()
31 .await?
32 .error_for_status()?
33 .json::<OidcDiscovery>()
34 .await?;
35
36 Ok(Self {
37 auth_endpoint: discovery.authorization_endpoint,
38 token_endpoint: discovery.token_endpoint,
39 userinfo_endpoint: discovery.userinfo_endpoint,
40 })
41 }
42}
43
44impl SimpleOAuthProvider for Oidc {
45 fn authorize_url(&self) -> &str {
46 &self.auth_endpoint
47 }
48
49 fn token_url(&self) -> &str {
50 &self.token_endpoint
51 }
52
53 fn user_info_url(&self) -> &str {
54 &self.userinfo_endpoint
55 }
56
57 fn default_scopes(&self) -> &'static [&'static str] {
58 &["openid", "profile"]
59 }
60
61 fn extract_user_info(&self, val: serde_json::Value) -> Result<UserInfo, serde_json::Error> {
62 let user_info: OidcUserInfo = serde_json::from_value(val)?;
63
64 Ok(UserInfo {
65 id: user_info.sub,
66 name: user_info.name,
67 username: user_info.preferred_username,
68 email: user_info.email,
69 email_verified: user_info.email_verified,
70 avatar_url: user_info.picture,
71 groups: user_info.groups,
72 })
73 }
74}