|
|
|
|
Re: fine-grained access control [message #1541801 is a reply to message #1541624] |
Fri, 02 January 2015 08:25 |
Chris Monty Messages: 8 Registered: January 2015 |
Junior Member |
|
|
Maybe I can help. Just as a point of clarification, from reading your description it sounds to me like you don't need to be using "fine-grained" access control, but rather standard hierarchical controls. Fine-grained is where you allow access per object, and then every time you check for access, you ask "Can this user read the object with this id?" (very fine-grained). With hierarchical you're just asking "Can the user read objects at this security level?".
In your example, the behaviour is correct I think. The user's access level is loaded on startup, and does not change, so the result of execCheckLevel can be cached (and doesn't need to be called again). You need to shift the level-checking mechanism to outside of the permission object.
I use hierarchical access control. In addition to the inherited levels LEVEL_UNDEFINED(-1), LEVEL_NONE(0) and LEVEL_ALL(100), I use LEVEL_OWN(10) and LEVEL_GLOBAL(20). In my database, each Unit object has a visibility setting which determines if only its owner (current user is object's creator and has LEVEL_OWN access level) can access it, or whether all users with the LEVEL_GLOBAL permission can access it. My permission code is thus:
import org.eclipse.scout.rt.shared.security.BasicHierarchyPermission;
public class ReadUnitPermission extends BasicHierarchyPermission {
/**
* Can read own entries.
*/
public static final int LEVEL_OWN = 10;
/**
* Can read global entries.
*/
public static final int LEVEL_GLOBAL = 20;
private static final long serialVersionUID = 0L;
public ReadUnitPermission() {
super("ReadUnit", LEVEL_OWN);
}
}
Note that you set the "required" permission level in the constructor. In my case above, the default required permission level is "LEVEL_OWN". What's also important is that the permission level ids increase in value, so in my example LEVEL_UNDEFINED(-1) < LEVEL_NONE(0) < LEVEL_OWN(10) < LEVEL_GLOBAL(20) < LEVEL_ALL(100). When I want to know if the user has the permission, I can write:
ACCESS.getLevel(new ReadUnitPermission()) >= LEVEL_OWN
If I want to show filter out 'hidden' objects in an outline, I use this SQL select:
DB.selectInto(""
+ "SELECT UNIT_NR, "
+ " NAME, "
+ " LAST_MODIFIED,"
+ " SHARE_LEVEL "
+ " FROM UNIT "
+ " WHERE UNIT_NR IN :unitNrs "
+ " AND ((:permissionLevel = 100) OR (:permissionLevel >= 20 AND SHARE_LEVEL = " + PublicCode.ID + ") OR (:permissionLevel >= 10 AND SHARE_LEVEL = (" + PrivateCode.ID + ") AND USER_NR = :userNr)) "
+ " INTO :{unit.unitNr}, "
+ " :{unit.name}, "
+ " :{unit.lastModified},"
+ " :{unit.shareLevel} "
, formData
, new NVPair("permissionLevel", ACCESS.getLevel(new ReadUnitPermission()))
);
Also note, if you look at the javadoc for AbstractSqlService.execCustomBindFunction() it hints that there is standard bind support for checking permission levels using statements like:
::level(ReadUnitPermission)
I haven't tested this myself, but it might work.
|
|
|
Powered by
FUDForum. Page generated in 0.04470 seconds