@@ -2,6 +2,8 @@ use http::{HeaderMap, HeaderValue};
22use std:: fmt:: Debug ;
33use std:: sync:: { Arc , RwLock } ;
44
5+ use crate :: login:: url_discovery:: AutoDiscoveryAttemptFailure ;
6+ use crate :: prelude:: WpLoginClient ;
57use crate :: {
68 login:: { nonce:: WpRestNonceRetrieval , url_discovery:: AutoDiscoveryAttemptSuccess } ,
79 request:: RequestExecutor ,
@@ -86,32 +88,97 @@ impl ModifiableAuthenticationProvider {
8688 }
8789}
8890
89- #[ derive( Debug , uniffi:: Object ) ]
91+ #[ derive( uniffi:: Object ) ]
9092pub struct CookiesNonceAuthenticationProvider {
93+ site_url : String ,
9194 username : String ,
9295 password : String ,
93- nonce_retrieval : Arc < WpRestNonceRetrieval > ,
96+ request_executor : Arc < dyn RequestExecutor > ,
97+ nonce_retrieval : RwLock < Option < Arc < WpRestNonceRetrieval > > > ,
9498 auth : RwLock < WpAuthentication > ,
9599}
96100
97101#[ uniffi:: export]
98102impl CookiesNonceAuthenticationProvider {
99- #[ uniffi:: constructor]
103+ #[ uniffi:: constructor( name = "new" ) ]
100104 pub fn new (
101105 username : String ,
102106 password : String ,
103107 details : AutoDiscoveryAttemptSuccess ,
104108 request_executor : Arc < dyn RequestExecutor > ,
105109 ) -> Self {
106110 Self {
111+ site_url : details. api_details . site_url_string ( ) ,
112+ username,
113+ password,
114+ request_executor : request_executor. clone ( ) ,
115+ nonce_retrieval : RwLock :: new ( Some ( Arc :: new ( WpRestNonceRetrieval :: new (
116+ details,
117+ request_executor. clone ( ) ,
118+ ) ) ) ) ,
119+ auth : RwLock :: new ( WpAuthentication :: None ) ,
120+ }
121+ }
122+
123+ #[ uniffi:: constructor( name = "with_site_url" ) ]
124+ pub fn with_site_url (
125+ url : String ,
126+ username : String ,
127+ password : String ,
128+ request_executor : Arc < dyn RequestExecutor > ,
129+ ) -> Self {
130+ Self {
131+ site_url : url,
107132 username,
108133 password,
109- nonce_retrieval : Arc :: new ( WpRestNonceRetrieval :: new ( details, request_executor) ) ,
134+ request_executor,
135+ nonce_retrieval : RwLock :: new ( None ) ,
110136 auth : RwLock :: new ( WpAuthentication :: None ) ,
111137 }
112138 }
113139}
114140
141+ impl CookiesNonceAuthenticationProvider {
142+ fn get_nonce_retrieval ( & self ) -> Option < Arc < WpRestNonceRetrieval > > {
143+ self . nonce_retrieval
144+ . read ( )
145+ . expect ( "If the lock is poisoned, there isn't much we can do" )
146+ . as_ref ( )
147+ . cloned ( )
148+ }
149+
150+ async fn create_nonce_retrieval_if_needed (
151+ & self ,
152+ ) -> Result < Arc < WpRestNonceRetrieval > , AutoDiscoveryAttemptFailure > {
153+ if let Some ( nonce_retrieval) = self . get_nonce_retrieval ( ) {
154+ return Ok ( nonce_retrieval) ;
155+ }
156+
157+ let client =
158+ WpLoginClient :: new_with_default_middleware_pipeline ( self . request_executor . clone ( ) ) ;
159+ let result = client. api_discovery ( self . site_url . clone ( ) ) . await ;
160+ let details = match result. combined_result ( ) {
161+ Ok ( details) => details. clone ( ) ,
162+ Err ( err) => {
163+ return Err ( err. clone ( ) ) ;
164+ }
165+ } ;
166+
167+ let nonce_retrieval = Arc :: new ( WpRestNonceRetrieval :: new (
168+ details,
169+ self . request_executor . clone ( ) ,
170+ ) ) ;
171+
172+ * self
173+ . nonce_retrieval
174+ . write ( )
175+ . expect ( "If the lock is poisoned, there isn't much we can do" ) =
176+ Some ( nonce_retrieval. clone ( ) ) ;
177+ Ok ( nonce_retrieval)
178+ }
179+ }
180+
181+ #[ uniffi:: export]
115182#[ async_trait:: async_trait]
116183impl WpDynamicAuthenticationProvider for CookiesNonceAuthenticationProvider {
117184 fn auth ( & self ) -> WpAuthentication {
@@ -122,8 +189,12 @@ impl WpDynamicAuthenticationProvider for CookiesNonceAuthenticationProvider {
122189 }
123190
124191 async fn refresh ( & self ) -> bool {
125- match self
126- . nonce_retrieval
192+ let nonce_retrieval = match self . create_nonce_retrieval_if_needed ( ) . await {
193+ Ok ( value) => value,
194+ Err ( _) => return false ,
195+ } ;
196+
197+ match nonce_retrieval
127198 . get_nonce ( self . username . clone ( ) , self . password . clone ( ) )
128199 . await
129200 {
@@ -140,6 +211,15 @@ impl WpDynamicAuthenticationProvider for CookiesNonceAuthenticationProvider {
140211 }
141212}
142213
214+ impl Debug for CookiesNonceAuthenticationProvider {
215+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
216+ f. debug_struct ( "CookiesNonceAuthenticationProvider" )
217+ . field ( "site_url" , & self . site_url )
218+ . field ( "username" , & self . username )
219+ . finish ( )
220+ }
221+ }
222+
143223#[ uniffi:: export( with_foreign) ]
144224#[ async_trait:: async_trait]
145225pub trait WpDynamicAuthenticationProvider : Send + Sync + Debug {
0 commit comments