From 973140d25b6882031f1de8010da589b94971988b Mon Sep 17 00:00:00 2001 From: Karen Etheridge Date: Wed, 13 Jan 2021 15:38:40 -0800 Subject: [PATCH 1/4] remove hack code for GET /hardware_product/specification/latest ..this should have been removed with commit 38e0ca3f66f. --- lib/Conch/Controller/JSONSchema.pm | 6 ------ 1 file changed, 6 deletions(-) diff --git a/lib/Conch/Controller/JSONSchema.pm b/lib/Conch/Controller/JSONSchema.pm index fe530e5ef..837c723e1 100644 --- a/lib/Conch/Controller/JSONSchema.pm +++ b/lib/Conch/Controller/JSONSchema.pm @@ -91,12 +91,6 @@ sub get_from_disk ($c) { $bundled_schema->{'$id'} = $c->url_for('/json_schema/'.$type.'/'.$name)->to_abs; $bundled_schema->{'$schema'} //= 'https://json-schema.org/draft/2019-09/schema'; - # hack! remove when adding get-from-database functionality - if ($c->req->url->path =~ qr{^/json_schema/hardware_product/specification/(?:1|latest)$}) { - $bundled_schema->{'$id'} = $c->url_for->path('1')->to_abs; - delete $bundled_schema->{deprecated}; - } - $c->res->headers->content_type('application/schema+json'); return $c->status(200, $bundled_schema); } From de20b2a973a11b59aaa9ee41bad09eb4e1c5622f Mon Sep 17 00:00:00 2001 From: Karen Etheridge Date: Fri, 15 Jan 2021 13:09:23 -0800 Subject: [PATCH 2/4] fix docs --- docs/modules/Conch::Controller::User.md | 2 +- docs/modules/Conch::Route::JSONSchema.md | 3 ++- docs/modules/Conch::Route::User.md | 6 +++--- lib/Conch/Controller/User.pm | 2 +- lib/Conch/Route/JSONSchema.pm | 3 ++- lib/Conch/Route/User.pm | 6 +++--- 6 files changed, 12 insertions(+), 10 deletions(-) diff --git a/docs/modules/Conch::Controller::User.md b/docs/modules/Conch::Controller::User.md index 09e546486..d7c5e2de2 100644 --- a/docs/modules/Conch::Controller::User.md +++ b/docs/modules/Conch::Controller::User.md @@ -98,7 +98,7 @@ Response uses the UserDetailed json schema. ### update -Updates user attributes. System admin only. +Updates user attributes. System admin only, unless the target user is the authenticated user. Sends an email to the affected user, unless `?send_mail=0` is included in the query. The response uses the UserError json schema for some error conditions; on success, redirects to diff --git a/docs/modules/Conch::Route::JSONSchema.md b/docs/modules/Conch::Route::JSONSchema.md index 1f876398e..5a8c89433 100644 --- a/docs/modules/Conch::Route::JSONSchema.md +++ b/docs/modules/Conch::Route::JSONSchema.md @@ -29,7 +29,8 @@ Sets up the routes for /json\_schema that require authentication. Returns the JSON Schema document specified by type and name, used for validating endpoint requests and responses. -- Does not require authentication. +- Note: references to JSON Schemas that would require authentication are not bundled into +`$defs`. - Controller/Action: ["get\_from\_disk" in Conch::Controller::JSONSchema](../modules/Conch%3A%3AController%3A%3AJSONSchema#get_from_disk) - Response: a JSON Schema ([response.json#/$defs/JSONSchemaOnDisk](../json-schema/response.json#/$defs/JSONSchemaOnDisk)) (Content-Type is `application/schema+json`). diff --git a/docs/modules/Conch::Route::User.md b/docs/modules/Conch::Route::User.md index c093dc043..7c2f4b2d7 100644 --- a/docs/modules/Conch::Route::User.md +++ b/docs/modules/Conch::Route::User.md @@ -19,10 +19,10 @@ All routes require authentication. - Controller/Action: ["get" in Conch::Controller::User](../modules/Conch%3A%3AController%3A%3AUser#get) - Response: [response.json#/$defs/UserDetailed](../json-schema/response.json#/$defs/UserDetailed) -### `POST /user/:target_user_id_or_email?send_mail=<1|0>` +### `POST /user/me?send_mail=<1|0>` Optionally take the query parameter `send_mail` (defaults to `1`) to send -an email telling the user their account was updated +an email telling the user their account was updated. - Controller/Action: ["update" in Conch::Controller::User](../modules/Conch%3A%3AController%3A%3AUser#update) - Request: [request.json#/$defs/UpdateUser](../json-schema/request.json#/$defs/UpdateUser) @@ -118,7 +118,7 @@ otherwise, the user is logged out. ### `POST /user/:target_user_id_or_email?send_mail=<1|0>` Optionally take the query parameter `send_mail` (defaults to `1`) to send -an email telling the user their account was updated +an email telling the user their account was updated. - Requires system admin authorization - Controller/Action: ["update" in Conch::Controller::User](../modules/Conch%3A%3AController%3A%3AUser#update) diff --git a/lib/Conch/Controller/User.pm b/lib/Conch/Controller/User.pm index dfaa742c9..92b12da42 100644 --- a/lib/Conch/Controller/User.pm +++ b/lib/Conch/Controller/User.pm @@ -351,7 +351,7 @@ sub get ($c) { =head2 update -Updates user attributes. System admin only. +Updates user attributes. System admin only, unless the target user is the authenticated user. Sends an email to the affected user, unless C is included in the query. The response uses the UserError json schema for some error conditions; on success, redirects to diff --git a/lib/Conch/Route/JSONSchema.pm b/lib/Conch/Route/JSONSchema.pm index a7d4af25c..0caa9f043 100644 --- a/lib/Conch/Route/JSONSchema.pm +++ b/lib/Conch/Route/JSONSchema.pm @@ -107,7 +107,8 @@ requests and responses. =over 4 -=item * Does not require authentication. +=item * Note: references to JSON Schemas that would require authentication are not bundled into +C<$defs>. =item * Controller/Action: L diff --git a/lib/Conch/Route/User.pm b/lib/Conch/Route/User.pm index 2dc912477..6b9b41821 100644 --- a/lib/Conch/Route/User.pm +++ b/lib/Conch/Route/User.pm @@ -142,10 +142,10 @@ All routes require authentication. =back -=head2 C<< POST /user/:target_user_id_or_email?send_mail=<1|0> >> +=head2 C<< POST /user/me?send_mail=<1|0> >> Optionally take the query parameter C (defaults to C<1>) to send -an email telling the user their account was updated +an email telling the user their account was updated. =over 4 @@ -327,7 +327,7 @@ otherwise, the user is logged out. =head2 C<< POST /user/:target_user_id_or_email?send_mail=<1|0> >> Optionally take the query parameter C (defaults to C<1>) to send -an email telling the user their account was updated +an email telling the user their account was updated. =over 4 From 26fc1bbf62d0f2ec604d85853cf2fa61e86335c3 Mon Sep 17 00:00:00 2001 From: Karen Etheridge Date: Mon, 18 Jan 2021 14:55:20 -0800 Subject: [PATCH 3/4] disable POST /user/me for admins until the underlying issue is fixed --- lib/Conch/Controller/User.pm | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/Conch/Controller/User.pm b/lib/Conch/Controller/User.pm index 92b12da42..784fd4ad2 100644 --- a/lib/Conch/Controller/User.pm +++ b/lib/Conch/Controller/User.pm @@ -368,6 +368,12 @@ sub update ($c) { my $is_system_admin = $c->is_system_admin; + if ($is_system_admin and not $INC{'Test/More.pm'} and my $conch_ui_version = $c->req->headers->header('X-Conch-UI')) { + my ($major, $minor, $tiny) = $conch_ui_version =~ /^v(\d+)\.(\d+)(?:\.(\d+))?/; + return $c->status(403, { error => 'this api is blocked until https://github.com/joyent/conch-ui/issues/303 is fixed' }) + if $major == 4 and $minor == 1 and ($tiny//0) == 0; + } + my $user = $c->stash('target_user'); my %orig_columns = $user->get_columns; $user->set_columns($input); From 7d9117e6474604bdacb68be31602c62bada8d1b2 Mon Sep 17 00:00:00 2001 From: Karen Etheridge Date: Mon, 18 Jan 2021 15:32:19 -0800 Subject: [PATCH 4/4] if a user's email address is changed, also send an email to the old address --- lib/Conch/Controller/User.pm | 11 +++++++++++ t/integration/users.t | 18 +++++++++++++----- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/lib/Conch/Controller/User.pm b/lib/Conch/Controller/User.pm index 784fd4ad2..b09273c4b 100644 --- a/lib/Conch/Controller/User.pm +++ b/lib/Conch/Controller/User.pm @@ -409,6 +409,17 @@ sub update ($c) { orig_data => \%orig_columns, new_data => \%dirty_columns, ); + + # also send to old email address, if it was changed! + $c->send_mail( + template_file => 'updated_user_account', + From => 'noreply', + To => '"'.$orig_columns{name}.'" <'.$orig_columns{email}.'>', + Subject => 'Your Conch account has been updated', + orig_data => \%orig_columns, + new_data => \%dirty_columns, + ) + if exists $dirty_columns{email} and fc $input->{email} ne fc $orig_columns{email}; } $c->log->debug('updating user '.$user->email.': '.$c->req->text); diff --git a/t/integration/users.t b/t/integration/users.t index 8bbaf253c..38fe1ef4b 100644 --- a/t/integration/users.t +++ b/t/integration/users.t @@ -183,15 +183,23 @@ subtest 'User' => sub { { email => 'cONcH@cONCh.joyent.us' }, { name => 'conch' }; - $t->post_ok('/user/me', json => { email => 'rO_USer@cONCh.joyent.us', name => 'rO_USer' }) + $t->post_ok('/user/me', json => { email => 'rO_USer_new@cONCh.joyent.us', name => 'rO_USer' }) ->status_is(204) ->location_is('/user/'.$ro_user->id) - ->email_cmp_deeply({ - To => '"rO_USer" ', + ->email_cmp_deeply([ + { + To => '"rO_USer" ', From => 'noreply@joyent.com', Subject => 'Your Conch account has been updated', - body => re(qr/^Your account at \Q$JOYENT\E has been updated:\R\R {7}email: ro_user\@conch.joyent.us -> rO_USer\@cONCh.joyent.us\R {8}name: ro_user -> rO_USer\R\R/m), - }); + body => re(qr/^Your account at \Q$JOYENT\E has been updated:\R\R {7}email: ro_user\@conch.joyent.us -> rO_USer_new\@cONCh.joyent.us\R {8}name: ro_user -> rO_USer\R\R/m), + }, + { + To => '"ro_user" ', + From => 'noreply@joyent.com', + Subject => 'Your Conch account has been updated', + body => re(qr/^Your account at \Q$JOYENT\E has been updated:\R\R {7}email: ro_user\@conch.joyent.us -> rO_USer_new\@cONCh.joyent.us\R {8}name: ro_user -> rO_USer\R\R/m), + }, + ]); $ro_user->discard_changes;