yew_oauth2/components/context/
mod.rs1mod agent;
4
5pub use agent::*;
6
7use crate::{
8 agent::{AgentConfiguration, Client, LoginOptions, LogoutOptions, OAuth2Operations},
9 context::{LatestAccessToken, OAuth2Context},
10};
11use agent::Agent as AgentContext;
12use std::time::Duration;
13use yew::prelude::*;
14
15#[derive(Clone, Debug, Properties)]
17pub struct OAuth2Properties<C: Client> {
18 pub config: C::Configuration,
20
21 #[prop_or_default]
23 pub scopes: Vec<String>,
24
25 #[prop_or(Duration::from_secs(30))]
29 pub grace_period: Duration,
30
31 #[prop_or_default]
37 pub max_expiration: Option<Duration>,
38
39 #[prop_or_default]
41 pub audience: Option<String>,
42
43 #[prop_or_default]
45 pub children: Children,
46
47 #[prop_or_default]
49 pub login_options: Option<LoginOptions>,
50
51 #[prop_or_default]
53 pub logout_options: Option<LogoutOptions>,
54}
55
56impl<C: Client> PartialEq for OAuth2Properties<C> {
57 fn eq(&self, other: &Self) -> bool {
58 self.config == other.config
59 && self.scopes == other.scopes
60 && self.grace_period == other.grace_period
61 && self.max_expiration == other.max_expiration
62 && self.audience == other.audience
63 && self.children == other.children
64 }
65}
66
67pub struct OAuth2<C: Client> {
71 context: OAuth2Context,
72 latest_access_token: LatestAccessToken,
73 agent: AgentContext<C>,
74 config: AgentConfiguration<C>,
75}
76
77#[doc(hidden)]
78pub enum Msg {
79 Context(OAuth2Context),
80}
81
82impl<C: Client> Component for OAuth2<C> {
83 type Message = Msg;
84 type Properties = OAuth2Properties<C>;
85
86 fn create(ctx: &Context<Self>) -> Self {
87 let config = Self::make_config(ctx.props());
88 let callback = ctx.link().callback(Msg::Context);
89
90 let agent = crate::agent::Agent::new(move |s| callback.emit(s));
91 let _ = agent.configure(config.clone());
92
93 Self {
94 context: OAuth2Context::NotInitialized,
95 latest_access_token: LatestAccessToken {
96 access_token: Default::default(),
97 },
98 agent: AgentContext::new(agent),
99 config,
100 }
101 }
102
103 fn update(&mut self, _ctx: &Context<Self>, msg: Self::Message) -> bool {
104 match msg {
105 Self::Message::Context(context) => {
106 if self.context != context {
107 self.latest_access_token
108 .set_access_token(context.access_token());
109 self.context = context;
110 return true;
111 }
112 }
113 }
114 false
115 }
116
117 fn changed(&mut self, ctx: &Context<Self>, _: &Self::Properties) -> bool {
118 let config = Self::make_config(ctx.props());
119 if self.config != config {
120 let _ = self.agent.configure(config.clone());
122 self.config = config;
123 }
124
125 true
126 }
127
128 fn view(&self, ctx: &Context<Self>) -> Html {
129 html!(
130 <>
131 <ContextProvider<OAuth2Context> context={self.context.clone()} >
132 <ContextProvider<AgentContext<C>> context={self.agent.clone()}>
133 <ContextProvider<LatestAccessToken> context={self.latest_access_token.clone()}>
134 { for ctx.props().children.iter() }
135 </ContextProvider<LatestAccessToken>>
136 </ContextProvider<AgentContext<C>>>
137 </ContextProvider<OAuth2Context>>
138 </>
139 )
140 }
141}
142
143impl<C: Client> OAuth2<C> {
144 fn make_config(props: &OAuth2Properties<C>) -> AgentConfiguration<C> {
145 AgentConfiguration {
146 config: props.config.clone(),
147 scopes: props.scopes.clone(),
148 grace_period: props.grace_period,
149 max_expiration: props.max_expiration,
150 audience: props.audience.clone(),
151 default_login_options: props.login_options.clone(),
152 default_logout_options: props.logout_options.clone(),
153 }
154 }
155}
156
157#[cfg(feature = "openid")]
158pub mod openid {
159 pub type OAuth2 = super::OAuth2<crate::agent::client::OpenIdClient>;
161}
162
163pub mod oauth2 {
164 pub type OAuth2 = super::OAuth2<crate::agent::client::OAuth2Client>;
166}