Authorization and Authentication
LibreHealth has a very granulated permissions system. Every action is associated with a Privilege. An action would be "Add Patient", "Update Patient", "Delete Patient", "Add Concept", "Update Concept", etc. A Role contains a collection of Privileges. A Role can also point to a list of inherited roles. The role inherits all privileges from that inherited role. In this way, hierarchies of roles are possible. A User contains only a collection of Roles, not Privileges.
AOP annotations are used to require a privilege for a service method.
@Authorized({"Add Patients"})
The annotation is placed in the interface of the service. If the current user does not possess that privilege an APIAuthenticationException is thrown. (The webapp catches this exception and redirects to the login form).
Each page in the webapp is able to require a certain privilege for the page with the openmrs:require taglib. The openmrs:hasPrivilege taglib provides support for restricting only certain sections of a page.
While using the API, you may come to a point where you need to temporarily grant the current user a certain privilege in order to make an API call. This is accomplished using the Context.addProxyPrivilege(String priv) and removeProxyPrivilege(String priv) methods. Multiple priv objects defining the same string can be proxied. Subsequent calls to removePrivilege will only pop the first one off the stack. Best practice says that you should put your API method calls in a try/catch block and put the removeProxyPrivilege call in a finally block.