1
- use std:: sync:: atomic :: { AtomicBool , Ordering } ;
1
+ use std:: sync:: RwLock ;
2
2
use wp_api:: auth:: { ModifiableAuthenticationProvider , WpDynamicAuthenticationProvider } ;
3
3
use wp_api_integration_tests:: prelude:: * ;
4
4
@@ -20,27 +20,79 @@ async fn test_static_auth_provider() {
20
20
assert_eq ! ( FIRST_USER_ID , user. id) ;
21
21
}
22
22
23
- #[ tokio:: test]
24
- #[ parallel]
25
- async fn test_dynamic_auth_provider ( ) {
26
- #[ derive( Default ) ]
27
- struct DynamicAuthProvider {
28
- is_authorized : AtomicBool ,
23
+ #[ derive( Debug ) ]
24
+ struct DynamicAuthProvider {
25
+ auth : RwLock < WpAuthentication > ,
26
+ refreshed_auth : RwLock < Option < WpAuthentication > > ,
27
+ }
28
+
29
+ impl DynamicAuthProvider {
30
+ fn new ( ) -> Self {
31
+ Self {
32
+ auth : RwLock :: new ( WpAuthentication :: None ) ,
33
+ refreshed_auth : RwLock :: new ( None ) ,
34
+ }
35
+ }
36
+
37
+ fn authenticate_with ( & self , auth : WpAuthentication ) {
38
+ * ( self . auth . write ( ) . unwrap ( ) ) = auth;
39
+ }
40
+
41
+ fn allow_refresh_auth ( & self , auth : WpAuthentication ) {
42
+ * ( self . refreshed_auth . write ( ) . unwrap ( ) ) = Some ( auth) ;
43
+ }
44
+ }
45
+
46
+ #[ async_trait:: async_trait]
47
+ impl WpDynamicAuthenticationProvider for DynamicAuthProvider {
48
+ fn auth ( & self ) -> WpAuthentication {
49
+ self . auth . read ( ) . unwrap ( ) . clone ( )
29
50
}
30
51
31
- impl WpDynamicAuthenticationProvider for DynamicAuthProvider {
32
- fn auth ( & self ) -> WpAuthentication {
33
- if self . is_authorized . load ( Ordering :: Relaxed ) {
34
- WpAuthentication :: from_username_and_password (
35
- TestCredentials :: instance ( ) . admin_username . to_string ( ) ,
36
- TestCredentials :: instance ( ) . admin_password . to_string ( ) ,
37
- )
38
- } else {
39
- WpAuthentication :: None
40
- }
52
+ async fn refresh ( & self ) -> bool {
53
+ if let Some ( ref auth) = * ( self . refreshed_auth . read ( ) . unwrap ( ) ) {
54
+ * ( self . auth . write ( ) . unwrap ( ) ) = auth. clone ( ) ;
55
+ return true ;
56
+ } else {
57
+ return false ;
41
58
}
42
59
}
43
- let dynamic_auth_provider = Arc :: new ( DynamicAuthProvider :: default ( ) ) ;
60
+ }
61
+
62
+ #[ tokio:: test]
63
+ #[ parallel]
64
+ async fn test_dynamic_auth_provider ( ) {
65
+ let dynamic_auth_provider = Arc :: new ( DynamicAuthProvider :: new ( ) ) ;
66
+ let client: WpApiClient = api_client_with_auth_provider ( Arc :: new (
67
+ WpAuthenticationProvider :: dynamic ( dynamic_auth_provider. clone ( ) ) ,
68
+ ) ) ;
69
+
70
+ // Assert that initial unauthorized request fails
71
+ client
72
+ . users ( )
73
+ . retrieve_me_with_edit_context ( )
74
+ . await
75
+ . assert_wp_error ( WpErrorCode :: Unauthorized ) ;
76
+
77
+ // Assert that request succeeds after providing a valid authentication
78
+ dynamic_auth_provider. authenticate_with ( WpAuthentication :: from_username_and_password (
79
+ TestCredentials :: instance ( ) . admin_username . to_string ( ) ,
80
+ TestCredentials :: instance ( ) . admin_password . to_string ( ) ,
81
+ ) ) ;
82
+ let user = client
83
+ . users ( )
84
+ . retrieve_me_with_edit_context ( )
85
+ . await
86
+ . assert_response ( )
87
+ . data ;
88
+ // FIRST_USER_ID is the current user's id
89
+ assert_eq ! ( FIRST_USER_ID , user. id) ;
90
+ }
91
+
92
+ #[ tokio:: test]
93
+ #[ parallel]
94
+ async fn test_refresh_dynamic_auth_provider ( ) {
95
+ let dynamic_auth_provider = Arc :: new ( DynamicAuthProvider :: new ( ) ) ;
44
96
let client: WpApiClient = api_client_with_auth_provider ( Arc :: new (
45
97
WpAuthenticationProvider :: dynamic ( dynamic_auth_provider. clone ( ) ) ,
46
98
) ) ;
@@ -52,10 +104,13 @@ async fn test_dynamic_auth_provider() {
52
104
. await
53
105
. assert_wp_error ( WpErrorCode :: Unauthorized ) ;
54
106
55
- // Assert that request succeeds after setting `is_authorized = true`
56
- dynamic_auth_provider
57
- . is_authorized
58
- . store ( true , Ordering :: Relaxed ) ;
107
+ // Set the refreshed authentication
108
+ dynamic_auth_provider. allow_refresh_auth ( WpAuthentication :: from_username_and_password (
109
+ TestCredentials :: instance ( ) . admin_username . to_string ( ) ,
110
+ TestCredentials :: instance ( ) . admin_password . to_string ( ) ,
111
+ ) ) ;
112
+
113
+ // Assert that request succeeds after refresh
59
114
let user = client
60
115
. users ( )
61
116
. retrieve_me_with_edit_context ( )
0 commit comments