Adjusts fileroot for document paths at the moment that the document is to be displayed.
[openemr.git] / library / acl.inc
blob988f04b62195e410620b375f04e8089ac98a810f
1 <?php
2   // If you have installed phpGACL (http://phpgacl.sourceforge.net/)
3   // and have configured it for your site, then uncomment the following
4   // statement and change it to point to the location where
5   // gacl.class.php is intalled.
6   //
7   // $phpgacl_location = "/var/www/gacl";
9   // The following Access Control Objects (ACO) are currently supported.
10   // These are the "things to be protected":
11   //
12   // Section "admin" (Administration):
13   //   super       Superuser - can delete patients, encounters, issues
14   //   calendar    Calendar Settings
15   //   database    Database Reporting
16   //   forms       Forms Administration
17   //   practice    Practice Settings
18   //   superbill   Superbill Codes Administration
19   //   users       Users/Groups/Logs Administration
20   //   batchcom    Batch Communication Tool
21   //   language    Language Interface Tool
22   //   drugs       Pharmacy Dispensary
23   //   acl         ACL Administration
24   //
25   // Section "acct" (Accounting):
26   //   bill        Billing (write optional)
27   //   eob         EOB Data Entry
28   //   rep         Financial Reporting - my encounters
29   //   rep_a       Financial Reporting - anything
30   //
31   // Section "patients" (Patient Information):
32   //   appt        Appointments (write optional)
33   //   demo        Demographics (write,addonly optional)
34   //   med         Medical Records and History (write,addonly optional)
35   //   trans       Transactions, e.g. referrals (write optional)
36   //   docs        Documents (write,addonly optional)
37   //   notes       Patient Notes (write,addonly optional)
38   //
39   // Section "encounters" (Encounter Information):
40   //   auth        Authorize - my encounters
41   //   auth_a      Authorize - any encounters
42   //   coding      Coding - my encounters (write,wsome optional)
43   //   coding_a    Coding - any encounters (write,wsome optional)
44   //   notes       Notes - my encounters (write,addonly optional)
45   //   notes_a     Notes - any encounters (write,addonly optional)
46   //   date_a      Fix encounter dates - any encounters
47   //   relaxed     Less-private information (write,addonly optional)
48   //               (e.g. the Sports Fitness encounter form)
49   //
50   // Section "squads" applies to sports team use only:
51   //   acos in this section define the user-specified list of squads
52   //
53   // Section "sensitivities" (Sensitivities):
54   //   normal     Normal
55   //   high       High
57   if (isset ($phpgacl_location)) {
58     include_once("$phpgacl_location/gacl.class.php");
59     $gacl_object = new gacl();
60     //DO NOT CHANGE BELOW VARIABLE
61     $section_aro_value = 'users';
62   }
64   // acl_check should return 0 if access is denied.  Otherwise it may
65   // return anything that evaluates to true.  In addition if any of the
66   // following types of access are applicable, then the corresponding value
67   // must be returned if and only if such access is granted (ony one may
68   // be specified):
69   //
70   // * write   - the user may add or modify the ACO
71   // * wsome   - the user has limited add/modify access to the ACO
72   // * addonly - the user may view and add but not modify entries
73   //
74   function acl_check($section, $value, $user = '') {
75     global $gacl_object, $phpgacl_location, $section_aro_value;
76     if (! $user) $user = $_SESSION['authUser'];
78     if ($phpgacl_location) {
79       return $gacl_object->acl_check($section, $value, $section_aro_value, $user);
80     }
82     // If no phpgacl, then apply the old static rules whereby "authorized"
83     // users (providers) can do anything, and other users can do most things.
84     // If you want custom access control but don't want to mess with phpGACL,
85     // then you could customize the code below instead.
87     if ($section == 'admin' && $value == 'super') return 0;
89     if ($_SESSION['userauthorized']) return 'write';
91     if ($section == 'patients') {
92       if ($value == 'med') return 1;
93       return 'write';
94     }
95     else if ($section == 'encounters') {
96       if (strpos($value, 'coding' ) === 0) return 'write';
97       if (strpos($value, 'notes'  ) === 0) return 'write';
98       if ($value == 'relaxed') return 'write';
99     }
100     else if ($section != 'admin') {
101       return 'write';
102     }
104     return 0;
105   }
107   // Get the ACO name/value pairs for a designated section.  Each value
108   // is an array (section_value, value, order_value, name, hidden).
109   //
110   function acl_get_section_acos($section) {
111     global $phpgacl_location;
112     if ($phpgacl_location) {
113       include_once("$phpgacl_location/gacl_api.class.php");
114       $gacl = new gacl_api();
115       $arr1 = $gacl->get_objects($section, 1, 'ACO');
116       $arr = array();
117       if (!empty($arr1[$section])) {
118         foreach ($arr1[$section] as $value) {
119           $odata = $gacl->get_object_data($gacl->get_object_id($section, $value, 'ACO'), 'ACO');
120           $arr[$value] = $odata[0];
121         }
122       }
123       return $arr;
124     }
125     return 0;
126   }
128   // Return an array keyed on squad ACO names.
129   // This is only applicable for sports team use.
130   //
131   function acl_get_squads() {
132     return acl_get_section_acos('squads');
133   }
135   // Return an array keyed on encounter sensitivity level ACO names.
136   // Sensitivities are useful when some encounter notes are not
137   // medically sensitive (e.g. a physical fitness test), and/or if
138   // some will be "for doctor's eyes only" (e.g. STD treatment).
139   //
140   // When a non-blank sensitivity value exists in the new encounter
141   // form, it names an additional ACO required for access to all forms
142   // in the encounter.  If you want some encounters to be non-sensitive,
143   // then you also need some default nonblank sensitivity for normal
144   // encounters, as well as greater encounter notes permissions for
145   // those allowed to view non-sensitive encounters.
146   //
147   function acl_get_sensitivities() {
148     return acl_get_section_acos('sensitivities');
149   }
151   //
152   // Returns a sorted array of all available Group Titles.
153   //
154   function acl_get_group_title_list() {
155     global $phpgacl_location;
156     if (isset ($phpgacl_location)) {
157       include_once("$phpgacl_location/gacl_api.class.php");
158       $gacl = new gacl_api();
159       $parent_id = $gacl->get_root_group_id();
160       $arr_group_ids = $gacl->get_group_children($parent_id, 'ARO', 'RECURSE');
161       $arr_group_titles = array();
162       foreach ($arr_group_ids as $value) {
163         $arr_group_data = $gacl->get_group_data($value, 'ARO');
164         $arr_group_titles[$value] = $arr_group_data[3];
165       }
166       sort($arr_group_titles);
167       return $arr_group_titles;
168     }
169     return 0;
170   }
172   //
173   // Returns a sorted array of group Titles that a user belongs to.
174   // Returns 0 if does not belong to any group yet.
175   //   $user_name = Username, which is login name.
176   //
177   function acl_get_group_titles($user_name) {
178     global $phpgacl_location, $section_aro_value;
179     if (isset ($phpgacl_location)) {
180       include_once("$phpgacl_location/gacl_api.class.php");
181       $gacl = new gacl_api();
182       $user_aro_id = $gacl->get_object_id($section_aro_value, $user_name, 'ARO');
183       if ($user_aro_id) {
184         $arr_group_id = $gacl->get_object_groups($user_aro_id, 'ARO', 'NO_RECURSE');
185         if ($arr_group_id) {
186           foreach ($arr_group_id as $key => $value) {
187             $arr_group_data = $gacl->get_group_data($value, 'ARO');
188             $arr_group_titles[$key] =  $arr_group_data[3];
189           }
190         sort($arr_group_titles);
191         return $arr_group_titles;
192         }
193       }
194     }
195     return 0;
196   }
198   //
199   // This will place the user aro object into selected group(s)
200   // It uses the set_user_aro() function
201   //   $username = username (string)
202   //   $group = title of group(s) (string or array)
203   //
204   function add_user_aros($username, $group) {
205    $current_user_groups = acl_get_group_titles($username);
206    if (!$current_user_groups) {
207     $current_user_groups = array();
208    }
209    if (is_array($group)){
210     foreach ($group as $value) {
211        if (!in_array($value, $current_user_groups)) { 
212         array_push($current_user_groups, $value);
213        }
214     }
215    }
216    else {   
217     if (!in_array($group, $current_user_groups)) {
218      array_push($current_user_groups, $group);
219     }
220    }    
221    $user_data = mysql_fetch_array(sqlStatement("select * from users where username='" .
222     $username . "'"));
223    set_user_aro($current_user_groups, $username, $user_data["fname"],
224     $user_data["mname"], $user_data["lname"]);
225    return;
226   }
228   //
229   // This will remove the user aro object from the selected group(s)
230   // It uses the set_user_aro() function
231   //   $username = username (string)
232   //   $group = title of group(s) (string or array)
233   //
234   function remove_user_aros($username, $group) {
235    $current_user_groups = acl_get_group_titles($username);
236    $new_user_groups = array();
237    if (is_array($group)){
238     foreach ($current_user_groups as $value) {    
239      if (!in_array($value, $group)) {
240       array_push($new_user_groups, $value);
241      }
242     }    
243    }
244    else {   
245     foreach ($current_user_groups as $value) {     
246      if ($value != $group) {
247       array_push($new_user_groups, $value);
248      }
249     }
250    }
251    $user_data = mysql_fetch_array(sqlStatement("select * from users where username='" .
252     $username . "'"));
253    set_user_aro($new_user_groups, $username, $user_data["fname"],
254     $user_data["mname"], $user_data["lname"]);
255    return;
256   }
258   //
259   // This will either create or edit a user aro object, and then place it
260   // in the requested groups. It will not allow removal of the 'admin'
261   // user from the 'admin' group.
262   //   $arr_group_titles = titles of the groups that user will be added to.
263   //   $user_name = username, which is login name.
264   //   $first_name = first name
265   //   $middle_name = middle name
266   //   $last_name = last name
267   //
268   function set_user_aro($arr_group_titles, $user_name, $first_name, $middle_name, $last_name) {
269     global $phpgacl_location, $section_aro_value;
271     if (isset ($phpgacl_location)) {
272       include_once("$phpgacl_location/gacl_api.class.php");
273       $gacl = new gacl_api();
275       //get array of all available group ID numbers
276       $parent_id = $gacl->get_root_group_id();
277       $arr_all_group_ids = $gacl->get_group_children($parent_id, 'ARO', 'RECURSE');
279       //Cycle through ID array to find and process each selected group
280       //Create a counter since processing of first hit is unique
281       $counter = 0;
282       foreach ($arr_all_group_ids as $value) {
283         $arr_group_data = $gacl->get_group_data($value, 'ARO');
284         if (in_array($arr_group_data[3], $arr_group_titles)) {
285           //We have a hit, so need to add group and increment counter
286           //  because processing of first hit is unique
287           $counter = $counter + 1;
288           //create user full name field
289           if ($middle_name) {
290             $full_name = $first_name . " " . $middle_name . " " .  $last_name;
291           }
292           else {
293             $full_name = $first_name . " " . $last_name;
294           }
296           //If this is not the first group to be added, then will skip below
297           // and will be added. If this is the first group, then need to
298           // go thru several steps before adding the group.
299           if ($counter == 1) {
300             //get ID of user ARO object, if it exist
301             $user_aro_id = $gacl->get_object_id($section_aro_value, $user_name, 'ARO');
302             if ($user_aro_id) {
303               //user ARO object already exist, so will edit it
304               $gacl->edit_object($user_aro_id, $section_aro_value, $full_name, $user_name, 10, 0, 'ARO');
306               //remove all current user ARO object group associations
307               $arr_remove_group_ids = $gacl->get_object_groups($user_aro_id, 'ARO', 'NO_RECURSE');
308               foreach ($arr_remove_group_ids as $value2) {
309                 $gacl->del_group_object($value2, $section_aro_value, $user_name, 'ARO');
310               }
311             }
312             else {
313               //user ARO object does not exist, so will create it
314               $gacl->add_object($section_aro_value, $full_name, $user_name, 10, 0, 'ARO');
315             }
316           }
318           //place the user ARO object in the selected group
319           $gacl->add_group_object($value, $section_aro_value, $user_name, 'ARO');
321           //
322           //Below will not allow 'admin' user to be removed from 'admin' group
323           //
324           if ($user_name == 'admin') {
325             $boolean_admin=0;
326             $admin_id = $gacl->get_object_id($section_aro_value, 'admin', 'ARO');
327             $arr_admin = $gacl->get_object_groups($admin_id, 'ARO', 'NO_RECURSE');
328             foreach ($arr_admin as $value3) {
329               $arr_admin_data = $gacl->get_group_data($value3, 'ARO');
330               if (strcmp($arr_admin_data[2], 'admin') == 0) {
331                 $boolean_admin=1;
332               }
333             }
334             if (!$boolean_admin) {
335               foreach ($arr_all_group_ids as $value4) {
336                 $arr_temp = $gacl->get_group_data($value4, 'ARO');
337                 if ($arr_temp[2] == 'admin') {
338                   $gacl->add_group_object($value4, $section_aro_value, 'admin', 'ARO');
339                 }
340               }
341             }
342           }
343         }
344       }
345     }
346    return;
347   }
349   //
350   // Returns true if acl exist
351   // Returns false if acl doesn't exist
352   //  EITHER $title or $name is required(send FALSE in variable
353   //  not being used). If both are sent, then only $title will be
354   //  used.
355   //  $return_value is required
356   //    $title = title of acl (string)
357   //    $name = name of acl (string)
358   //    $return_value = return value of acl (string)
359   //
360   function acl_exist($title, $name, $return_value) {
361    global $phpgacl_location;
362    if (isset ($phpgacl_location)) {
363     include_once("$phpgacl_location/gacl_api.class.php");
364     $gacl = new gacl_api();
365     if (!$name) {
366      $acl = $gacl->search_acl(FALSE, FALSE, FALSE, FALSE, $title, FALSE, FALSE, FALSE, $return_value);
367     }
368     else if (!$title) {
369      $group_id = $gacl->get_group_id($name, NULL, 'ARO');
370      if ($group_id) {
371       $group_data = $gacl->get_group_data($group_id, 'ARO');
372       $acl = $gacl->search_acl(FALSE, FALSE, FALSE, FALSE, $group_data[3], FALSE, FALSE, FALSE, $return_value);
373      }
374      else {
375      return false;
376      }
377     }
378     else {
379      $acl = $gacl->search_acl(FALSE, FALSE, FALSE, FALSE, $title, FALSE, FALSE, FALSE, $return_value);
380     }
381     if (!empty($acl)) {
382      return true;
383     }
384     else {
385      return false;
386     }
387    }
388   }
390   //
391   // This will add a new acl and group(if group doesn't yet exist)
392   // with one aco in it.
393   //   $acl_title = title of acl (string)
394   //   $acl_name = name of acl (string)
395   //   $return_value = return value of acl (string)
396   //   $note = description of acl (array)
397   //
398   function acl_add($acl_title, $acl_name, $return_value, $note) {
399    global $phpgacl_location;
400    if (isset ($phpgacl_location)) {
401     include_once("$phpgacl_location/gacl_api.class.php");
402     $gacl = new gacl_api();
403     $group_id = $gacl->get_group_id($acl_name, $acl_title, 'ARO');
404     if ($group_id) {
405      //group already exist, so just create acl
406      $gacl->add_acl(array("patients"=>array("appt")),
407       NULL, array($group_id), NULL, NULL, 1, 1, $return_value, $note);
408     }
409     else {
410      //create group, then create acl
411      $parent_id = $gacl->get_root_group_id();
412      $aro_id = $gacl->add_group($acl_name, $acl_title, $parent_id, 'ARO');
413      $gacl->add_acl(array("patients"=>array("appt")),
414       NULL, array($aro_id), NULL, NULL, 1, 1, $return_value, $note);
415     }
416     return;
417    }
418    return 0;
419   }
421   //
422   // This will remove acl. It will also remove group(if the group
423   // is no longer associated with any acl's).
424   //   $acl_title = title of acl (string)
425   //   $acl_name = name of acl (string)
426   //   $return_value = return value of acl (string)
427   //   $note = description of acl (array)
428   //
429   function acl_remove($acl_title, $return_value) {
430    global $phpgacl_location;
431    if (isset ($phpgacl_location)) {
432     include_once("$phpgacl_location/gacl_api.class.php");
433     $gacl = new gacl_api();
434     //First, delete the acl
435     $acl_id=$gacl->search_acl(FALSE, FALSE, FALSE, FALSE, $acl_title, FALSE, FALSE, FALSE, $return_value);
436     $gacl->del_acl($acl_id[0]);
437     //Then, remove the group(if no more acl's are remaining)
438     $acl_search=$gacl->search_acl(FALSE, FALSE, FALSE, FALSE, $acl_title, FALSE, FALSE, FALSE, FALSE);
439     if (empty($acl_search)){
440      $group_id=$gacl-> get_group_id(NULL, $acl_title, 'ARO');
441      $gacl->del_group($group_id, TRUE, 'ARO');
442     }
443     return;
444    }
445    return 0;
446   }
448   //
449   // This will place the aco(s) into the selected acl
450   //   $acl_title = title of acl (string)
451   //   $return_value = return value of acl (string)
452   //   $aco_id = id of aco (array)
453   //
454   function acl_add_acos($acl_title, $return_value, $aco_id) {
455    global $phpgacl_location;
456    if (isset ($phpgacl_location)) {
457     include_once("$phpgacl_location/gacl_api.class.php");
458     $gacl = new gacl_api();
459     $acl_id = $gacl->search_acl(FALSE, FALSE, FALSE, FALSE, $acl_title, FALSE, FALSE, FALSE, $return_value);
460     foreach ($aco_id as $value) { 
461      $aco_data = $gacl->get_object_data($value, 'ACO');
462      $aco_section = $aco_data[0][0];
463      $aco_name = $aco_data[0][1];   
464      $gacl->append_acl($acl_id[0], NULL, NULL, NULL, NULL, array($aco_section=>array($aco_name)));
465     }
466     return;
467    }
468    return 0;
469   }
471   //
472   // This will remove the aco(s) from the selected acl
473   //   $acl_title = title of acl (string)
474   //   $return_value = return value of acl (string)
475   //   $aco_id = id of aco (array)
476   //
477   function acl_remove_acos($acl_title, $return_value, $aco_id) {
478    global $phpgacl_location;
479    if (isset ($phpgacl_location)) {
480     include_once("$phpgacl_location/gacl_api.class.php");
481     $gacl = new gacl_api();
482     $acl_id = $gacl->search_acl(FALSE, FALSE, FALSE, FALSE, $acl_title, FALSE, FALSE, FALSE, $return_value);
483     foreach ($aco_id as $value) {
484      $aco_data = $gacl->get_object_data($value, 'ACO');
485      $aco_section = $aco_data[0][0];
486      $aco_name = $aco_data[0][1];
487      $gacl->shift_acl($acl_id[0], NULL, NULL, NULL, NULL, array($aco_section=>array($aco_name)));
488      }
489     return;
490    }
491    return 0;
492   }
494   //
495   // This will return the number of aco objects
496   //  in a specified acl.
497   //   $acl_title = title of acl (string)
498   //   $return_value = return value of acl (string)
499   //
500   function acl_count_acos($acl_title, $return_value) {
501    global $phpgacl_location;
502    if (isset ($phpgacl_location)) {
503     include_once("$phpgacl_location/gacl_api.class.php");
504     $gacl = new gacl_api();
505     $acl_id = $gacl->search_acl(FALSE, FALSE, FALSE, FALSE, $acl_title, FALSE, FALSE, FALSE, $return_value);
506     $acl_data = $gacl->get_acl($acl_id[0]);
507     $aco_count = 0;
508     foreach ($acl_data['aco'] as $key => $value) {
509      $aco_count = $aco_count + count($acl_data['aco'][$key]);
510     }
511     return $aco_count;
512    }
513    return 0;
514   }