@@ -122,210 +122,3 @@ impl From<OpenIdProfileResponse> for Profile {
122122 }
123123 }
124124}
125-
126- #[ cfg( test) ]
127- mod tests {
128- use super :: * ;
129-
130- use std:: sync:: mpsc:: channel;
131- use std:: thread:: JoinHandle ;
132-
133- use actix:: System ;
134- use actix_web:: { dev:: Server , web, App , HttpRequest , HttpResponse , HttpServer } ;
135- use futures:: Future ;
136-
137- const USERINFO_ENDPOINT : & str = "/userinfo" ;
138- const ALL_DETAILS_TOKEN : & str = "all_details" ;
139- const ONLY_SUB_TOKEN : & str = "only_sub" ;
140- const UNEXPECTED_RESPONSE_CODE_TOKEN : & str = "unexpected_response_code" ;
141- const INVALID_RESPONSE_TOKEN : & str = "invalid_response" ;
142- const SUB : & str = "sub" ;
143- const NAME : & str = "name" ;
144- const GIVEN_NAME : & str = "given_name" ;
145- const FAMILY_NAME : & str = "family_name" ;
146- const EMAIL : & str = "email" ;
147- const PICTURE : & str = "picture" ;
148-
149- /// Verifies that the OpenID profile provider correctly returns all relevant profile information
150- /// when it's provided.
151- ///
152- /// 1. Start the mock OpenID server
153- /// 2. Get the profile for a user with all details filled out
154- /// 3. Verify that all profile details are correct
155- /// 4. Shutdown the OpenID server
156- #[ test]
157- fn all_details ( ) {
158- let ( shutdown_handle, address) = run_mock_openid_server ( "all_details" ) ;
159-
160- let profile = OpenIdProfileProvider :: new ( format ! ( "{}{}" , address, USERINFO_ENDPOINT ) )
161- . get_profile ( ALL_DETAILS_TOKEN )
162- . expect ( "Failed to get profile" )
163- . expect ( "Profile not found" ) ;
164-
165- assert_eq ! ( & profile. subject, SUB ) ;
166- assert_eq ! ( profile. name. as_deref( ) , Some ( NAME ) ) ;
167- assert_eq ! ( profile. given_name. as_deref( ) , Some ( GIVEN_NAME ) ) ;
168- assert_eq ! ( profile. family_name. as_deref( ) , Some ( FAMILY_NAME ) ) ;
169- assert_eq ! ( profile. email. as_deref( ) , Some ( EMAIL ) ) ;
170- assert_eq ! ( profile. picture. as_deref( ) , Some ( PICTURE ) ) ;
171-
172- shutdown_handle. shutdown ( ) ;
173- }
174-
175- /// Verifies that the OpenID profile provider correctly returns the profile when only the
176- /// subject is provided
177- ///
178- /// 1. Start the mock OpenID server
179- /// 2. Get the profile for a user with only the subject filled out
180- /// 3. Verify that the `subject` field is correct and all other fields are empty
181- /// 4. Shutdown the OpenID server
182- #[ test]
183- fn only_sub ( ) {
184- let ( shutdown_handle, address) = run_mock_openid_server ( "only_sub" ) ;
185-
186- let profile = OpenIdProfileProvider :: new ( format ! ( "{}{}" , address, USERINFO_ENDPOINT ) )
187- . get_profile ( ONLY_SUB_TOKEN )
188- . expect ( "Failed to get profile" )
189- . expect ( "Profile not found" ) ;
190-
191- assert_eq ! ( & profile. subject, SUB ) ;
192- assert ! ( profile. name. is_none( ) ) ;
193- assert ! ( profile. given_name. is_none( ) ) ;
194- assert ! ( profile. family_name. is_none( ) ) ;
195- assert ! ( profile. email. is_none( ) ) ;
196- assert ! ( profile. picture. is_none( ) ) ;
197-
198- shutdown_handle. shutdown ( ) ;
199- }
200-
201- /// Verifies that the OpenID profile provider correctly returns `Ok(None)` when receiving a
202- /// `401 Unauthorized` response from the OpenID server (which means the token is unknown).
203- ///
204- /// 1. Start the mock OpenID server
205- /// 2. Attempt to get the profile for an unknown token
206- /// 3. Verify that the profile provider returns the correct value
207- /// 4. Shutdown the OpenID server
208- #[ test]
209- fn unauthorized_token ( ) {
210- let ( shutdown_handle, address) = run_mock_openid_server ( "unauthorized_token" ) ;
211-
212- let profile_opt = OpenIdProfileProvider :: new ( format ! ( "{}{}" , address, USERINFO_ENDPOINT ) )
213- . get_profile ( "unknown_token" )
214- . expect ( "Failed to get profile" ) ;
215-
216- assert ! ( profile_opt. is_none( ) ) ;
217-
218- shutdown_handle. shutdown ( ) ;
219- }
220-
221- /// Verifies that the OpenID profile provider correctly returns an error when receiving an
222- /// unexpected response code from the OpenID server.
223- ///
224- /// 1. Start the mock OpenID server
225- /// 2. Attempt to get the profile for a token that the server will return a non-200 and non-401
226- /// response for
227- /// 3. Verify that the profile provider returns an error
228- /// 4. Shutdown the OpenID server
229- #[ test]
230- fn unexpected_response_code ( ) {
231- let ( shutdown_handle, address) = run_mock_openid_server ( "unauthorized_token" ) ;
232-
233- let profile_res = OpenIdProfileProvider :: new ( format ! ( "{}{}" , address, USERINFO_ENDPOINT ) )
234- . get_profile ( UNEXPECTED_RESPONSE_CODE_TOKEN ) ;
235-
236- assert ! ( profile_res. is_err( ) ) ;
237-
238- shutdown_handle. shutdown ( ) ;
239- }
240-
241- /// Verifies that the OpenID profile provider correctly returns an error when receiving a
242- /// response that doesn't contain the `sub` field.
243- ///
244- /// 1. Start the mock OpenID server
245- /// 2. Attempt to get the profile for a token that the server will return an invalid response
246- /// for
247- /// 3. Verify that the profile provider returns an error
248- /// 4. Shutdown the OpenID server
249- #[ test]
250- fn invalid_response ( ) {
251- let ( shutdown_handle, address) = run_mock_openid_server ( "unauthorized_token" ) ;
252-
253- let profile_res = OpenIdProfileProvider :: new ( format ! ( "{}{}" , address, USERINFO_ENDPOINT ) )
254- . get_profile ( INVALID_RESPONSE_TOKEN ) ;
255-
256- assert ! ( profile_res. is_err( ) ) ;
257-
258- shutdown_handle. shutdown ( ) ;
259- }
260-
261- /// Runs a mock OAuth OpenID server and returns its shutdown handle along with the address the
262- /// server is running on.
263- fn run_mock_openid_server ( test_name : & str ) -> ( OpenIDServerShutdownHandle , String ) {
264- let ( tx, rx) = channel ( ) ;
265-
266- let instance_name = format ! ( "OpenID-Server-{}" , test_name) ;
267- let join_handle = std:: thread:: Builder :: new ( )
268- . name ( instance_name. clone ( ) )
269- . spawn ( move || {
270- let sys = System :: new ( instance_name) ;
271- let server = HttpServer :: new ( || {
272- App :: new ( ) . service ( web:: resource ( USERINFO_ENDPOINT ) . to ( userinfo_endpoint) )
273- } )
274- . bind ( "127.0.0.1:0" )
275- . expect ( "Failed to bind OpenID server" ) ;
276- let address = format ! ( "http://127.0.0.1:{}" , server. addrs( ) [ 0 ] . port( ) ) ;
277- let server = server. disable_signals ( ) . system_exit ( ) . start ( ) ;
278- tx. send ( ( server, address) ) . expect ( "Failed to send server" ) ;
279- sys. run ( ) . expect ( "OpenID server runtime failed" ) ;
280- } )
281- . expect ( "Failed to spawn OpenID server thread" ) ;
282-
283- let ( server, address) = rx. recv ( ) . expect ( "Failed to receive server" ) ;
284-
285- ( OpenIDServerShutdownHandle ( server, join_handle) , address)
286- }
287-
288- /// The handler for the OpenID server's user info endpoint.
289- fn userinfo_endpoint ( req : HttpRequest ) -> HttpResponse {
290- match req
291- . headers ( )
292- . get ( "Authorization" )
293- . and_then ( |auth| auth. to_str ( ) . ok ( ) )
294- . and_then ( |auth_str| auth_str. strip_prefix ( "Bearer " ) )
295- {
296- Some ( token) if token == ALL_DETAILS_TOKEN => HttpResponse :: Ok ( )
297- . content_type ( "application/json" )
298- . json ( json ! ( {
299- "sub" : SUB ,
300- "name" : NAME ,
301- "given_name" : GIVEN_NAME ,
302- "family_name" : FAMILY_NAME ,
303- "email" : EMAIL ,
304- "picture" : PICTURE ,
305- } ) ) ,
306- Some ( token) if token == ONLY_SUB_TOKEN => HttpResponse :: Ok ( )
307- . content_type ( "application/json" )
308- . json ( json ! ( {
309- "sub" : SUB ,
310- } ) ) ,
311- Some ( token) if token == UNEXPECTED_RESPONSE_CODE_TOKEN => {
312- HttpResponse :: BadRequest ( ) . finish ( )
313- }
314- Some ( token) if token == INVALID_RESPONSE_TOKEN => HttpResponse :: Ok ( ) . finish ( ) ,
315- Some ( _) => HttpResponse :: Unauthorized ( ) . finish ( ) ,
316- None => HttpResponse :: BadRequest ( ) . finish ( ) ,
317- }
318- }
319-
320- struct OpenIDServerShutdownHandle ( Server , JoinHandle < ( ) > ) ;
321-
322- impl OpenIDServerShutdownHandle {
323- pub fn shutdown ( self ) {
324- self . 0
325- . stop ( false )
326- . wait ( )
327- . expect ( "Failed to stop OpenID server" ) ;
328- self . 1 . join ( ) . expect ( "OpenID server thread failed" ) ;
329- }
330- }
331- }
0 commit comments