Skip to content

Commit

Permalink
Implemented permission-based "delete" button visibility in generic vi…
Browse files Browse the repository at this point in the history
…ew screen.
  • Loading branch information
nmihajlovski committed Jan 5, 2015
1 parent d4b33f1 commit 3ab51a5
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 5 deletions.
Expand Up @@ -24,6 +24,7 @@
import org.rapidoid.db.DB; import org.rapidoid.db.DB;
import org.rapidoid.html.Tag; import org.rapidoid.html.Tag;
import org.rapidoid.http.HttpExchange; import org.rapidoid.http.HttpExchange;
import org.rapidoid.security.Secure;
import org.rapidoid.util.U; import org.rapidoid.util.U;
import org.rapidoid.widget.FormWidget; import org.rapidoid.widget.FormWidget;


Expand All @@ -43,7 +44,13 @@ public Object content(HttpExchange x) {
return x.notFound(); return x.notFound();
} }


FormWidget details = show(entity).buttons(EDIT, BACK, DELETE); FormWidget details = show(entity);

if (Secure.getObjectPermissions(x.username(), entity).delete) {
details = details.buttons(EDIT, BACK, DELETE);
} else {
details = details.buttons(EDIT, BACK);
}


return row(caption, details); return row(caption, details);
} }
Expand Down
Expand Up @@ -37,7 +37,7 @@
@CanRead(CommonRoles.LOGGED_IN) @CanRead(CommonRoles.LOGGED_IN)
@CanChange({ CommonRoles.OWNER }) @CanChange({ CommonRoles.OWNER })
@CanInsert(CommonRoles.LOGGED_IN) @CanInsert(CommonRoles.LOGGED_IN)
@CanDelete(CommonRoles.OWNER) @CanDelete({ CommonRoles.OWNER, CommonRoles.ADMIN })
public class Task extends Entity { public class Task extends Entity {


@CanChange({ MODERATOR, OWNER }) @CanChange({ MODERATOR, OWNER })
Expand Down
Expand Up @@ -252,7 +252,7 @@ protected void initPermissions() {


for (int i = 0; i < fieldNames.length; i++) { for (int i = 0; i < fieldNames.length; i++) {
if (permissions[i] == null) { if (permissions[i] == null) {
permissions[i] = Secure.getDataPermissions(exchange().username(), targetClass, target, permissions[i] = Secure.getPropertyPermissions(exchange().username(), targetClass, target,
fieldNames[i]); fieldNames[i]);
} }
} }
Expand Down
Expand Up @@ -98,7 +98,8 @@ public static boolean hasAnyRole(String username, String[] roles, Class<?> clazz
return false; return false;
} }


public static DataPermissions getDataPermissions(String username, Class<?> clazz, Object target, String propertyName) { public static DataPermissions getPropertyPermissions(String username, Class<?> clazz, Object target,
String propertyName) {
U.notNull(clazz, "class"); U.notNull(clazz, "class");


if (Collection.class.isAssignableFrom(clazz) || Map.class.isAssignableFrom(clazz) if (Collection.class.isAssignableFrom(clazz) || Map.class.isAssignableFrom(clazz)
Expand Down Expand Up @@ -127,6 +128,65 @@ public static DataPermissions getDataPermissions(String username, Class<?> clazz
return DataPermissions.from(read, insert, change, delete); return DataPermissions.from(read, insert, change, delete);
} }


public static DataPermissions getClassPermissions(String username, Class<?> clazz) {
U.notNull(clazz, "class");

if (Collection.class.isAssignableFrom(clazz) || Map.class.isAssignableFrom(clazz)
|| Object[].class.isAssignableFrom(clazz)) {
return DataPermissions.ALL;
}

if (!hasRoleBasedAccess(username, clazz, null)) {
return DataPermissions.NONE;
}

CanRead canRead = Metadata.classAnnotation(clazz, CanRead.class);
CanInsert canInsert = Metadata.classAnnotation(clazz, CanInsert.class);
CanChange canChange = Metadata.classAnnotation(clazz, CanChange.class);
CanDelete canDelete = Metadata.classAnnotation(clazz, CanDelete.class);

if (canRead == null && canInsert == null && canChange == null && canDelete == null) {
return DataPermissions.ALL;
}

boolean read = canRead != null && hasAnyRole(username, canRead.value(), clazz, null);
boolean insert = canInsert != null && hasAnyRole(username, canInsert.value(), clazz, null);
boolean change = canChange != null && hasAnyRole(username, canChange.value(), clazz, null);
boolean delete = canDelete != null && hasAnyRole(username, canDelete.value(), clazz, null);

return DataPermissions.from(read, insert, change, delete);
}

public static DataPermissions getObjectPermissions(String username, Object target) {
U.notNull(target, "target");
Class<?> clazz = target.getClass();

if (Collection.class.isAssignableFrom(clazz) || Map.class.isAssignableFrom(clazz)
|| Object[].class.isAssignableFrom(clazz)) {
return DataPermissions.ALL;
}

if (!hasRoleBasedAccess(username, clazz, null)) {
return DataPermissions.NONE;
}

CanRead canRead = Metadata.classAnnotation(clazz, CanRead.class);
CanInsert canInsert = Metadata.classAnnotation(clazz, CanInsert.class);
CanChange canChange = Metadata.classAnnotation(clazz, CanChange.class);
CanDelete canDelete = Metadata.classAnnotation(clazz, CanDelete.class);

if (canRead == null && canInsert == null && canChange == null && canDelete == null) {
return DataPermissions.ALL;
}

boolean read = canRead != null && hasAnyRole(username, canRead.value(), clazz, target);
boolean insert = canInsert != null && hasAnyRole(username, canInsert.value(), clazz, target);
boolean change = canChange != null && hasAnyRole(username, canChange.value(), clazz, target);
boolean delete = canDelete != null && hasAnyRole(username, canDelete.value(), clazz, target);

return DataPermissions.from(read, insert, change, delete);
}

public static List<String> getUserRoles(String username) { public static List<String> getUserRoles(String username) {
return security.getUserRoles(username); return security.getUserRoles(username);
} }
Expand Down
Expand Up @@ -28,7 +28,7 @@ public abstract class SecurityTestCommons extends TestCommons implements CommonR
protected void checkPermissions(String username, Class<?> clazz, Object target, String propertyName, protected void checkPermissions(String username, Class<?> clazz, Object target, String propertyName,
boolean canRead, boolean canChange) { boolean canRead, boolean canChange) {


DataPermissions perms = Secure.getDataPermissions(username, clazz, target, propertyName); DataPermissions perms = Secure.getPropertyPermissions(username, clazz, target, propertyName);


eq(perms.read, canRead); eq(perms.read, canRead);
eq(perms.change, canChange); eq(perms.change, canChange);
Expand Down
5 changes: 5 additions & 0 deletions rapidoid-utils/src/main/java/org/rapidoid/util/Metadata.java
Expand Up @@ -36,6 +36,11 @@ public static Map<Class<?>, Annotation> classAnnotations(Class<?> clazz) {
return annotations; return annotations;
} }


@SuppressWarnings("unchecked")
public static <T extends Annotation> T classAnnotation(Class<?> clazz, Class<T> annotationClass) {
return (T) classAnnotations(clazz).get(annotationClass);
}

public static Map<Class<?>, Annotation> fieldAnnotations(Class<?> clazz, String fieldName) { public static Map<Class<?>, Annotation> fieldAnnotations(Class<?> clazz, String fieldName) {


Field field = Cls.getField(clazz, fieldName); Field field = Cls.getField(clazz, fieldName);
Expand Down

0 comments on commit 3ab51a5

Please sign in to comment.