rustauth_oauth/oauth2/
types.rs1use url::Url;
2
3use super::error::OAuthError;
4
5#[derive(Debug, Clone, PartialEq, Eq)]
6pub struct AuthorizationEndpoint(String);
7
8#[derive(Debug, Clone, PartialEq, Eq)]
9pub struct TokenEndpoint(String);
10
11#[derive(Debug, Clone, PartialEq, Eq)]
12pub struct RedirectUri(String);
13
14#[derive(Clone, PartialEq, Eq)]
15pub struct ClientSecret(String);
16
17impl AuthorizationEndpoint {
18 pub fn new(value: impl Into<String>) -> Result<Self, OAuthError> {
19 validated_absolute_url(value).map(Self)
20 }
21
22 pub fn as_str(&self) -> &str {
23 &self.0
24 }
25}
26
27impl TokenEndpoint {
28 pub fn new(value: impl Into<String>) -> Result<Self, OAuthError> {
29 validated_absolute_url(value).map(Self)
30 }
31
32 pub fn as_str(&self) -> &str {
33 &self.0
34 }
35}
36
37impl RedirectUri {
38 pub fn new(value: impl Into<String>) -> Result<Self, OAuthError> {
39 validated_absolute_url(value).map(Self)
40 }
41
42 pub fn as_str(&self) -> &str {
43 &self.0
44 }
45}
46
47impl ClientSecret {
48 pub fn new(value: impl Into<String>) -> Result<Self, OAuthError> {
49 let value = value.into();
50 if value.is_empty() {
51 return Err(OAuthError::MissingOption("client_secret"));
52 }
53 Ok(Self(value))
54 }
55
56 pub fn expose_secret(&self) -> &str {
57 &self.0
58 }
59}
60
61impl std::fmt::Debug for ClientSecret {
62 fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
63 formatter.write_str("ClientSecret(<redacted>)")
64 }
65}
66
67fn validated_absolute_url(value: impl Into<String>) -> Result<String, OAuthError> {
68 let value = value.into();
69 let url = Url::parse(&value)?;
70 if url.scheme() != "https" && url.scheme() != "http" {
71 return Err(OAuthError::InvalidConfiguration(format!(
72 "unsupported URL scheme `{}`",
73 url.scheme()
74 )));
75 }
76 Ok(value)
77}