66
77use axum:: {
88 extract:: { Form , State } ,
9- response:: { Html , IntoResponse , Response } ,
9+ response:: { IntoResponse , Response } ,
1010} ;
11- use axum_extra:: TypedHeader ;
1211use hyper:: StatusCode ;
13- use mas_axum_utils:: { SessionInfoExt , cookies:: CookieJar , csrf :: CsrfExt , sentry:: SentryEventID } ;
12+ use mas_axum_utils:: { SessionInfoExt , cookies:: CookieJar , sentry:: SentryEventID } ;
1413use mas_data_model:: { AuthorizationCode , Pkce } ;
15- use mas_keystore:: Keystore ;
16- use mas_policy:: Policy ;
1714use mas_router:: { PostAuthAction , UrlBuilder } ;
1815use mas_storage:: {
1916 BoxClock , BoxRepository , BoxRng ,
2017 oauth2:: { OAuth2AuthorizationGrantRepository , OAuth2ClientRepository } ,
2118} ;
22- use mas_templates:: { PolicyViolationContext , TemplateContext , Templates } ;
19+ use mas_templates:: Templates ;
2320use oauth2_types:: {
2421 errors:: { ClientError , ClientErrorCode } ,
2522 pkce,
@@ -29,9 +26,8 @@ use oauth2_types::{
2926use rand:: { Rng , distributions:: Alphanumeric } ;
3027use serde:: Deserialize ;
3128use thiserror:: Error ;
32- use tracing:: warn;
3329
34- use self :: { callback:: CallbackDestination , complete :: GrantCompletionError } ;
30+ use self :: callback:: CallbackDestination ;
3531use crate :: { BoundActivityTracker , PreferredLanguage , impl_from_error_for_route} ;
3632
3733mod callback;
@@ -134,10 +130,7 @@ pub(crate) async fn get(
134130 clock : BoxClock ,
135131 PreferredLanguage ( locale) : PreferredLanguage ,
136132 State ( templates) : State < Templates > ,
137- State ( key_store) : State < Keystore > ,
138133 State ( url_builder) : State < UrlBuilder > ,
139- policy : Policy ,
140- user_agent : Option < TypedHeader < headers:: UserAgent > > ,
141134 activity_tracker : BoundActivityTracker ,
142135 mut repo : BoxRepository ,
143136 cookie_jar : CookieJar ,
@@ -166,9 +159,6 @@ pub(crate) async fn get(
166159
167160 // Get the session info from the cookie
168161 let ( session_info, cookie_jar) = cookie_jar. session_info ( ) ;
169- let ( csrf_token, cookie_jar) = cookie_jar. csrf_token ( & clock, & mut rng) ;
170-
171- let user_agent = user_agent. map ( |TypedHeader ( ua) | ua. to_string ( ) ) ;
172162
173163 // One day, we will have try blocks
174164 let res: Result < Response , RouteError > = ( {
@@ -235,8 +225,8 @@ pub(crate) async fn get(
235225 . await ?) ;
236226 }
237227
238- // Fail early if prompt=none and there is no active session
239- if prompt. contains ( & Prompt :: None ) && maybe_session . is_none ( ) {
228+ // Fail early if prompt=none; we never let it go through
229+ if prompt. contains ( & Prompt :: None ) {
240230 return Ok ( callback_destination
241231 . go (
242232 & templates,
@@ -287,8 +277,6 @@ pub(crate) async fn get(
287277 None
288278 } ;
289279
290- let requires_consent = prompt. contains ( & Prompt :: Consent ) ;
291-
292280 let grant = repo
293281 . oauth2_authorization_grant ( )
294282 . add (
@@ -300,151 +288,43 @@ pub(crate) async fn get(
300288 code,
301289 params. auth . state . clone ( ) ,
302290 params. auth . nonce ,
303- params. auth . max_age ,
304291 response_mode,
305292 response_type. has_id_token ( ) ,
306- requires_consent,
307293 params. auth . login_hint ,
308294 )
309295 . await ?;
310296 let continue_grant = PostAuthAction :: continue_grant ( grant. id ) ;
311297
312298 let res = match maybe_session {
313- // Cases where there is no active session, redirect to the relevant page
314- None if prompt. contains ( & Prompt :: None ) => {
315- // This case should already be handled earlier
316- unreachable ! ( ) ;
317- }
318299 None if prompt. contains ( & Prompt :: Create ) => {
319300 // Client asked for a registration, show the registration prompt
320301 repo. save ( ) . await ?;
321302
322- url_builder. redirect ( & mas_router:: Register :: and_then ( continue_grant) )
303+ url_builder
304+ . redirect ( & mas_router:: Register :: and_then ( continue_grant) )
323305 . into_response ( )
324306 }
307+
325308 None => {
326309 // Other cases where we don't have a session, ask for a login
327310 repo. save ( ) . await ?;
328311
329- url_builder. redirect ( & mas_router:: Login :: and_then ( continue_grant) )
312+ url_builder
313+ . redirect ( & mas_router:: Login :: and_then ( continue_grant) )
330314 . into_response ( )
331315 }
332316
333- // Special case when we already have a session but prompt=login|select_account
334- Some ( session)
335- if prompt. contains ( & Prompt :: Login )
336- || prompt. contains ( & Prompt :: SelectAccount ) =>
337- {
338- // TODO: better pages here
317+ Some ( user_session) => {
318+ // TODO: better support for prompt=create when we have a session
339319 repo. save ( ) . await ?;
340320
341- activity_tracker. record_browser_session ( & clock, & session) . await ;
342-
343- url_builder. redirect ( & mas_router:: Reauth :: and_then ( continue_grant) )
321+ activity_tracker
322+ . record_browser_session ( & clock, & user_session)
323+ . await ;
324+ url_builder
325+ . redirect ( & mas_router:: Consent ( grant. id ) )
344326 . into_response ( )
345327 }
346-
347- // Else, we immediately try to complete the authorization grant
348- Some ( user_session) if prompt. contains ( & Prompt :: None ) => {
349- activity_tracker. record_browser_session ( & clock, & user_session) . await ;
350-
351- // With prompt=none, we should get back to the client immediately
352- match self :: complete:: complete (
353- & mut rng,
354- & clock,
355- & activity_tracker,
356- user_agent,
357- repo,
358- key_store,
359- policy,
360- & url_builder,
361- grant,
362- & client,
363- & user_session,
364- )
365- . await
366- {
367- Ok ( params) => callback_destination. go ( & templates, & locale, params) . await ?,
368- Err ( GrantCompletionError :: RequiresConsent ) => {
369- callback_destination
370- . go (
371- & templates,
372- & locale,
373- ClientError :: from ( ClientErrorCode :: ConsentRequired ) ,
374- )
375- . await ?
376- }
377- Err ( GrantCompletionError :: RequiresReauth ) => {
378- callback_destination
379- . go (
380- & templates,
381- & locale,
382- ClientError :: from ( ClientErrorCode :: InteractionRequired ) ,
383- )
384- . await ?
385- }
386- Err ( GrantCompletionError :: PolicyViolation ( _grant, _res) ) => {
387- callback_destination
388- . go ( & templates, & locale, ClientError :: from ( ClientErrorCode :: AccessDenied ) )
389- . await ?
390- }
391- Err ( GrantCompletionError :: Internal ( e) ) => {
392- return Err ( RouteError :: Internal ( e) )
393- }
394- Err ( e @ GrantCompletionError :: NotPending ) => {
395- // This should never happen
396- return Err ( RouteError :: Internal ( Box :: new ( e) ) ) ;
397- }
398- }
399- }
400- Some ( user_session) => {
401- activity_tracker. record_browser_session ( & clock, & user_session) . await ;
402-
403- let grant_id = grant. id ;
404- // Else, we show the relevant reauth/consent page if necessary
405- match self :: complete:: complete (
406- & mut rng,
407- & clock,
408- & activity_tracker,
409- user_agent,
410- repo,
411- key_store,
412- policy,
413- & url_builder,
414- grant,
415- & client,
416- & user_session,
417- )
418- . await
419- {
420- Ok ( params) => callback_destination. go ( & templates, & locale, params) . await ?,
421- Err ( GrantCompletionError :: RequiresConsent ) => {
422- url_builder. redirect ( & mas_router:: Consent ( grant_id) ) . into_response ( )
423- }
424- Err ( GrantCompletionError :: PolicyViolation ( grant, res) ) => {
425- warn ! ( violation = ?res, "Authorization grant for client {} denied by policy" , client. id) ;
426-
427- let ctx = PolicyViolationContext :: for_authorization_grant ( grant, client)
428- . with_session ( user_session)
429- . with_csrf ( csrf_token. form_value ( ) )
430- . with_language ( locale) ;
431-
432- let content = templates. render_policy_violation ( & ctx) ?;
433- Html ( content) . into_response ( )
434- }
435- Err ( GrantCompletionError :: RequiresReauth ) => {
436- url_builder. redirect ( & mas_router:: Reauth :: and_then ( continue_grant) )
437- . into_response ( )
438- }
439- Err ( GrantCompletionError :: Internal ( e) ) => {
440- return Err ( RouteError :: Internal ( e) )
441- }
442- Err ( e @ GrantCompletionError :: NotPending ) => {
443- // This should never happen
444- return Err ( RouteError :: Internal ( Box :: new ( e) ) ) ;
445- }
446- }
447- }
448328 } ;
449329
450330 Ok ( res)
0 commit comments