fix for acl admin gui
[openemr.git] / interface / usergroup / adminacl.php
blob176d839d91d204e7d5edb47b293159c690c0fc81
1 <?php
2 /**
3 * Allows acl(php-gacl) administration. Heavily ajax and
4 * javascript/jquery dependent. All ajax functions are called
5 * from adminacl_ajax.php
7 * @package OpenEMR
8 * @link http://www.open-emr.org
9 * @author Brady Miller <brady.g.miller@gmail.com>
10 * @copyright Copyright (c) 2007-2016 Brady Miller <brady.g.miller@gmail.com>
11 * @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
14 include_once("../globals.php");
15 include_once("$srcdir/acl.inc");
17 //ensure user has proper access
18 if (!acl_check('admin', 'acl')) {
19 echo "(" . xl('ACL Administration Not Authorized') . ")";
20 exit;
22 //ensure phpgacl is installed
23 if (!isset($phpgacl_location)) {
24 echo "(" . xl('PHP-gacl is not installed') . ")";
25 exit;
29 <html>
30 <head>
31 <script type="text/JavaScript" src="<?php echo $GLOBALS['assets_static_relative']; ?>/jquery-min-1-4-3/index.js"></script>
32 <script type="text/JavaScript">
34 $(document).ready(function(){
36 //Show membership section by default
37 $("#membership_show").click();
38 membership_show();
39 //Show membership section by default
41 $("a.link_submit").live("click", function(){
42 generic_click(this);
43 return false;
44 });
46 $("input.button_submit").live("click", function(){
47 generic_click(this);
48 return false;
49 });
51 $("#membership_show").live("click", function(){
52 membership_show();
53 return;
54 });
56 $("#acl_show").live("click", function(){
57 acl_show();
58 return;
59 });
61 $("input.button_acl_add").live("click", function(){
62 //if Clear, then reset form
63 if (this.id == "button_acl_add_clear") {
64 $("#acl_error").empty();
65 $("#div_acl_add_form span.alert").empty();
66 return;
68 //if Cancel, then reset/hide form and show create/remove acl links
69 if (this.id == "button_acl_add_cancel") {
70 $("#div_acl_add_form").hide("slow");
71 $("#acl_error").empty();
72 $("#div_acl_add_form span.alert").empty();
73 $("#none_acl_returns").show();
74 $("#none_acl_list").show();
75 return;
77 //Submit selected, so send ajax request
78 title = $("#title_field").val();
79 identifier = $("#id_field").val();
80 return_value = $("#return_field").val();
81 description = $("#desc_field").val();
82 $.ajax({
83 type: "POST",
84 url: "../../library/ajax/adminacl_ajax.php",
85 dataType: "xml",
86 data: {
87 control: "acl",
88 action: "add",
89 title: title,
90 identifier: identifier,
91 return_value: return_value,
92 description: description
94 success: function(xml){
95 //if successful, then show new group
96 if ($(xml).find("success").text() == "SUCCESS") {
97 $("#button_acl_add_cancel").click();
98 acl_show();
100 //Remove Loading indicator and old errors, then display new errors
101 $("#div_acl_add_form span.loading").hide();
102 $("#acl_error").empty();
103 $("#div_acl_add_form span.alert").empty();
104 $(xml).find("error").each(function(){
105 temparray = $(this).text().split("_");
106 $("#" + temparray[0] + "_error").append(temparray[1]);
108 $("#acl_error").show();
109 $("#div_acl_add_form span.alert").show();
111 beforeSend: function(){
112 //Show Loading indicator
113 $("#div_acl_add_form span.loading").show();
115 error: function(){
116 //Remove Loading indicator and show errors
117 $("#div_acl_add_form span.loading").hide();
118 $("#acl_error").empty();
119 $("#acl_error").append("<span class='alert'><?php xl('ERROR, unable to collect data from server','e'); ?><br></span>");
120 $("#acl_error").show();
123 return false;
126 $("input.button_acl_remove").live("click", function(){
127 //if Clear, then reset form
128 if (this.id == "button_acl_remove_clear") {
129 $("#acl_error").empty();
130 $("#div_acl_remove_form span.alert").empty();
131 return;
133 //if Cancel, then reset/hide form and show create/remove acl links
134 if (this.id == "button_acl_remove_cancel") {
135 $("#div_acl_remove_form").hide("slow");
136 $("#acl_error").empty();
137 $("#div_acl_remove_form span.alert").empty();
138 $("#none_acl_returns").show();
139 $("#none_acl_list").show();
140 return;
142 //Ensure confirmed before deleting group
143 confirmDelete = $("input[@name=acl_remove_confirm]:checked").val();
144 if (confirmDelete == "no") { //send confirm alert and exit
145 $("#remove_confirm_error").empty();
146 $("#remove_confirm_error").append("<?php xl('Select Yes to confirm group deletion','e'); ?>");
147 return false;
149 //Delete and confirmed, so send ajax request
150 temparray = $("#acl_field").val().split("-");
151 title = temparray[0];
152 return_value = temparray[1];
153 $.ajax({
154 type: "POST",
155 url: "../../library/ajax/adminacl_ajax.php",
156 dataType: "xml",
157 data: {
158 control: "acl",
159 action: "remove",
160 title: title,
161 return_value: return_value
163 success: function(xml){
164 //if successful, then show new group
165 if ($(xml).find("success").text() == "SUCCESS") {
166 $("#button_acl_remove_cancel").click();
167 acl_show();
169 //Remove Loading indicator and old errors, then display new errors
170 $("#div_acl_remove_form span.loading").hide();
171 $("#acl_error").empty();
172 $("#div_acl_remove_form span.alert").empty();
173 $(xml).find("error").each(function(){
174 temparray = $(this).text().split("_");
175 $("#" + temparray[0] + "_error").append(temparray[1]);
177 $("#acl_error").show();
178 $("#div_acl_remove_form span.alert").show();
180 beforeSend: function(){
181 //Show Loading indicator
182 $("#div_acl_remove_form span.loading").show();
184 error: function(){
185 //Remove Loading indicator and show errors
186 $("#div_acl_remove_form span.loading").hide();
187 $("#acl_error").empty();
188 $("#acl_error").append("<span class='alert'><?php xl('ERROR, unable to collect data from server','e'); ?><br></span>");
189 $("#acl_error").show();
192 return false;
195 function membership_show() {
196 if (!$("#membership_show").attr("checked")) {
197 $("#membership_error").empty();
198 $("#membership").hide("slow");
199 return;
201 //Send ajax request
202 $.ajax({
203 type: "POST",
204 url: "../../library/ajax/adminacl_ajax.php",
205 dataType: "xml",
206 data: {
207 control: "username",
208 action: "list"
210 success: function(xml){
211 $("#membership_error").empty();
212 $("#membership").empty();
213 $(xml).find("user").each(function(){
214 username = $(this).find("username").text();
215 $("#membership").append("<div id='link_" + username + "'><span class='text'>" + username + "</span><a class='link_submit' href='no_javascript' id='" + username + "_membership_list' title='<?php xl('Edit','e'); ?> " + username + "'>(<?php xl('Edit','e'); ?>)</a></span><a class='link_submit' href='no_javascript' id='" + username + "_membership_hide' style='display: none' title='<?php xl('Hide','e'); ?> " + username + "'>(<?php xl('Hide','e'); ?>)</a><span class='alert' style='display: none;'>&nbsp;&nbsp;<?php xl('This user is not a member of any group','e'); ?>!!!</span><span class='loading' style='display: none;'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<?php xl('LOADING','e'); ?>...</span></div><div id='error_" + username + "'></div><div id='" + username + "' style='display: none'><table class='lists' border='1' bgcolor='white' cellpadding='3' cellspacing='2'><tr><td align='center'><span class='bold'><?php xl('Active','e'); ?></span></td><td align='center'><span class='bold'><?php xl('Inactive','e'); ?></span></td></tr><tr><td align='center'><select name='active[]' multiple></select><br /><p align='center'><input class='button_submit' type='button' title='<?php xl('Remove','e'); ?>' id='" + username + "_membership_remove' value=' >> '></p></td><td align='center'><select name='inactive[]' multiple></select><br /><p align='center'><input class='button_submit' type='button' title='<?php xl('Add','e'); ?>' id='" + username + "_membership_add' value=' << ' ></p></td></tr></table></div>");
216 if ($(this).find("alert").text() == "no membership") {
217 $("#link_" + username + " span.alert").show();
220 //Show the username list and remove loading indicator
221 $("#membership").show("slow");
222 $("#membership_edit span.loading:first").hide();
224 beforeSend: function(){
225 //Show Loading indicator
226 $("#membership_edit span.loading:first").show();
228 error: function(){
229 //Remove Loading indicator and previous error, if any, then show error
230 $("#membership_edit span.loading:first").hide();
231 $("#membership_error").empty();
232 $("#membership_error").append("<span class='alert'><?php xl('ERROR, unable to collect data from server','e'); ?><br><br></span>");
233 $("#membership_error").show();
236 return;
239 function acl_show() {
240 if (!$("#acl_show").attr("checked")) {
241 $("#acl_error").empty();
242 $("#none_acl_returns").hide();
243 $("#none_acl_list").hide();
244 $("#acl").hide("slow");
245 $("#div_acl_add_form").hide("slow");
246 $("#div_acl_remove_form").hide("slow");
247 return;
249 //Send ajax request
250 $.ajax({
251 type: "POST",
252 url: "../../library/ajax/adminacl_ajax.php",
253 dataType: "xml",
254 data: {
255 control: "acl",
256 action: "list"
258 success: function(xml){
259 $("#acl_error").empty();
260 $("#acl").empty();
261 $(xml).find("acl").each(function(){
262 value_acl = $(this).find("value").text();
263 title = $(this).find("title").text();
264 titleDash = value_acl.replace(" ","-");
265 return_value = $(this).find("returnid").text();
266 return_title = $(this).find("returntitle").text();
267 note = $(this).find("note").text();
268 $("#acl").append("<div id='acl_link_" + titleDash + "_" + return_value + "'><span class='text' title='" + note + "'>" + title + "-" + return_title + "</span><a class='link_submit' href='no_javascript' id='" + titleDash + "_aco_list_" + return_value + "' title='<?php xl('Edit','e'); ?> " + title + "-" + return_title + "'>(<?php xl('Edit','e'); ?>)</a></span><a class='link_submit' href='no_javascript' id='" + titleDash + "_acl_hide_" + return_value + "' style='display: none' title='<?php xl('Hide','e'); ?> " + title + "-" + return_title + "'>(<?php xl('Hide','e'); ?>)</a><span class='loading' style='display: none;'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<?php xl('LOADING','e'); ?>...</span></div><div id='acl_error_" + titleDash + "_" + return_value + "'></div><div id='acl_" + titleDash + "_" + return_value + "' style='display: none'><table border='1' bgcolor='white' cellpadding='3' cellspacing='2'><tr><td align='center'><span class='bold'><?php xl('Active','e'); ?></span></td><td align='center'><span class='bold'><?php xl('Inactive','e'); ?></span></td></tr><tr><td align='center'><select name='active[]' size='6' multiple></select><br /><p align='center'><input class='button_submit' type='button' title='<?php xl('Remove','e'); ?>' id='" + titleDash +"_aco_remove_" + return_value + "' value=' >> '></p></td><td align='center'><select name='inactive[]' size='6' multiple></select><br /><p align='center'><input class='button_submit' type='button' title='<?php xl('Add','e'); ?>' id='" + titleDash + "_aco_add_" + return_value + "' value=' << ' ></p></td></tr></table></div>");
270 //Show the acl list and add link. Remove loading indicator.
271 $("#acl").show("slow");
272 $("#acl_edit span.loading:first").hide();
273 $("#none_acl_returns").show();
274 $("#none_acl_list").show();
276 beforeSend: function(){
277 //Show Loading indicator
278 $("#acl_edit span.loading:first").show();
280 error:function(){
281 //Remove Loading indicator and previous error, if any, then show error
282 $("#acl_edit span.loading:first").hide();
283 $("#acl_error").empty();
284 $("#acl_error").append("<span class='alert'><?php xl('ERROR, unable to collect data from server','e'); ?><br><br></span>");
285 $("#acl_error").show();
288 return;
291 function generic_click(cthis) {
292 //set up variables and html page pointers
293 temparray = cthis.id.split("_");
294 identity = temparray[0];
295 identityFormatted = identity.replace("-"," ");
296 control = temparray[1];
297 action = temparray[2];
298 return_value = temparray[3];
299 if (control == "membership") {
300 contentPointer = "#" + identity;
301 linkPointer = "#link_" + identity;
302 linkPointerPost ="";
303 errorPointer = "#error_" + identity;
305 if (control == "acl" || control == "aco") {
306 contentPointer = "#acl_" + identity + "_" + return_value;
307 linkPointer = "#acl_link_" + identity + "_" + return_value;
308 linkPointerPost ="";
309 errorPointer = "#acl_error_" + identity + "_" + return_value;
311 //special cases, show add/remove acl forms
312 if (identity == "none" && control == "acl") { //action == "returns"
313 if (action == "returns") {
314 contentPointer = "#div_acl_add_form";
316 else if (action == "list") {
317 contentPointer = "#div_acl_remove_form";
319 linkPointer = "#acl_edit";
320 linkPointerPost =":first";
321 errorPointer = "#acl_error";
324 //If clicked Hide link
325 if (action == "hide") {
326 //Remove stuff and show Edit link
327 $(contentPointer).hide("slow");
328 $(errorPointer).hide();
329 $(linkPointer + " a.link_submit:last").hide();
330 $(linkPointer + " a.link_submit:first").show();
331 return;
334 //If clicked Add with ACO or membership, then collect selections
335 if (action == "add" && !(control == "acl")) {
336 var selected = [];
337 selected = $(contentPointer + " select:last").val();
340 //If clicked Remove with ACO or membership, then collect selections
341 if (action == "remove" && !(control == "acl")) {
342 var selected = [];
343 selected = $(contentPointer + " select:first").val();
346 //Send ajax request
347 $.ajax({
348 type: "POST",
349 url: "../../library/ajax/adminacl_ajax.php",
350 dataType: "xml",
351 data: {
352 name: identityFormatted,
353 control: control,
354 action: action,
355 'selection[]': selected,
356 return_value: return_value
358 success: function(xml){
360 //SPECIAL CASES to show the add/remove acl form, then exit
361 if (identity == "none" && control == "acl") {
362 $(contentPointer + " select").empty();
363 if (action == "returns") {
364 $(xml).find("return").each(function(){
365 $(contentPointer + " select").append("<option value='" + $(this).find("returnid").text() + "'>" + $(this).find("returntitle").text() + "</option>");
368 else if (action == "list") {
369 $(xml).find("acl").each(function(){
370 $(contentPointer + " select").append("<option value='" + $(this).find("value").text() + "-" + $(this).find("returnid").text() + "'>" + $(this).find("title").text() + "-" + $(this).find("returntitle").text() + "</option>");
373 $(contentPointer + " option").removeAttr('selected');
374 $(contentPointer).show("slow");
375 $("#none_acl_returns").hide();
376 $("#none_acl_list").hide();
377 $(linkPointer + " span.loading" + linkPointerPost).hide();
378 return;
381 if (control == "membership") {
382 //Remove, then re-populate, then set size of selection boxes
383 $(contentPointer + " select").empty();
384 counterActive = 0;
385 counterInactive = 0;
386 $(xml).find("active").find("group").each(function(){
387 $(contentPointer + " select:first").append("<option value='" + $(this).find("value").text() + "'>" + $(this).find("label").text() + "</option>");
388 counterActive = counterActive + 1;
390 $(xml).find("inactive").find("group").each(function(){
391 $(contentPointer + " select:last").append("<option value='" + $(this).find("value").text() + "'>" + $(this).find("label").text() + "</option>");
392 counterInactive = counterInactive + 1;
394 $(contentPointer + " option").removeAttr('selected');
395 if (counterActive > counterInactive) {
396 size = counterActive;
398 else {
399 size = counterInactive;
401 if (size > 10) {
402 size = 10;
404 if (counterActive > 0) {
405 //ensure remove the no active group alert
406 $(linkPointer + " span.alert").hide();
410 if (control == "acl" || control == "aco") {
411 //Remove, then re-populate, then set size of selection boxes
412 $(contentPointer + " select").empty();
413 counterActive = 0;
414 counterInactive = 0;
415 $(xml).find("active").find("section").each(function(){
416 $(contentPointer + " select:first").append("<optgroup label='" + $(this).find("name").text() + "'>");
417 counterActive = counterActive + 1;
418 $(this).find("aco").each(function(){
419 $(contentPointer + " select:first").append("<option value='" + $(this).find("id").text() + "'>" + $(this).find("title").text() + "</option>");
420 counterActive = counterActive + 1;
422 $(contentPointer + " select:first").append("</optgroup>");
424 $(xml).find("inactive").find("section").each(function(){
425 $(contentPointer + " select:last").append("<optgroup label='" + $(this).find("name").text() + "'>");
426 counterInactive = counterInactive + 1;
427 $(this).find("aco").each(function(){
428 $(contentPointer + " select:last").append("<option value='" + $(this).find("id").text() + "'>" + $(this).find("title").text() + "</option>");
429 counterInactive = counterInactive + 1;
431 $(contentPointer + " select:last").append("</optgroup>");
433 $(contentPointer + " option").removeAttr('selected');
434 if (counterActive > counterInactive) {
435 size = counterActive;
437 else {
438 size = counterInactive;
440 if (size > 15) {
441 size = 15;
445 //display the selection boxes
446 $(contentPointer + " select").attr('size', size);
447 $(contentPointer).show("slow");
449 if (action == "list") {
450 //Remove Edit link and show Hide link
451 $(linkPointer + " a.link_submit:first").hide();
452 $(linkPointer + " a.link_submit:last").show();
455 //Remove Loading indicator
456 $(linkPointer + " span.loading" + linkPointerPost).hide();
458 //Remove old errors, then display any new errors to user
459 $(errorPointer).empty();
460 $(xml).find("error").each(function(){
461 $(errorPointer).append("<span class='alert'>" + $(this).text() + "<br></span>");
462 $(errorPointer).show();
465 beforeSend: function(){
466 //Show Loading indicator
467 $(linkPointer + " span.loading" + linkPointerPost).show();
469 error: function(){
470 //Remove Loading indicator and show errors
471 $(linkPointer + " span.loading" + linkPointerPost).hide();
472 $(errorPointer).empty();
473 $(errorPointer).append("<span class='alert'><?php xl('ERROR, unable to collect data from server','e'); ?><br></span>");
474 $(errorPointer).show();
477 return;
480 </script>
482 <link rel="stylesheet" href="<?php echo $css_header;?>" type="text/css">
483 <style type="text/css">
484 body {
485 padding: 5pt 15pt 5pt 5pt;
486 margin: 0pt;
488 .loading {
489 font-family: sans-serif;
490 text-decoration: blink;
491 font-size: 10pt;
492 color: red;
493 font-weight: bold;
495 .alert {
496 font-family: sans-serif;
497 font-size: 10pt;
498 color: red;
499 font-weight: bold;
501 .section {
502 border: solid;
503 border-width: 1px;
504 border-color: #0000ff;
505 margin: 0 0 10pt 10pt;
506 padding: 5pt;
508 </style>
509 </head>
511 <body class="body_top">
512 <span class='title'><?php xl('Access Control List Administration','e'); ?></span>&nbsp;
513 <?php if ($phpgacl_location) {
514 echo "<a href='../../gacl/admin/acl_admin.php' onclick='top.restoreSession()'><span class='back'>(" . xl('Advanced') . ")</span></a>";
515 } ?>
516 <br><br>
517 <div id='membership_edit'>
518 <span class=bold><input type='checkbox' id='membership_show'><?php xl('User Memberships','e'); ?></span>
519 <span class='loading' style='display: none;'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<?php xl('LOADING','e'); ?>...</span>
520 <div id='membership_error'>
521 </div>
522 <div class=section id='membership' style='display: none;'>
523 </div>
524 </div>
525 <div id='acl_edit'>
526 <span class=bold><input type='checkbox' id='acl_show'><?php xl('Groups and Access Controls','e'); ?></span>
527 <a class='link_submit' href='no_javascript' id='none_acl_returns' title=<?php xl('Add New Group','e','\'','\''); ?> style='display: none;'>(<?php xl('Add New Group','e'); ?>)</a>
528 <a class='link_submit' href='no_javascript' id='none_acl_list' title=<?php xl('Remove Group','e','\'','\''); ?> style='display: none;'>(<?php xl('Remove Group','e'); ?>)</a>
529 <span class='loading' style='display: none;'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<?php xl('LOADING','e'); ?>...</span>
530 <div id='acl_error'>
531 </div>
532 <div id='div_acl_add_form' style='display: none;'>
533 <form class="section" id="acl_add_form" action="no_javascript" method="post">
534 <span class='bold'><?php xl('New Group Information','e'); ?></span><span class='loading' style='display: none;'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<?php xl('LOADING','e'); ?>...</span>
535 <table>
536 <tr>
537 <td>
538 <span class='text'><?php xl('Title','e'); ?>:</span>
539 </td>
540 <td>
541 <input type="text" id="title_field"><td><span class="alert" id="title_error"></span></td>
542 </td>
543 </tr>
544 <tr>
545 <td>
546 <span class='text'><?php xl('Identifier(one word)','e'); ?>:</span>
547 </td>
548 <td>
549 <input type="text" id="id_field"><td><span class="alert" id="identifier_error"></span></td>
550 </td>
551 </tr>
552 <tr>
553 <td>
554 <span class='text'><?php xl('Return Value','e'); ?>:</span>
555 </td>
556 <td>
557 <select id="return_field"></select><td><span class="alert" id="return_error"></span></td>
558 </td>
559 </tr>
560 <tr>
561 <td>
562 <span class='text'><?php xl('Description','e'); ?>:</span>
563 </td>
564 <td>
565 <input type="text" id="desc_field"><td><span class="alert" id="description_error"></span></td>
566 </td>
567 </tr>
568 </table>
569 <input type="submit" class="button_acl_add" id="button_acl_add_submit" title=<?php xl('Submit','e','\'','\''); ?> value=<?php xl('Submit','e','\'','\''); ?>>
570 <input type="reset" class="button_acl_add" id="button_acl_add_clear" title=<?php xl('Clear','e','\'','\''); ?> value=<?php xl('Clear','e','\'','\''); ?>>
571 <input type="reset" class="button_acl_add" id="button_acl_add_cancel" title=<?php xl('Cancel','e','\'','\''); ?> value=<?php xl('Cancel','e','\'','\''); ?>>
572 </form>
573 </div>
574 <div id='div_acl_remove_form' style='display: none;'>
575 <form class="section" id="acl_remove_form" action="no_javascript" method="post">
576 <span class='bold'><?php xl('Remove Group Form','e'); ?></span><span class='loading' style='display: none;'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<?php xl('LOADING','e'); ?>...</span>
577 <table>
578 <tr>
579 <td align="right">
580 <span class='text'><?php xl('Group','e'); ?>:</span>
581 </td>
582 <td>
583 <select id="acl_field"></select><td><span class="alert" id="aclTitle_error"></span></td>
584 </td>
585 </tr>
586 <tr>
587 <td>
588 <span class='text'><?php xl('Do you really want to delete this group','e'); ?>?</span>
589 </td>
590 <td>
591 <input type="radio" name="acl_remove_confirm" value = "yes"><span class='text'><?php xl('Yes','e'); ?></span>
592 <input type="radio" name="acl_remove_confirm" value = "no" checked><span class='text'><?php xl('No','e'); ?></span>
593 <td><span class="alert" id="remove_confirm_error"></span></td>
594 </td>
595 </tr>
596 </table>
597 <input type="submit" class="button_acl_remove" id="button_acl_remove_delete" title=<?php xl('Delete','e','\'','\''); ?> value=<?php xl('Delete','e','\'','\''); ?>>
598 <input type="reset" class="button_acl_remove" id="button_acl_remove_cancel" title=<?php xl('Cancel','e','\'','\''); ?> value=<?php xl('Cancel','e','\'','\''); ?>>
599 </form>
600 </div>
601 <div class=section id='acl' style='display: none;'>
602 </div>
603 </div>
604 </body>
605 </html>