1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
use crate::{
acquire_token_silent, msal,
msal::Msal,
requests::{AuthorizationUrlRequest, RedirectRequest, SilentRequest},
sso_silent, AuthenticationResult, Configuration, PublicClientApplication,
};
use wasm_bindgen::{JsCast, JsValue};
pub struct RedirectApp<FSuccess>
where
FSuccess: Fn(AuthenticationResult) + Clone,
{
auth: msal::PublicClientApplication,
on_redirect_success: FSuccess,
}
impl<FSuccess> Clone for RedirectApp<FSuccess>
where
FSuccess: Fn(AuthenticationResult) + Clone,
{
fn clone(&self) -> Self {
Self {
auth: self.auth.clone().into(),
on_redirect_success: self.on_redirect_success.clone(),
}
}
}
impl<FSuccess> Msal for RedirectApp<FSuccess>
where
FSuccess: Fn(AuthenticationResult) + Clone,
{
fn auth(&self) -> &msal::PublicClientApplication {
&self.auth
}
}
impl<FSuccess> PublicClientApplication for RedirectApp<FSuccess> where
FSuccess: Fn(AuthenticationResult) + Clone
{
}
impl<FSuccess> RedirectApp<FSuccess>
where
FSuccess: Fn(AuthenticationResult) + Clone,
{
pub fn new(
configuration: Configuration,
on_redirect_success: FSuccess,
) -> Self {
let auth = msal::PublicClientApplication::new(configuration.into());
Self {
auth,
on_redirect_success,
}
}
pub async fn login_redirect(&self) {
let empty: [&str; 0] = [];
self.login_redirect_with_scopes(&empty).await
}
pub async fn login_redirect_with_scopes<'a, T>(&self, scopes: &'a [T])
where
T: Into<String> + Clone,
{
match self.auth.handle_redirect_promise().await {
Ok(auth_result) => {
let auth_res = auth_result.unchecked_into::<msal::AuthenticationResult>();
if auth_res.is_undefined() || auth_res.is_null() {
self.auth.login_redirect(scopes.into())
} else {
(self.on_redirect_success)(auth_res.into())
}
}
Err(_) => {
}
}
}
pub async fn acquire_token_redirect<'a>(&self, request: &'a RedirectRequest<'a>) {
self.auth.acquire_token_redirect(request.into())
}
pub async fn sso_silent<'a>(
&self,
request: &'a AuthorizationUrlRequest<'a>,
) -> Result<AuthenticationResult, JsValue> {
sso_silent(&self.auth, request).await
}
pub async fn acquire_token_silent<'a>(
&self,
request: &'a SilentRequest<'a>,
) -> Result<AuthenticationResult, JsValue> {
acquire_token_silent(&self.auth, request).await
}
}
#[cfg(test)]
mod tests {
wasm_bindgen_test_configure!(run_in_browser);
use super::*;
use crate::{tests::*, BrowserAuthOptions};
use wasm_bindgen_test::*;
#[allow(unused_must_use)]
#[wasm_bindgen_test]
fn login_redirect() {
let b = BrowserAuthOptions::new(tests::CLIENT_ID)
.set_authority(AUTHORITY)
.set_redirect_uri(REDIRECT_URI);
let config = Configuration::new(b);
let client_app = RedirectApp::new(config, |_| ());
client_app.login_redirect();
}
}