Skip to main content

oauth_toolkit/
redirect.rs

1//! Redirect URI validation for OAuth2.
2
3/// Exact-match a redirect URI against a registered allowlist.
4pub fn redirect_uri_allowed(requested: &str, registered: &[String]) -> bool {
5    registered.iter().any(|r| r == requested)
6}
7
8/// Build a provider callback redirect URI from a base URL and provider name.
9///
10/// Returns `"{base_url}/auth/callback/{provider}"`.
11pub fn build_redirect_uri(base_url: &str, provider: &str) -> String {
12    format!(
13        "{}/auth/callback/{}",
14        base_url.trim_end_matches('/'),
15        provider
16    )
17}
18
19#[cfg(test)]
20mod tests {
21    use super::*;
22
23    #[test]
24    fn redirect_uri_allowed_exact() {
25        assert!(redirect_uri_allowed(
26            "https://app.com/callback",
27            &["https://app.com/callback".into()]
28        ));
29    }
30
31    #[test]
32    fn redirect_uri_allowed_mismatch() {
33        assert!(!redirect_uri_allowed(
34            "https://evil.com/callback",
35            &["https://app.com/callback".into()]
36        ));
37    }
38
39    #[test]
40    fn redirect_uri_allowed_empty() {
41        assert!(!redirect_uri_allowed("https://app.com", &[]));
42    }
43
44    #[test]
45    fn build_redirect_uri_works() {
46        assert_eq!(
47            build_redirect_uri("https://app.com", "github"),
48            "https://app.com/auth/callback/github"
49        );
50    }
51
52    #[test]
53    fn build_redirect_uri_trailing_slash() {
54        assert_eq!(
55            build_redirect_uri("https://app.com/", "google"),
56            "https://app.com/auth/callback/google"
57        );
58    }
59}