diff options
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Auth.pm | 10 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Auth/Social.pm | 22 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Report/New.pm | 10 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Report/Update.pm | 10 | ||||
-rw-r--r-- | t/app/controller/auth_social.t | 5 | ||||
-rw-r--r-- | templates/web/base/my/my.html | 14 |
6 files changed, 54 insertions, 17 deletions
diff --git a/perllib/FixMyStreet/App/Controller/Auth.pm b/perllib/FixMyStreet/App/Controller/Auth.pm index 964d8f19a..d4784ae8c 100644 --- a/perllib/FixMyStreet/App/Controller/Auth.pm +++ b/perllib/FixMyStreet/App/Controller/Auth.pm @@ -219,7 +219,7 @@ sub get_token : Private { sub set_oauth_token_data : Private { my ( $self, $c, $token_data ) = @_; - foreach (qw/facebook_id twitter_id oidc_id extra logout_redirect_uri/) { + foreach (qw/facebook_id twitter_id oidc_id extra logout_redirect_uri change_password_uri/) { $token_data->{$_} = $c->session->{oauth}{$_} if $c->session->{oauth}{$_}; } } @@ -291,9 +291,11 @@ sub process_login : Private { $user->update_or_insert; $c->authenticate( { $type => $data->{$type}, $ver => 1 }, 'no_password' ); - if ($data->{logout_redirect_uri}) { - $c->session->{oauth} ||= (); - $c->session->{oauth}{logout_redirect_uri} = $data->{logout_redirect_uri}; + foreach (qw/logout_redirect_uri change_password_uri/) { + if ($data->{$_}) { + $c->session->{oauth} ||= (); + $c->session->{oauth}{$_} = $data->{$_}; + } } diff --git a/perllib/FixMyStreet/App/Controller/Auth/Social.pm b/perllib/FixMyStreet/App/Controller/Auth/Social.pm index aa3177163..06e67573f 100644 --- a/perllib/FixMyStreet/App/Controller/Auth/Social.pm +++ b/perllib/FixMyStreet/App/Controller/Auth/Social.pm @@ -207,6 +207,19 @@ sub oidc_sign_in : Private { $oauth{logout_redirect_uri} = $redirect_uri; } + # The OIDC endpoint may provide a specific URI for changing the user's password. + if ( my $password_change_uri = $c->cobrand->feature('oidc_login')->{password_change_uri} ) { + $oauth{change_password_uri} = $oidc->uri_to_redirect( + uri => $password_change_uri, + redirect_uri => $c->uri_for('/auth/OIDC'), + scope => 'openid', + state => 'password_change', + extra => { + response_mode => 'form_post', + }, + ); + } + $c->session->{oauth} = \%oauth; $c->res->redirect($url); } @@ -231,6 +244,10 @@ sub oidc_callback: Path('/auth/OIDC') : Args(0) { ); $c->res->redirect($url); $c->detach; + } elsif ($c->user_exists && $c->get_param('state') && $c->get_param('state') eq 'password_change') { + $c->flash->{flash_message} = _('Password change cancelled.'); + $c->res->redirect('/my'); + $c->detach; } else { $c->detach('oauth_failure'); } @@ -250,6 +267,11 @@ sub oidc_callback: Path('/auth/OIDC') : Args(0) { $c->detach('oidc_sign_in', []); } + # User may be coming back here after changing their password on the OIDC endpoint + if ($c->user_exists && $c->get_param('state') && $c->get_param('state') eq 'password_change') { + $c->detach('/auth/profile/change_password_success', []); + } + # The only other valid state param is 'login' at this point. $c->detach('/page_error_400_bad_request', []) unless $c->get_param('state') eq 'login'; diff --git a/perllib/FixMyStreet/App/Controller/Report/New.pm b/perllib/FixMyStreet/App/Controller/Report/New.pm index a19c43af8..be812c040 100644 --- a/perllib/FixMyStreet/App/Controller/Report/New.pm +++ b/perllib/FixMyStreet/App/Controller/Report/New.pm @@ -1331,10 +1331,12 @@ sub process_confirmation : Private { $problem->user->update; - # Make sure OIDC logout redirection happens, if applicable - if ($data->{logout_redirect_uri}) { - $c->session->{oauth} ||= (); - $c->session->{oauth}{logout_redirect_uri} = $data->{logout_redirect_uri}; + # Make sure extra oauth state is restored, if applicable + foreach (qw/logout_redirect_uri change_password_uri/) { + if ($data->{$_}) { + $c->session->{oauth} ||= (); + $c->session->{oauth}{$_} = $data->{$_}; + } } } if ($problem->user->email_verified) { diff --git a/perllib/FixMyStreet/App/Controller/Report/Update.pm b/perllib/FixMyStreet/App/Controller/Report/Update.pm index 1825286ca..28a58d4f8 100644 --- a/perllib/FixMyStreet/App/Controller/Report/Update.pm +++ b/perllib/FixMyStreet/App/Controller/Report/Update.pm @@ -585,10 +585,12 @@ sub process_confirmation : Private { }) if $data->{extra}; $comment->user->password( $data->{password}, 1 ) if $data->{password}; $comment->user->update; - # Make sure OIDC logout redirection happens, if applicable - if ($data->{logout_redirect_uri}) { - $c->session->{oauth} ||= (); - $c->session->{oauth}{logout_redirect_uri} = $data->{logout_redirect_uri}; + # Make sure extra oauth state is restored, if applicable + foreach (qw/logout_redirect_uri change_password_uri/) { + if ($data->{$_}) { + $c->session->{oauth} ||= (); + $c->session->{oauth}{$_} = $data->{$_}; + } } } diff --git a/t/app/controller/auth_social.t b/t/app/controller/auth_social.t index 160d46f8f..80b700e29 100644 --- a/t/app/controller/auth_social.t +++ b/t/app/controller/auth_social.t @@ -65,6 +65,7 @@ for my $test ( auth_uri => 'http://oidc.example.org/oauth2/v2.0/authorize', token_uri => 'http://oidc.example.org/oauth2/v2.0/token', logout_uri => 'http://oidc.example.org/oauth2/v2.0/logout', + password_change_uri => 'http://oidc.example.org/oauth2/v2.0/password_change', display_name => 'MyWestminster' } } @@ -79,6 +80,7 @@ for my $test ( success_callback => '/auth/OIDC?code=response-code&state=login', redirect_pattern => qr{oidc\.example\.org/oauth2/v2\.0/authorize}, logout_redirect_pattern => qr{oidc\.example\.org/oauth2/v2\.0/logout}, + password_change_pattern => qr{oidc\.example\.org/oauth2/v2\.0/password_change}, user_extras => [ [westminster_account_id => "1c304134-ef12-c128-9212-123908123901"], ], @@ -241,6 +243,9 @@ for my $state ( 'refused', 'no email', 'existing UID', 'okay' ) { $mech->content_contains( $report->title ); $mech->content_contains( "/report/$report_id" ); } + if ($test->{type} eq 'oidc') { + ok $mech->find_link( text => 'Change password', url_regex => $test->{password_change_pattern} ); + } } $mech->get('/auth/sign_out'); diff --git a/templates/web/base/my/my.html b/templates/web/base/my/my.html index 64ddb768e..048d99ef9 100644 --- a/templates/web/base/my/my.html +++ b/templates/web/base/my/my.html @@ -60,13 +60,17 @@ li .my-account-buttons a { </ul> <p class="my-account-buttons"> + [% IF c.session.oauth.change_password_uri %] + <a href="[% c.session.oauth.change_password_uri | html %]">[% loc('Change password') %]</a> + [% ELSE %] <a href="/auth/change_password"> - [%~ IF c.user.password ~%] - [% loc('Change password') %] - [%~ ELSE ~%] - [% loc('Set password') %] - [%~ END ~%] + [%~ IF c.user.password ~%] + [% loc('Change password') %] + [%~ ELSE ~%] + [% loc('Set password') %] + [%~ END ~%] </a> + [% END %] [% IF c.user AND (c.user.from_body OR c.user.is_superuser) %] <a href="/auth/generate_token">[% loc('Security') %]</a> [% END %] |