LP#1750894 Cascade settings retrieve API
authorBill Erickson <berickxx@gmail.com>
Tue, 27 Mar 2018 14:02:13 +0000 (10:02 -0400)
committerBill Erickson <berickxx@gmail.com>
Tue, 29 May 2018 14:13:36 +0000 (10:13 -0400)
Signed-off-by: Bill Erickson <berickxx@gmail.com>
Open-ILS/src/perlmods/lib/OpenILS/Application/Actor/Settings.pm [new file with mode: 0644]

diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Actor/Settings.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Actor/Settings.pm
new file mode 100644 (file)
index 0000000..139c46b
--- /dev/null
@@ -0,0 +1,111 @@
+package OpenILS::Application::Actor::Settings;
+use strict; use warnings;
+use base 'OpenILS::Application';
+use OpenSRF::AppSession;
+use OpenSRF::Utils::Logger q/$logger/;
+use OpenILS::Application::AppUtils;
+use OpenILS::Utils::CStoreEditor q/:funcs/;
+use OpenILS::Utils::Fieldmapper;
+use OpenSRF::Utils::JSON;
+use OpenILS::Event;
+my $U = "OpenILS::Application::AppUtils";
+
+
+__PACKAGE__->register_method (
+    method      => 'retrieve_settings',
+    api_name    => 'open-ils.actor.settings.retrieve', 
+    stream      => 1,
+    signature => {
+        desc => q/
+            Returns org unit, user, and workstation setting values 
+            for the requested setting types.
+
+            The API makes a best effort to find the correct setting
+            value based on the available context data.
+
+            If no auth token is provided, only publicly visible org
+            unit settings may be returned.
+
+            If no workstation is linked to the provided auth token, only 
+            user settings and perm-visible org unit settings may be 
+            returned.
+
+            If no org unit is provided, but a workstation is linked to the
+            auth token, the owning lib of the workstation is used as the
+            context org unit.
+        /,
+        params => [
+            {desc => 'settings. List of setting names', type => 'array'},
+            {desc => 'authtoken. Optional', type => 'string'},
+            {desc => 'org_id. Optional', type => 'number'}
+        ],
+        return => {
+            desc => q/
+                Stream of setting name=>value pairs in the same order 
+                as the provided list of setting names.  No key-value 
+                pair is returned for settings that have no value defined./,
+            type => 'string'
+        }
+    }
+);
+
+sub retrieve_settings {
+    my ($self, $client, $settings, $auth, $org_id) = @_;
+
+    my ($aou_id, $user_id, $ws_id, $evt) = get_context($auth, $org_id);
+    return $evt if $evt; # bogus auth token
+
+    return OpenILS::Event->new('BAD_PARAMS', 
+        desc => 'Cannot retrieve settings without a user or org unit')
+        unless ($user_id || $aou_id);
+
+    # Setting names may only contains letters, numbers, unders, and dots.
+    s/[^a-zA-Z0-9_\.]//g foreach @$settings;
+
+    # Encode as a db-friendly array.
+    my $settings_str = '{' . join(',', @$settings) . '}';
+
+    # Some settings could be bulky, so fetch them as a stream from 
+    # cstore, relaying values back to the caller as they arrive.
+    my $ses = OpenSRF::AppSession->create('open-ils.cstore');
+    my $req = $ses->request('open-ils.cstore.json_query', {
+        from => [
+            'actor.get_setting_batch', 
+            $settings_str, $aou_id, $user_id, $ws_id
+        ]
+    });
+
+    # The DB responds in setting-name order.
+    while (my $resp = $req->recv) {
+        my $json = $resp->content->{'actor.get_setting_batch'};
+        $client->respond(
+            {$settings->[0] => OpenSRF::Utils::JSON->JSON2perl($json)})
+            if defined $json;
+        shift @$settings;
+    }
+
+    $ses->kill_me;
+
+    return undef;
+}
+
+# Returns ($org_id, $user_id, $ws_id, $evt);
+# Any value may be undef.
+sub get_context {
+    my ($auth, $org_id) = @_;
+
+    return ($org_id) unless $auth;
+    
+    my $e = new_editor(authtoken => $auth);
+    return (undef, undef, undef, $e->event) unless $e->checkauth;
+
+    my $user_id = $e->requestor->id;
+    my $ws_id = $e->requestor->wsid;
+
+    # default to the workstation org if needed.
+    $org_id = $e->requestor->ws_ou if $ws_id && !$org_id;
+
+    return ($org_id, $user_id, $ws_id);
+}
+
+1;