Application Users, Privileges and Login
25/09/2009. Christian Hein
Introduction
Users, privileges, roles and authentication are very common issues to take into account during an application development process. JRapid simplifies the basics of this task by providing a built-in solution, partly eased by the definition of the required entities through a template and the use of stereotypes to take advantage of built in behavior for these classes.
User Management Template
Templates are available through the JRapid Community. They are a piece of JRapid source code that contains the definition of entities that together model a certain functionality or pattern. To import the template go to the Community menu and select the Add templates option.

This will show you a list of the available templates. Click on the Import link to the right of the User management template.

This will automatically create the entities and other resources needed to implement this functionality.

Note: the entities are created in dirty mode.
The User entity implements the User stereotype. This requires the entity to define the username, password, privileges and roles properties. More properties can be added to the User entity, but the ones mentioned above must be present.
Privileges is a special enumset and defines fixed options for the application that can only be changed during development. This enumeration of options will allow you to define the access privileges present in the application to the finest detail. This enumset is created with no values.

Privileges are bound to application functionality, this means, they are part of the application's source code and thus are fixed during execution.
The Role entity uses the Role stereotype. A Role groups privileges and makes it easier to grant them to a User. Roles, for being represented by an entity, can be defined or modified during execution of the application. This gives flexibility to this permissions approach. Roles are dynamic and represent real world user profiles.
The Login entity is transient and implements the Login stereotype. This provides the entity with the methods required for authentication of Users. By defining the entity in this way the form will automatically validate the entered credentials against the User records upon submit. If the authentication is successful, the application sets the user and granted privileges as attributes of the established session. In the Advanced tab of the Login entity details form you may see the Login stereotype selected, as expected, and a loginRedirect value for the Next function attribute. This defines the name of a JavaScript function to be executed after a successful login. You have to define this function in order to avoid getting an error after user login. In general, this function redirects the user to a particular panel.

The ChangePassword entity defines the properties required for a change password form but does not implement this functionality. You must overwrite the store method in the ChangePasswordServices class to perform the action.
Application
Once all the entities, privileges and roles have been defined the developer must make use of them to limit the access for users depending on their role.
There are several ways in which this model can be used and these may be used in conjunction.
Separation of data
Depending on the role granted to a User the records belonging to a certain entity may be listed in a partial way. Take the following example. A sales application has a Company entity that stores all the prospects and clients. Only one user is the responsible seller for a company. Each user may only list and edit their companies.

If a login process is implemented then we may know who the user that is listing the companies is and show only the corresponding records. This may be accomplished by defining a subset that filters the records by the property holding the seller value for each company. For getting the current user's id, JRapid offers the variable userId.

With the subset created we can now create a listing that uses it to filter the results to be shown.

Before taking a look at the listing we've just created we must use the Login form to establish a session.

After authenticating successfully we navigate to the listing using the same browser window where the session was established.

The list shows only the companies that belong to the user Tom.
Authorization
During development you may define different restrictions for the basic operations based on the privileges. These restrictions are defined for each entity. In the Advanced tab of the Edit entity form you enable this feature by checking the Restrict option.

You may define the privilege required to save, read, list or remove records of an entity. These restrictions are saved in the authorization.properties file of your project.
The restrictions defined here take effect in two levels. They restrict access to the files that implement the UI and they restrict the access to the web services that are involved in each operation.
When a user without the necessary privileges tries to execute a restricted operation the system blocks the call and shows an error message.

Custom user information usage
When customizing functionality through java coding you can access the session to identify the current user and check privileges to restrict certain operations.
For example, you may find the current user with the following sentence:
User user = User.DAO().findById(Session.getMySession().getUserId());
And you may check if a given privilege is granted to the user by:
if(user.getPrivileges().contains("R")) {
...
}
Appendix
Including a custom JavaScript library
You may create a file with a .js extension and define in it all the custom functions your applications needs. To be able to execute this functions that are called from Next functions attributes or upon certain events the library must be included in the front end files (forms, listings or panels). To do this you may use the <config> element, an <app> child, in your XML JRapid source definition.
For example, if your library's file is named myfunctions.js, you could include it with the following:
<?xml version="1.0" encoding="UTF-8"?>
<app basepackage="com.loginexample2009" name="Main">
<config>
<usescript location="myfunctions.js"/>
</config>
. . .
</app>
loginRedirect example
function loginRedirect() {
window.location.href = '../forms.Main/Index.htmli';
}
Encrypted passwords
Passwords are encrypted due to the use of the encrypt attribute in the property holding this value.
<property label="Password" name="password" type="password"encrypt="encrypt"/>In the Login entity an encrypt attribute is included at entity tag level.
< entity encrypt="encrypt" label="Log In" name="Login" stereotype="Login" transient="transient">