Granting access to specific users to manage drug and product inventory

kodusote wrote on Monday, February 10, 2014:

At present, only persons with Administrator role have access to manage the in-house Inventory of drugs and products. It forces one to give this high level role to persons that only need to add this task to their current role such as the pharmacist or store-keeper. Is there a way one can grant this access as a separate task so that it can be given to whoever needs to manage the inventory without being given the role of an Administrator?

blankev wrote on Monday, February 10, 2014:

Just give the person, that can be appointed, an extra User PW name with extra written instructions of responsibility. USER: Admin2 PW: PW2. This person will be logged as Admin2 and PW2 so whoever needs to control, can check this persons goings. The only risk that comes in view, is this person with admin rights can also view the medical problems of the database AND make mistakes and ruin your program as every administrator can do.

kodusote wrote on Monday, February 10, 2014:

Thanks Pieter. That is what we are doing at present with all the associated risks you mentioned. This is why we are looking for other ways of limiting th risks and remove the need for someone to keep looking over the person’s shoulder.

fsgl wrote on Monday, February 10, 2014:

A new user, pharmacist, was created in the 4.1.2 Demo, password=pass. All other Administration ACO’s were removed except Dispensary. Problem is that the new user can only destroy drugs. Not much good if Add Drugs is unavailable.

Fine granular control from ACL not possible. Nor is it possible from phpGACL.

Code modification necessary to gain fine granular control.

blankev wrote on Monday, February 10, 2014:

Did you open Globals? Features? Second row: Activate Drugs and Products: Inventory and sell both drugs and non-drugs product.

Login: admin an pass, I am able to do the work create new drugs and inventory.

Next step would to create: Admin2 and PW2 and you are able to sell products and add products. I did not try to delete. Since most advises are usually do not delete in the Databases but inactivate.

From there you might be able to downgrade the options through ACL for admin2

It is all working in Demo V 4.1.2 till next reset. I added an special Weight Tablet.

blankev wrote on Monday, February 10, 2014:

Phill Belford got some of those miracle drug on his encounter 10-feb-2014

Demo V 4.1.2

blankev wrote on Monday, February 10, 2014:

If you want to make a difference for the drug add administrator you have to dive into Advanced (top row) in the ACL-permissions.

Add a User the with the same rights as administrator and start deleting permissions for the drug-administrator.

I do not understand this exercise but probably some other users know what to do and what NOT to do and this last thing seems even more important.

And a little bit luck wish from this side of OpenEMR…, let us know what you did if you accomplished what needed to be done for only a drug add administrator.

fsgl wrote on Monday, February 10, 2014:

Did all of the above with new user, pharmacist. Feckless if pharmacist can only destroy drugs.

Brady explained here about the lack of fine granular control.

blankev wrote on Tuesday, February 11, 2014:

If you go to Demo V 4.1.2 patch 3 you Login: parm and password: pharm tell me if you can or can not add and destroy.

I Can do both. But also see all the client information, what should be tweaked out.

blankev wrote on Tuesday, February 11, 2014:

What demo version are you using?

fsgl wrote on Tuesday, February 11, 2014:

In Demo 4.1.2 (3) pharm has all the Administration privileges, hence able to add and destroy drugs. Back to square 1.

Creating a new user and a new group does not solve the problem either. Only solution is code modification.

blankev wrote on Tuesday, February 11, 2014:

Did you try to make the needed steps for the Demo Pharmacist to make ACL security so this Pharmacist can do some and do other things NOT in the Advanced table?

If you did, what did you do so I don’t have to experiment with the same steps.

fsgl wrote on Tuesday, February 11, 2014:

If Advanced table = clicking the Advanced link -> phpGACL. Unable to make any changes there.

Because of unfamiliarity with the gacl tables, no reason to work there.

All changes occurred in OpenEMR’s ACL menu (not Advanced, ACL Admin).

blankev wrote on Tuesday, February 11, 2014:

fsgl,

we could do it together. Make a WIKI about ACL, or just find the correct tweaking with me. The manual and explanation of ACL is finely grained and explains in lay terms what you can and what not to expect.

We could rewrite the manual with OpenEMR words. I am sure there have been done something in the past but I did not yet look it up.

fsgl wrote on Tuesday, February 11, 2014:

There is a Wiki article on ACL that I think that Brady authored. A more basic tutorial may be needed for neophytes. Will put it on my agenda.

Because Windows XP will no longer be supported after April of this year, I put in a larger hard drive for my desktop, installed Ubuntu 12.04 LTS (open source is wonderful!) with a dual-boot. Even fooled around with BitTorrent for the download. But can’t make a silk purse out of a sow’s ear. No way to make a DSL connection faster except to cough up more money for a cable connection. Will have to get everything tidy with Ubuntu before that article on ACL can be started.

kodusote wrote on Wednesday, February 12, 2014:

I have tried the suggestions by Pieter on my test site (4.1.2 patch 4) and the only way to make the user manage the drug inventory is to give the Administrator role.

I checked the link suggested by fsgl and the wikis on Access Control List and ACOs and there does not appear to be an ACO limited to the management of the drug inventory. The Pharmacy Dispensary control is related to drug dispensing and not the inventory management. It appears that the control of inventory management is “hidden” in the Administrator’s battery of controls that need to be made more granular in order for this to be granted to others.

It would be appreciated if any of the developers (won’t want to bother Brady) could guide as to how this can be done on one’s test site.

Kayode

bradymiller wrote on Wednesday, February 12, 2014:

Hi Kayode,

In linux, can do a quick review of what acl_check() things are happening in the drugs scripts via the following grep command (doing withing the openemr directory):
grep -B 4 -A 4 -R “acl_check” interface/drugs/

and here is the output(note the acl_check in center of each code block, so you can begin to infer what each one does):

Let me know where the script(s) for your inventory stuff is and can then do the same.


interface/drugs/add_edit_lot.php-$info_msg = "";
interface/drugs/add_edit_lot.php-
interface/drugs/add_edit_lot.php-$form_trans_type = isset($_POST['form_trans_type']) ? $_POST['form_trans_type'] : '0';
interface/drugs/add_edit_lot.php-
interface/drugs/add_edit_lot.php:if (!acl_check('admin', 'drugs')) die(xlt('Not authorized'));
interface/drugs/add_edit_lot.php-if (!$drug_id) die(xlt('Drug ID missing!'));
interface/drugs/add_edit_lot.php-?>
interface/drugs/add_edit_lot.php-<html>
interface/drugs/add_edit_lot.php-<head>
--
interface/drugs/drug_inventory.php- require_once("$srcdir/formatting.inc.php");
interface/drugs/drug_inventory.php- require_once("$srcdir/htmlspecialchars.inc.php");
interface/drugs/drug_inventory.php-
interface/drugs/drug_inventory.php- // Check authorization.
interface/drugs/drug_inventory.php: $thisauth = acl_check('admin', 'drugs');
interface/drugs/drug_inventory.php- if (!$thisauth) die(xlt('Not authorized'));
interface/drugs/drug_inventory.php-
interface/drugs/drug_inventory.php-// For each sorting option, specify the ORDER BY argument.
interface/drugs/drug_inventory.php-//
--
interface/drugs/destroy_lot.php- $drug_id = $_REQUEST['drug'];
interface/drugs/destroy_lot.php- $lot_id  = $_REQUEST['lot'];
interface/drugs/destroy_lot.php- $info_msg = "";
interface/drugs/destroy_lot.php-
interface/drugs/destroy_lot.php: if (!acl_check('admin', 'drugs')) die(xlt('Not authorized'));
interface/drugs/destroy_lot.php- if (!$drug_id) die(xlt('Drug ID missing!'));
interface/drugs/destroy_lot.php- if (!$lot_id ) die(xlt('Lot ID missing!'));
interface/drugs/destroy_lot.php-?>
interface/drugs/destroy_lot.php-<html>
--
interface/drugs/add_edit_drug.php- $drug_id = $_REQUEST['drug'];
interface/drugs/add_edit_drug.php- $info_msg = "";
interface/drugs/add_edit_drug.php- $tmpl_line_no = 0;
interface/drugs/add_edit_drug.php-
interface/drugs/add_edit_drug.php: if (!acl_check('admin', 'drugs')) die(xlt('Not authorized'));
interface/drugs/add_edit_drug.php-
interface/drugs/add_edit_drug.php-// Format dollars for display.
interface/drugs/add_edit_drug.php-//
interface/drugs/add_edit_drug.php-function bucks($amount) {
--
interface/drugs/add_edit_drug.php-     "WHERE drug_id = ?", array($drug_id));
interface/drugs/add_edit_drug.php-    sqlStatement("DELETE FROM drug_templates WHERE drug_id = ?", array($drug_id));
interface/drugs/add_edit_drug.php-   }
interface/drugs/add_edit_drug.php-   else { // deleting
interface/drugs/add_edit_drug.php:    if (acl_check('admin', 'super')) {
interface/drugs/add_edit_drug.php-     sqlStatement("DELETE FROM drug_inventory WHERE drug_id = ?", array($drug_id));
interface/drugs/add_edit_drug.php-     sqlStatement("DELETE FROM drug_templates WHERE drug_id = ?", array($drug_id));
interface/drugs/add_edit_drug.php-     sqlStatement("DELETE FROM drugs WHERE drug_id = ?", array($drug_id));
interface/drugs/add_edit_drug.php-     sqlStatement("DELETE FROM prices WHERE pr_id = ? AND pr_selector != ''", array($drug_id));
--
interface/drugs/add_edit_drug.php-
interface/drugs/add_edit_drug.php-<p>
interface/drugs/add_edit_drug.php-<input type='submit' name='form_save' value='<?php echo xla('Save'); ?>' />
interface/drugs/add_edit_drug.php-
interface/drugs/add_edit_drug.php:<?php if (acl_check('admin', 'super')) { ?>
interface/drugs/add_edit_drug.php-&nbsp;
interface/drugs/add_edit_drug.php-<input type='submit' name='form_delete' value='<?php echo xla('Delete'); ?>' style='color:red' />
interface/drugs/add_edit_drug.php-<?php } ?>
interface/drugs/add_edit_drug.php-
--
interface/drugs/dispense_drug.php- $quantity        = $_REQUEST['quantity'];
interface/drugs/dispense_drug.php- $fee             = $_REQUEST['fee'];
interface/drugs/dispense_drug.php- $user            = $_SESSION['authUser'];
interface/drugs/dispense_drug.php-
interface/drugs/dispense_drug.php: if (!acl_check('admin', 'drugs')) die(xl('Not authorized'));
interface/drugs/dispense_drug.php-
interface/drugs/dispense_drug.php- if (!$drug_id        ) $drug_id = 0;
interface/drugs/dispense_drug.php- if (!$prescription_id) $prescription_id = 0;
interface/drugs/dispense_drug.php- if (!$quantity       ) $quantity = 0;

blankev wrote on Wednesday, February 12, 2014:

To be seen in : http://demo.open-emr.org:2107/openemr/interface/main/main_screen.php?auth=login&site=default

Create a Group called Pharmacist.

Now in Groups give Pharmicist the Following:

ACL Administration

AND

Pharmacy Dispensary

Pharmacist need to have activated both, to be able to Add and Destroy.
Many other options are inactivated. You can probably lock down more activities, but this has to wait till another day.

kodusote wrote on Wednesday, February 12, 2014:

Dear Brady,

Thanks for your help. The result of the grep of the drug directory is as follows:
fshd@ubuntu:/var/www/openemr$ grep -B 4 -A 4 -R “acl_check” interface/drugs/
interface/drugs/dispense_drug.php- $quantity = $_REQUEST[‘quantity’];
interface/drugs/dispense_drug.php- $fee = $_REQUEST[‘fee’];
interface/drugs/dispense_drug.php- $user = $_SESSION[‘authUser’];
interface/drugs/dispense_drug.php-
interface/drugs/dispense_drug.php: if (!acl_check(‘admin’, ‘drugs’)) die(xl(‘Not authorized’));
interface/drugs/dispense_drug.php-
interface/drugs/dispense_drug.php- if (!$drug_id ) $drug_id = 0;
interface/drugs/dispense_drug.php- if (!$prescription_id) $prescription_id = 0;
interface/drugs/dispense_drug.php- if (!$quantity ) $quantity = 0;

interface/drugs/drug_inventory.php- require_once("$srcdir/formatting.inc.php");
interface/drugs/drug_inventory.php- require_once("$srcdir/htmlspecialchars.inc.php");
interface/drugs/drug_inventory.php-
interface/drugs/drug_inventory.php- // Check authorization.
interface/drugs/drug_inventory.php: $thisauth = acl_check(‘admin’, ‘drugs’);
interface/drugs/drug_inventory.php- if (!$thisauth) die(xlt(‘Not authorized’));
interface/drugs/drug_inventory.php-
interface/drugs/drug_inventory.php-// For each sorting option, specify the ORDER BY argument.
interface/drugs/drug_inventory.php-//

interface/drugs/add_edit_drug.php- $drug_id = $_REQUEST[‘drug’];
interface/drugs/add_edit_drug.php- $info_msg = “”;
interface/drugs/add_edit_drug.php- $tmpl_line_no = 0;
interface/drugs/add_edit_drug.php-
interface/drugs/add_edit_drug.php: if (!acl_check(‘admin’, ‘drugs’)) die(xlt(‘Not authorized’));
interface/drugs/add_edit_drug.php-
interface/drugs/add_edit_drug.php-// Format dollars for display.
interface/drugs/add_edit_drug.php-//
interface/drugs/add_edit_drug.php-function bucks($amount) {

interface/drugs/add_edit_drug.php- “WHERE drug_id = ?”, array($drug_id));
interface/drugs/add_edit_drug.php- sqlStatement(“DELETE FROM drug_templates WHERE drug_id = ?”, array($drug_id));
interface/drugs/add_edit_drug.php- }
interface/drugs/add_edit_drug.php- else { // deleting
interface/drugs/add_edit_drug.php: if (acl_check(‘admin’, ‘super’)) {
interface/drugs/add_edit_drug.php- sqlStatement(“DELETE FROM drug_inventory WHERE drug_id = ?”, array($drug_id));
interface/drugs/add_edit_drug.php- sqlStatement(“DELETE FROM drug_templates WHERE drug_id = ?”, array($drug_id));
interface/drugs/add_edit_drug.php- sqlStatement(“DELETE FROM drugs WHERE drug_id = ?”, array($drug_id));
interface/drugs/add_edit_drug.php- sqlStatement(“DELETE FROM prices WHERE pr_id = ? AND pr_selector != ‘’”, array($drug_id));

interface/drugs/add_edit_drug.php-
interface/drugs/add_edit_drug.php-


interface/drugs/add_edit_drug.php-<input type=‘submit’ name=‘form_save’ value=’<?php echo xla('Save'); ?>’ />
interface/drugs/add_edit_drug.php-
interface/drugs/add_edit_drug.php:<?php if (acl_check('admin', 'super')) { ?>
interface/drugs/add_edit_drug.php- 
interface/drugs/add_edit_drug.php-<input type=‘submit’ name=‘form_delete’ value=’<?php echo xla('Delete'); ?>’ style=‘color:red’ />
interface/drugs/add_edit_drug.php-<?php } ?>
interface/drugs/add_edit_drug.php-

interface/drugs/destroy_lot.php- $drug_id = $_REQUEST[‘drug’];
interface/drugs/destroy_lot.php- $lot_id = $_REQUEST[‘lot’];
interface/drugs/destroy_lot.php- $info_msg = “”;
interface/drugs/destroy_lot.php-
interface/drugs/destroy_lot.php: if (!acl_check(‘admin’, ‘drugs’)) die(xlt(‘Not authorized’));
interface/drugs/destroy_lot.php- if (!$drug_id) die(xlt(‘Drug ID missing!’));
interface/drugs/destroy_lot.php- if (!$lot_id ) die(xlt(‘Lot ID missing!’));
interface/drugs/destroy_lot.php-?>
interface/drugs/destroy_lot.php-

interface/drugs/add_edit_lot.php-$info_msg = “”;
interface/drugs/add_edit_lot.php-
interface/drugs/add_edit_lot.php-$form_trans_type = isset($_POST[‘form_trans_type’]) ? $_POST[‘form_trans_type’] : ‘0’;
interface/drugs/add_edit_lot.php-
interface/drugs/add_edit_lot.php:if (!acl_check(‘admin’, ‘drugs’)) die(xlt(‘Not authorized’));
interface/drugs/add_edit_lot.php-if (!$drug_id) die(xlt(‘Drug ID missing!’));
interface/drugs/add_edit_lot.php-?>
interface/drugs/add_edit_lot.php-
interface/drugs/add_edit_lot.php-
fshd@ubuntu:/var/www/openemr$

In addition, there is acl_check() in the left_nav.php which I think controls the display of the link to the Management module. At present, only persons with Administration access rights can view the link on the menu, all others see only the “Destroyed” link.

Regards.

Kayode

bradymiller wrote on Friday, February 21, 2014:

Hi,

This is a bug in left_nav.php. Here’s the fix:
https://github.com/bradymiller/openemr/commit/374720db4f4ea399f7f3b0d64537a24903598ce8

Let me know if you think the person with this aco should also have destroy privileges (currently this is only the super, which seems odd).

Will plan to commit this to main codebase over next several days (and will include it in the next 4.1.2 patch).

-brady
OpenEMR