aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--perllib/FixMyStreet/App/Controller/Auth.pm10
-rw-r--r--perllib/FixMyStreet/App/Controller/Auth/Social.pm22
-rw-r--r--perllib/FixMyStreet/App/Controller/Report/New.pm10
-rw-r--r--perllib/FixMyStreet/App/Controller/Report/Update.pm10
-rw-r--r--t/app/controller/auth_social.t5
-rw-r--r--templates/web/base/my/my.html14
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 %]