From 4019ae163873b5fb615d0bdab2bdbaa2e3995ce0 Mon Sep 17 00:00:00 2001 From: Bill Erickson Date: Tue, 3 Apr 2018 15:49:48 -0400 Subject: [PATCH] LP#1750894 Apply user/ws settings magically Signed-off-by: Bill Erickson --- Open-ILS/examples/fm_IDL.xml | 4 +- .../lib/OpenILS/Application/Actor/Settings.pm | 133 ++++++++++++++++++++- .../Pg/upgrade/YYYY.data.workstation-settings.sql | 5 + 3 files changed, 139 insertions(+), 3 deletions(-) diff --git a/Open-ILS/examples/fm_IDL.xml b/Open-ILS/examples/fm_IDL.xml index e798ef29df..bb9f9c06ae 100644 --- a/Open-ILS/examples/fm_IDL.xml +++ b/Open-ILS/examples/fm_IDL.xml @@ -12389,13 +12389,13 @@ SELECT usr, - + diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Actor/Settings.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Actor/Settings.pm index 139c46ba53..c3a49139c1 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Actor/Settings.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Actor/Settings.pm @@ -10,6 +10,8 @@ use OpenSRF::Utils::JSON; use OpenILS::Event; my $U = "OpenILS::Application::AppUtils"; +# Setting names may only contains letters, numbers, unders, and dots. +my $name_regex = qr/[^a-zA-Z0-9_\.]/; __PACKAGE__->register_method ( method => 'retrieve_settings', @@ -60,7 +62,7 @@ sub retrieve_settings { unless ($user_id || $aou_id); # Setting names may only contains letters, numbers, unders, and dots. - s/[^a-zA-Z0-9_\.]//g foreach @$settings; + s/$name_regex//g foreach @$settings; # Encode as a db-friendly array. my $settings_str = '{' . join(',', @$settings) . '}'; @@ -108,4 +110,133 @@ sub get_context { return ($org_id, $user_id, $ws_id); } +__PACKAGE__->register_method ( + method => 'apply_user_or_ws_setting', + api_name => 'open-ils.actor.settings.apply.user_or_ws', + stream => 1, + signature => { + desc => q/ + Apply values to user or workstation settings, depending + on which is supported via local configuration. + + The API ignores nonexistent settings and only returns error + events when an auth, permission, or internal error occurs. + /, + params => [ + {desc => 'authtoken', type => 'string'}, + {desc => 'settings. Hash of key/value pairs', type => 'object'}, + ], + return => { + desc => 'Returns the number of applied settings on succes, Event on error.', + type => 'number or event' + } + } +); + +sub apply_user_or_ws_setting { + my ($self, $client, $auth, $settings) = @_; + + my $e = new_editor(authtoken => $auth, xact => 1); + return $e->die_event unless $e->checkauth; + + my $applied = 0; + my $ws_allowed = 0; + + for my $name (keys %$settings) { + $name =~ s/$name_regex//g; + my $val = $$settings{$name}; + my $stype = $e->retrieve_config_usr_setting_type($name); + + if ($stype) { + my $evt = apply_user_setting($e, $name, $val); + return $evt if $evt; + $applied++; + + } elsif ($e->requestor->wsid) { + $stype = $e->retrieve_config_workstation_setting_type($name); + next unless $stype; # no such workstation setting, skip. + + if (!$ws_allowed) { + # Confirm the caller has permission to apply workstation + # settings at the logged-in workstation before applying. + # Do the perm check here so it's only needed once per batch. + return $e->die_event unless + $ws_allowed = $e->allowed('APPLY_WORKSTATION_SETTING'); + } + + my $evt = apply_workstation_setting($e, $name, $val); + return $evt if $evt; + $applied++; + } + } + + $e->commit if $applied > 0; + $e->rollback if $applied == 0; + + return $applied; +} + +# CUD for user settings. +# Returns undef on success, Event on error. +# NOTE: This code was copied as-is from +# open-ils.actor.patron.settings.update, because it lets us +# manage the batch of updates within a single transaction. Also +# worth noting the APIs in this mod could eventually replace +# open-ils.actor.patron.settings.update. Maybe. +sub apply_user_setting { + my ($e, $name, $val) = @_; + my $user_id = $e->requestor->id; + + my $set = $e->search_actor_user_setting( + {usr => $user_id, name => $name})->[0]; + + if (defined $val) { + $val = OpenSRF::Utils::JSON->perl2JSON($val); + if ($set) { + $set->value($val); + $e->update_actor_user_setting($set) or return $e->die_event; + } else { + $set = Fieldmapper::actor::user_setting->new; + $set->usr($user_id); + $set->name($name); + $set->value($val); + $e->create_actor_user_setting($set) or return $e->die_event; + } + } elsif ($set) { + $e->delete_actor_user_setting($set) or return $e->die_event; + } + + return undef; +} + +# CUD for workstation settings. +# Assumes ->wsid contains a value and permissions have been checked. +# Returns undef on success, Event on error. +sub apply_workstation_setting { + my ($e, $name, $val) = @_; + my $ws_id = $e->requestor->wsid; + + my $set = $e->search_actor_workstation_setting( + {workstation => $ws_id, name => $name})->[0]; + + if (defined $val) { + $val = OpenSRF::Utils::JSON->perl2JSON($val); + + if ($set) { + $set->value($val); + $e->update_actor_workstation_setting($set) or return $e->die_event; + } else { + $set = Fieldmapper::actor::workstation_setting->new; + $set->workstation($ws_id); + $set->name($name); + $set->value($val); + $e->create_actor_workstation_setting($set) or return $e->die_event; + } + } elsif ($set) { + $e->delete_actor_workstation_setting($set) or return $e->die_event; + } + + return undef; +} + 1; diff --git a/Open-ILS/src/sql/Pg/upgrade/YYYY.data.workstation-settings.sql b/Open-ILS/src/sql/Pg/upgrade/YYYY.data.workstation-settings.sql index c07dc6902a..2824e4b0d7 100644 --- a/Open-ILS/src/sql/Pg/upgrade/YYYY.data.workstation-settings.sql +++ b/Open-ILS/src/sql/Pg/upgrade/YYYY.data.workstation-settings.sql @@ -9,6 +9,11 @@ VALUES ('eg.circ.checkin.no_precat_alert', 'Checkin Suppress Precat Alert' /*TODO: i18n*/, 'circ', 'bool'); */ +INSERT INTO permission.perm_list (id, code, description) VALUES + (594, 'APPLY_WORKSTATION_SETTING', + oils_i18n_gettext(594, 'APPLY_WORKSTATION_SETTING', 'ppl', 'description')); + + COMMIT; -- 2.11.0