Rights

In this Lesson

You will learn how to provide fine-grained security for features within a solution.

Concepts

Most non-trivial solutions require you to restrict access to certain features. For example, managers are likely to be granted more features than the people they manage and system administrators may have access to configuration information but no access to the actual information contained in the solution.

Soiree provides two mechanisms to control access to features.

  1. Scenes
    By controlling a person’s access to scenes you control what they can do. This is rather large-grained control.
  2. Rights
    Rights provide fine-grained control over securable features. You can think of rights as keys you hand out to users which allow them to unlock some feature in your solution.

A right is a formal definition of a secured feature. A right can represent anything and you would create a right only for things which need to be selectively granted to users – meaning you plan for some users to access the thing while others cannot.

Here are some of the ways a right may be used

  • To control access to agent events
  • To control access to agent conduits
    (Conduits have not been discussed yet. They are the processing channel behind the drop side of drag and drop operations.)
  • To control visibility of an element or layer in a scene
  • To control logic inside an agent

Creating Rights

Rights are a Soiree item and are defined using a Soiree item wizard just like any other item. Here is an example of the wizard creating a right to control the ability to delete parties. Notice the definition is very simple – it is really just an ID (package.Name) that represents something.



Subscribing to Rights

Agents have the ability to subscribe to rights. This is somewhat akin to an agent’s ability to subscribe to context values: when an agent expresses an interest in a right it is delivered to the agent via its scheme.

An agent subscribes to rights in two ways

  1. Adding a right to the agent’s Rights section of the agent definition by right-clicking in the rights section.

  2. By attaching a right to an event or conduit.
    The event or conduit will be enabled if the user has been granted the right or disabled if they have not.



    When you add a right to an event or conduit the right is also added to the subscribed rights section of the agent definition.

When agents subscribe to rights their schemes will contain a boolean value for each right. At runtime the pump will set these values to true if there is a user on the connection and the user has been granted the right otherwise they will be set to false. These boolean values in the scheme may be used in two ways

  1. The developer can use the right to perform conditional logic in the agent.
    The scheme will contain a method starting with isRight followed by the underscore delimited name of the right, for example: public Boolean isRight_com_example_party_right_DeleteParty()
  2. The designer can use the right to control visibility of an element or layer in a scene.

Checking a user’s rights

Any Java class which has access to the SoireeUser object can determine if a user has been granted a right. For example, an agent which does not subscribe to a right may still check to see if it has been granted to the user as follows

SoireeUser user = getConversation().getConnection().getUser();
if (user != null){
	if (user.hasRight("com.example.party.right.DeleteParty"))
		System.out.println("User may delete");
}

Using Rights in the party solution

The PartyDefinition scene you created provides the ability to both delete and edit a party. Anyone who has access to this scene may perform those functions – unless you secure them.

Let’s imagine you now are required to restrict access to the delete and edit features to selected users. You have two choices

  1. Create separate scenes for each capability
    You could provide separate scenes to view, create, edit, or delete a scene and then restrict users to only the scenes they should have access to. You will be doing this in a future lesson through the use of security groups and menus.
  2. Create rights to control access to the delete and edit capabilities within the existing scene. This lesson goes there.

Creating Rights

You will now create rights for securing the delete and edit features.

  1. Create a right for securing the delete feature



  2. Create a right for securing the edit feature



You should now have two rights defined in your project



Subscribing to Rights

You will now modify the PartyList and Party agents to subscribe to these rights.

  1. Open the PartyList agent definition
  2. Select the list tab at the bottom of the agent editor



  3. Select the delete event



  4. Secure the event with the DeleteParty right



  5. Select the Agent tab
  6. Expand the Rights section. You should see the subscribed right in the list of subscribed rights



  7. Build the agent



  8. Inspect the com.example.party.agent.partylist.PartyListS scheme class in the src-gen folder. The class should now contain this method



  9. Inspect the com.example.party.agent.partylist.PartyListSuper scheme class in the src-gen folder. Notice the delete event processing is now only allowed if the DeleteParty right is enabled.



  10. Important
    The agent is responsible for data integrity and security and should ensure users rights are respected. The designer could choose to fire the event at any time (forgetting or not knowing there is a security restriction) but the agent should only process the event if the user is authorized.
  11. Open the Party agent definition
  12. Expand the Rights section
  13. Right click in the rights section and add the EditParty right to the subscribed rights list



  14. Build the Party agent



Using rights in custom code

We mentioned a moment ago agents are responsible for security. Notice we just added a right to the Party agent but did not associate it with anything. The design intent for the EditParty right is to secure the ability to modify a party. What does that mean? In our simple solution it means the user should not be able to modify a row in the party table. It may mean something much broader in more fully instrumented solutions.

Imagine for a moment your party solution included the ability to define a menu of items to be served, a list of personnel to work the event, and a supplies list. Might ‘edit a party’ include all of these things? If so, then you need to ensure you secure updates to all that information as well.

So, how can agents secure the edit capability? You accomplish that with custom code. Let’s do that now. Because your party solution is very simple this will only involve protecting one table with one agent. The pattern we are about to show you would be replicated in multiple agents if the solution were more elaborate.

Danger
Remember, all custom code may only be added to classes in the src folder. If you customize anything in the src-gen folder those changes will be lost the next time you build the agent.
  1. Open the Party agent class in the src folder.



  2. Position the cursor at the bottom of the class and then select the following option from the Eclipse menu



    Add the isUpdateReady method to the class



  3. Replace the contents of the method with the following code using copy and paste from this document
    SoireeUser user = getConversation().getConnection().getUser();
    		
    if (user != null && user.hasRight("com.example.party.right.EditParty"))
    	return true;
    
    scheme.setSchemeMessage(error("You do not have the authority to modify the party"));
    return false;
    
  4. Resolve the syntax error by hovering the cursor over the error and selecting ‘import SoireeUser’ from the quick fix menu.



  5. You should now have a method that looks like this



Tip
You do not have to manually type item IDs. Right click on an item file in the package explorer, hover over the item type in the context menu, and select copy item ID to the clipboard



Test the agent security

Let’s test the solution and see how it has changed.

  1. Start Derby if it is not running
  2. Start the server (restart the server if it is already running so it obtains the updated Java classes)
  3. Start the Party Pool solution and advance to the party list
  4. Notice the delete icon is disabled.
    The delete button is disabled because it is attached to the delete event in the PartyList agent (which is disabled). The event is disabled because there is no user (a sign on process is not being used).



  5. Select a party from the list
    Notice the Edit hyperlink is still enabled.



  6. Select the Edit link
  7. Update a value in the party definition and press OK
    The update should be rejected as shown here.



Modify the scene to respect the rights

You will now make the scene alter its presentation to match the authority granted to the user.

Designer choice vs Developer Responsibility
Making the scene responsive to user security is a choice made by the designer to alter the user experience. It is not a substitute for securing the solution. As stated earlier – the agent is responsible for securing the solution – regardless of what may be requested by the scene.
  1. Open the PartyDefinition scene
  2. Bind the EditParty right to the Edit hyperlink’s visible property.



    The hyperlinks bindings should now be as follows



  3. Save the scene definition
  4. Retest the solution.
    The Edit hyperlink should not be displayed because there is no user attached to the connection.



Hiding elements in a list

What if you wanted to hide the delete button in the party list instead of simply disabling it? How would you accomplish that?

Well, you could try dragging the right to the element in the same way you did for the Edit hyperlink. If you try this you will notice you are not allowed to drop the right onto the delete button.



Why are you not allowed to drop the right onto the element?

If you take a look at the binding properties for one of the elements in the styled grid you will notice the row is locked to the list grid.



Elements in a styled grid’s row may only accept child nodes contained in a grid node. Furthermore, this particular styled grid row is already locked to the the list grid node so it will only accept nodes from the same parent (the list node).

If you want to conditionally hide the delete button in the party list you must provide a boolean value in the list grid node as shown here.



The agent must then set this value when it is loading its scheme. The best place would be to provide this override method in the PartyList class as shown here



You can then bind the deleteAllowed node to the button’s visible property.



If you restart the server and run the solution the buttons will now be hidden.



That’s all for this lesson. You now have the right stuff.