1 package OpenILS::Application::Actor::Settings;
2 use strict; use warnings;
3 use base 'OpenILS::Application';
4 use OpenSRF::AppSession;
5 use OpenSRF::Utils::Logger q/$logger/;
6 use OpenILS::Application::AppUtils;
7 use OpenILS::Utils::CStoreEditor q/:funcs/;
8 use OpenILS::Utils::Fieldmapper;
9 use OpenSRF::Utils::JSON;
11 my $U = "OpenILS::Application::AppUtils";
13 # Setting names may only contains letters, numbers, unders, and dots.
14 my $name_regex = qr/[^a-zA-Z0-9_\.]/;
16 __PACKAGE__->register_method (
17 method => 'retrieve_settings',
18 api_name => 'open-ils.actor.settings.retrieve',
22 Returns org unit, user, and workstation setting values
23 for the requested setting types.
25 The API makes a best effort to find the correct setting
26 value based on the available context data.
28 If no auth token is provided, only publicly visible org
29 unit settings may be returned.
31 If no workstation is linked to the provided auth token, only
32 user settings and perm-visible org unit settings may be
35 If no org unit is provided, but a workstation is linked to the
36 auth token, the owning lib of the workstation is used as the
40 {desc => 'settings. List of setting names', type => 'array'},
41 {desc => 'authtoken. Optional', type => 'string'},
42 {desc => 'org_id. Optional', type => 'number'}
46 Stream of setting name=>value pairs in the same order
47 as the provided list of setting names. No key-value
48 pair is returned for settings that have no value defined./,
54 sub retrieve_settings {
55 my ($self, $client, $settings, $auth, $org_id) = @_;
57 my ($aou_id, $user_id, $ws_id, $evt) = get_context($auth, $org_id);
58 return $evt if $evt; # bogus auth token
60 return OpenILS::Event->new('BAD_PARAMS',
61 desc => 'Cannot retrieve settings without a user or org unit')
62 unless ($user_id || $aou_id);
64 # Setting names may only contains letters, numbers, unders, and dots.
65 s/$name_regex//g foreach @$settings;
67 # Encode as a db-friendly array.
68 my $settings_str = '{' . join(',', @$settings) . '}';
70 # Some settings could be bulky, so fetch them as a stream from
71 # cstore, relaying values back to the caller as they arrive.
72 my $ses = OpenSRF::AppSession->create('open-ils.cstore');
73 my $req = $ses->request('open-ils.cstore.json_query', {
75 'actor.get_cascade_setting_batch',
76 $settings_str, $aou_id, $user_id, $ws_id
80 while (my $resp = $req->recv) {
81 my $summary = $resp->content;
82 $summary->{value} = OpenSRF::Utils::JSON->JSON2perl($summary->{value});
83 $client->respond($summary);
90 # Returns ($org_id, $user_id, $ws_id, $evt);
91 # Any value may be undef.
93 my ($auth, $org_id) = @_;
95 return ($org_id) unless $auth;
97 my $e = new_editor(authtoken => $auth);
98 return (undef, undef, undef, $e->event) unless $e->checkauth;
100 my $user_id = $e->requestor->id;
101 my $ws_id = $e->requestor->wsid;
103 # default to the workstation org if needed.
104 $org_id = $e->requestor->ws_ou if $ws_id && !$org_id;
106 return ($org_id, $user_id, $ws_id);
109 __PACKAGE__->register_method (
110 method => 'apply_user_or_ws_setting',
111 api_name => 'open-ils.actor.settings.apply.user_or_ws',
115 Apply values to user or workstation settings, depending
116 on which is supported via local configuration.
118 The API ignores nonexistent settings and only returns error
119 events when an auth, permission, or internal error occurs.
122 {desc => 'authtoken', type => 'string'},
123 {desc => 'settings. Hash of key/value pairs', type => 'object'},
126 desc => 'Returns the number of applied settings on succes, Event on error.',
127 type => 'number or event'
132 sub apply_user_or_ws_setting {
133 my ($self, $client, $auth, $settings) = @_;
135 my $e = new_editor(authtoken => $auth, xact => 1);
136 return $e->die_event unless $e->checkauth;
141 for my $name (keys %$settings) {
142 $name =~ s/$name_regex//g;
143 my $val = $$settings{$name};
144 my $stype = $e->retrieve_config_usr_setting_type($name);
147 my $evt = apply_user_setting($e, $name, $val);
151 } elsif ($e->requestor->wsid) {
152 $stype = $e->retrieve_config_workstation_setting_type($name);
153 next unless $stype; # no such workstation setting, skip.
156 # Confirm the caller has permission to apply workstation
157 # settings at the logged-in workstation before applying.
158 # Do the perm check here so it's only needed once per batch.
159 return $e->die_event unless
160 $ws_allowed = $e->allowed('APPLY_WORKSTATION_SETTING');
163 my $evt = apply_workstation_setting($e, $name, $val);
169 $e->commit if $applied > 0;
170 $e->rollback if $applied == 0;
175 # CUD for user settings.
176 # Returns undef on success, Event on error.
177 # NOTE: This code was copied as-is from
178 # open-ils.actor.patron.settings.update, because it lets us
179 # manage the batch of updates within a single transaction. Also
180 # worth noting the APIs in this mod could eventually replace
181 # open-ils.actor.patron.settings.update. Maybe.
182 sub apply_user_setting {
183 my ($e, $name, $val) = @_;
184 my $user_id = $e->requestor->id;
186 my $set = $e->search_actor_user_setting(
187 {usr => $user_id, name => $name})->[0];
190 $val = OpenSRF::Utils::JSON->perl2JSON($val);
193 $e->update_actor_user_setting($set) or return $e->die_event;
195 $set = Fieldmapper::actor::user_setting->new;
199 $e->create_actor_user_setting($set) or return $e->die_event;
202 $e->delete_actor_user_setting($set) or return $e->die_event;
208 # CUD for workstation settings.
209 # Assumes ->wsid contains a value and permissions have been checked.
210 # Returns undef on success, Event on error.
211 sub apply_workstation_setting {
212 my ($e, $name, $val) = @_;
213 my $ws_id = $e->requestor->wsid;
215 my $set = $e->search_actor_workstation_setting(
216 {workstation => $ws_id, name => $name})->[0];
219 $val = OpenSRF::Utils::JSON->perl2JSON($val);
223 $e->update_actor_workstation_setting($set) or return $e->die_event;
225 $set = Fieldmapper::actor::workstation_setting->new;
226 $set->workstation($ws_id);
229 $e->create_actor_workstation_setting($set) or return $e->die_event;
232 $e->delete_actor_workstation_setting($set) or return $e->die_event;
238 __PACKAGE__->register_method (
239 method => 'applied_settings',
240 api_name => 'open-ils.actor.settings.staff.applied.names',
245 Returns a list of setting names where a value is applied to
246 the current user or workstation.
248 This is a staff-only API created primarily to support the
249 getKeys() functionality used in the browser client for
250 server-managed settings.
252 Note as of now, this API can return names for user settings
253 which are unrelated to the staff client. ALL user setting
254 names matching the selected prefix are returned!
256 Use the workstation_only option to avoid returning any user
261 {desc => 'authtoken', type => 'string'},
263 'prefix. Limit keys to those starting with $prefix',
268 desc => 'List of strings, Event on error',
274 sub applied_settings {
275 my ($self, $client, $auth, $prefix, $options) = @_;
277 my $e = new_editor(authtoken => $auth);
278 return $e->event unless $e->checkauth;
279 return $e->event unless $e->allowed('STAFF_LOGIN');
284 select => {awss => ['name']},
287 workstation => $e->requestor->wsid
291 $query->{where}->{name} = {like => "$prefix%"} if $prefix;
293 for my $key (@{$e->json_query($query)}) {
294 $client->respond($key->{name});
297 return undef if $options->{workstation_only};
300 select => {aus => ['name']},
303 usr => $e->requestor->id
307 $query->{where}->{name} = {like => "$prefix%"} if $prefix;
309 for my $key (@{$e->json_query($query)}) {
310 $client->respond($key->{name});