[Major] removed the need for a role PrivilegeAdmin - now use privileges

- this solves the situation where a user might be allowed to add a user
with a specific role, but not change a role and other such use cases

Now there are privileges for every use case with two new
PrivilegePolicies:
- RoleAccessPrivilege
- UserAccessPrivilege
both of these policies expect a ch.eitchnet.utils.collections.Tuple as
privilege value. The Tuple is a simple wrapper for two values: first and
second. Each privilege has its own requirement on the actual values

Special privilege actions:
- PrivilegeAction -> privilege vlaue: String
  - Persist (required Allow)
  - Reload (required Allow)
  - GetPolicies (required Allow)

Role specific privileges:
- PrivilegeGetRole -> privilege value: Tuple(null, newRole)
- PrivilegeAddRole -> privilege value: Tuple(null, newRole)
- PrivilegeRemoveRole -> privilege value: Tuple(null, newRole)
- PrivilegeModifyRole -> privilege value: Tuple(oldRole, newRole)

Use specific privileges:
- PrivilegeGetUser -> privilege value: Tuple(null, newUser)
- PrivilegeAddUser -> privilege value: Tuple(null, newUser)
- PrivilegeRemoveUser -> privilege value: Tuple(null, newUser)
- PrivilegeModifyUser -> privilege value: Tuple(oldUser, newUser)
  - NOTE: without modifying roles, only fields and properties!
- PrivilegeAddRoleToUser -> privilege value: Tuple(oldUser, roleName)
- PrivilegeRemoveRoleFromUser -> privilege value: Tuple(oldUser,
	roleName)
This commit is contained in:
Robert von Burg 2015-03-12 17:32:06 +01:00
parent a3d76d4cd8
commit fa40671b8c
14 changed files with 951 additions and 384 deletions

View File

@ -25,6 +25,8 @@
<Policies>
<Policy name="DefaultPrivilege" class="ch.eitchnet.privilege.policy.DefaultPrivilege" />
<Policy name="RoleAccessPrivilege" class="ch.eitchnet.privilege.policy.RoleAccessPrivilege" />
<Policy name="UserAccessPrivilege" class="ch.eitchnet.privilege.policy.UserAccessPrivilege" />
</Policies>
</Privilege>

View File

@ -43,14 +43,52 @@
<Roles>
<Role name="PrivilegeAdmin" />
<Role name="PrivilegeAdmin">
<Privilege name="PrivilegeAction" policy="DefaultPrivilege">
<Allow>Persist</Allow>
<Allow>Reload</Allow>
<Allow>GetPolicies</Allow>
</Privilege>
<Privilege name="PrivilegeGetRole" policy="RoleAccessPrivilege">
<AllAllowed>true</AllAllowed>
</Privilege>
<Privilege name="PrivilegeAddRole" policy="RoleAccessPrivilege">
<AllAllowed>true</AllAllowed>
</Privilege>
<Privilege name="PrivilegeRemoveRole" policy="RoleAccessPrivilege">
<AllAllowed>true</AllAllowed>
</Privilege>
<Privilege name="PrivilegeModifyRole" policy="RoleAccessPrivilege">
<AllAllowed>true</AllAllowed>
</Privilege>
<Privilege name="PrivilegeGetUser" policy="UserAccessPrivilege">
<AllAllowed>true</AllAllowed>
</Privilege>
<Privilege name="PrivilegeAddUser" policy="UserAccessPrivilege">
<AllAllowed>true</AllAllowed>
</Privilege>
<Privilege name="PrivilegeRemoveUser" policy="UserAccessPrivilege">
<AllAllowed>true</AllAllowed>
</Privilege>
<Privilege name="PrivilegeModifyUser" policy="UserAccessPrivilege">
<AllAllowed>true</AllAllowed>
</Privilege>
<Privilege name="PrivilegeAddRoleToUser" policy="UserAccessPrivilege">
<AllAllowed>true</AllAllowed>
</Privilege>
<Privilege name="PrivilegeRemoveRoleFromUser" policy="UserAccessPrivilege">
<AllAllowed>true</AllAllowed>
</Privilege>
</Role>
<Role name="AppUser">
<Privilege name="ch.eitchnet.privilege.test.model.TestRestrictable" policy="DefaultPrivilege">
<AllAllowed>true</AllAllowed>
</Privilege>
</Role>
<Role name="MyRole" />
<Role name="system_admin_privileges">

View File

@ -39,12 +39,14 @@ import ch.eitchnet.privilege.model.IPrivilege;
import ch.eitchnet.privilege.model.PrivilegeContext;
import ch.eitchnet.privilege.model.PrivilegeRep;
import ch.eitchnet.privilege.model.RoleRep;
import ch.eitchnet.privilege.model.SimpleRestrictable;
import ch.eitchnet.privilege.model.UserRep;
import ch.eitchnet.privilege.model.UserState;
import ch.eitchnet.privilege.model.internal.PrivilegeImpl;
import ch.eitchnet.privilege.model.internal.Role;
import ch.eitchnet.privilege.model.internal.User;
import ch.eitchnet.privilege.policy.PrivilegePolicy;
import ch.eitchnet.utils.collections.Tuple;
import ch.eitchnet.utils.helper.StringHelper;
/**
@ -67,10 +69,7 @@ import ch.eitchnet.utils.helper.StringHelper;
*/
public class DefaultPrivilegeHandler implements PrivilegeHandler {
/**
* configuration parameter to define automatic persisting on password change
*/
private static final String PARAM_AUTO_PERSIST_ON_USER_CHANGES_DATA = "autoPersistOnUserChangesData"; //$NON-NLS-1$
///
/**
* slf4j logger
@ -115,32 +114,40 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
@Override
public RoleRep getRole(Certificate certificate, String roleName) {
// validate who is doing this
assertIsPrivilegeAdmin(certificate);
// validate user actually has this type of privilege
PrivilegeContext prvCtx = getPrivilegeContext(certificate);
prvCtx.assertHasPrivilege(PRIVILEGE_GET_ROLE);
Role role = this.persistenceHandler.getRole(roleName);
if (role == null)
return null;
prvCtx.validateAction(new SimpleRestrictable(PRIVILEGE_GET_ROLE, new Tuple(null, role)));
return role.asRoleRep();
}
@Override
public UserRep getUser(Certificate certificate, String username) {
// validate who is doing this
assertIsPrivilegeAdmin(certificate);
// validate user actually has this type of privilege
PrivilegeContext prvCtx = getPrivilegeContext(certificate);
prvCtx.assertHasPrivilege(PRIVILEGE_GET_USER);
User user = this.persistenceHandler.getUser(username);
if (user == null)
return null;
prvCtx.validateAction(new SimpleRestrictable(PRIVILEGE_GET_USER, new Tuple(null, user)));
return user.asUserRep();
}
@Override
public Map<String, String> getPolicyDefs(Certificate certificate) {
// validate who is doing this
assertIsPrivilegeAdmin(certificate);
// validate user actually has this type of privilege
PrivilegeContext prvCtx = getPrivilegeContext(certificate);
prvCtx.validateAction(new SimpleRestrictable(PRIVILEGE_ACTION, PRIVILEGE_ACTION_GET_POLICIES));
Map<String, String> policyDef = new HashMap<>(this.policyMap.size());
for (Entry<String, Class<PrivilegePolicy>> entry : this.policyMap.entrySet()) {
@ -149,33 +156,60 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
return policyDef;
}
@Override
public List<UserRep> getUsers(Certificate certificate) {
// validate who is doing this
assertIsPrivilegeAdmin(certificate);
Stream<User> usersStream = this.persistenceHandler.getAllUsers().stream();
List<UserRep> users = usersStream.map(u -> u.asUserRep()).collect(Collectors.toList());
return users;
}
@Override
public List<RoleRep> getRoles(Certificate certificate) {
// validate who is doing this
assertIsPrivilegeAdmin(certificate);
// validate user actually has this type of privilege
PrivilegeContext prvCtx = getPrivilegeContext(certificate);
prvCtx.assertHasPrivilege(PRIVILEGE_GET_ROLE);
Stream<Role> rolesStream = this.persistenceHandler.getAllRoles().stream();
// validate access to each role
// TODO throwing and catching exception ain't cool
rolesStream.filter(role -> {
try {
prvCtx.validateAction(new SimpleRestrictable(PRIVILEGE_GET_ROLE, new Tuple(null, role)));
return true;
} catch (AccessDeniedException e) {
return false;
}
});
List<RoleRep> roles = rolesStream.map(r -> r.asRoleRep()).collect(Collectors.toList());
return roles;
}
@Override
public List<UserRep> getUsers(Certificate certificate) {
// validate user actually has this type of privilege
PrivilegeContext prvCtx = getPrivilegeContext(certificate);
prvCtx.assertHasPrivilege(PRIVILEGE_GET_USER);
Stream<User> usersStream = this.persistenceHandler.getAllUsers().stream();
// validate access to each user
// TODO throwing and catching exception ain't cool
usersStream.filter(user -> {
try {
prvCtx.validateAction(new SimpleRestrictable(PRIVILEGE_GET_USER, new Tuple(null, user)));
return true;
} catch (AccessDeniedException e) {
return false;
}
});
List<UserRep> users = usersStream.map(u -> u.asUserRep()).collect(Collectors.toList());
return users;
}
@Override
public List<UserRep> queryUsers(Certificate certificate, UserRep selectorRep) {
// validate who is doing this
assertIsPrivilegeAdmin(certificate);
// validate user actually has this type of privilege
PrivilegeContext prvCtx = getPrivilegeContext(certificate);
prvCtx.assertHasPrivilege(PRIVILEGE_GET_USER);
String selUserId = selectorRep.getUserId();
String selUsername = selectorRep.getUsername();
@ -190,6 +224,13 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
List<User> allUsers = this.persistenceHandler.getAllUsers();
for (User user : allUsers) {
// TODO throwing and catching exception ain't cool
try {
prvCtx.validateAction(new SimpleRestrictable(PRIVILEGE_GET_USER, new Tuple(null, user)));
} catch (AccessDeniedException e) {
continue;
}
// selections
boolean userIdSelected;
boolean usernameSelected;
@ -319,8 +360,9 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
public UserRep addUser(Certificate certificate, UserRep userRep, byte[] password) {
try {
// validate who is doing this
assertIsPrivilegeAdmin(certificate);
// validate user actually has this type of privilege
PrivilegeContext prvCtx = getPrivilegeContext(certificate);
prvCtx.assertHasPrivilege(PRIVILEGE_ADD_USER);
// make sure userId is not set
if (StringHelper.isNotEmpty(userRep.getUserId())) {
@ -353,12 +395,15 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
}
// create new user
User user = createUser(userRep, passwordHash);
User newUser = createUser(userRep, passwordHash);
// validate this user may create such a user
prvCtx.validateAction(new SimpleRestrictable(PRIVILEGE_ADD_USER, new Tuple(null, newUser)));
// delegate to persistence handler
this.persistenceHandler.addUser(user);
this.persistenceHandler.addUser(newUser);
return user.asUserRep();
return newUser.asUserRep();
} finally {
clearPassword(password);
@ -369,8 +414,9 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
public UserRep replaceUser(Certificate certificate, UserRep userRep, byte[] password) {
try {
// validate who is doing this
assertIsPrivilegeAdmin(certificate);
// validate user actually has this type of privilege
PrivilegeContext prvCtx = getPrivilegeContext(certificate);
prvCtx.assertHasPrivilege(PRIVILEGE_MODIFY_USER);
// first validate user
userRep.validate();
@ -378,16 +424,16 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
validateRolesExist(userRep);
// validate user exists
User user = this.persistenceHandler.getUser(userRep.getUsername());
if (user == null) {
User existingUser = this.persistenceHandler.getUser(userRep.getUsername());
if (existingUser == null) {
String msg = "User {0} can not be replaced as it does not exist!";
throw new PrivilegeException(MessageFormat.format(msg, userRep.getUsername()));
}
// validate same userId
if (!user.getUserId().equals(userRep.getUserId())) {
if (!existingUser.getUserId().equals(userRep.getUserId())) {
String msg = "UserId of existing user {0} does not match userRep {1}";
msg = MessageFormat.format(msg, user.getUserId(), userRep.getUserId());
msg = MessageFormat.format(msg, existingUser.getUserId(), userRep.getUserId());
throw new PrivilegeException(MessageFormat.format(msg, userRep.getUsername()));
}
@ -401,12 +447,15 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
passwordHash = this.encryptionHandler.convertToHash(password);
}
user = createUser(userRep, passwordHash);
User newUser = createUser(userRep, passwordHash);
// validate this user may modify this user
prvCtx.validateAction(new SimpleRestrictable(PRIVILEGE_MODIFY_USER, new Tuple(existingUser, newUser)));
// delegate to persistence handler
this.persistenceHandler.replaceUser(user);
this.persistenceHandler.replaceUser(newUser);
return user.asUserRep();
return newUser.asUserRep();
} finally {
clearPassword(password);
@ -435,12 +484,13 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
public UserRep updateUser(Certificate certificate, UserRep userRep) throws AccessDeniedException,
PrivilegeException {
// validate who is doing this
assertIsPrivilegeAdmin(certificate);
// validate user actually has this type of privilege
PrivilegeContext prvCtx = getPrivilegeContext(certificate);
prvCtx.assertHasPrivilege(PRIVILEGE_MODIFY_USER);
// get existing user
User user = this.persistenceHandler.getUser(userRep.getUsername());
if (user == null) {
User existingUser = this.persistenceHandler.getUser(userRep.getUsername());
if (existingUser == null) {
throw new PrivilegeException(MessageFormat.format("User {0} does not exist!", userRep.getUsername())); //$NON-NLS-1$
}
@ -452,15 +502,15 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
"All updateable fields are empty for update of user {0}", userRep.getUsername())); //$NON-NLS-1$
}
String userId = user.getUserId();
String username = user.getUsername();
String password = user.getPassword();
String firstname = user.getFirstname();
String lastname = user.getLastname();
UserState userState = user.getUserState();
Set<String> roles = user.getRoles();
Locale locale = user.getLocale();
Map<String, String> propertyMap = user.getProperties();
String userId = existingUser.getUserId();
String username = existingUser.getUsername();
String password = existingUser.getPassword();
String firstname = existingUser.getFirstname();
String lastname = existingUser.getLastname();
UserState userState = existingUser.getUserState();
Set<String> roles = existingUser.getRoles();
Locale locale = existingUser.getLocale();
Map<String, String> propertyMap = existingUser.getProperties();
// get updated fields
if (StringHelper.isNotEmpty(userRep.getFirstname()))
@ -473,134 +523,64 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
propertyMap = userRep.getPropertyMap();
// create new user
user = new User(userId, username, password, firstname, lastname, userState, roles, locale, propertyMap);
User newUser = new User(userId, username, password, firstname, lastname, userState, roles, locale, propertyMap);
// validate this user may modify this user
prvCtx.validateAction(new SimpleRestrictable(PRIVILEGE_MODIFY_USER, new Tuple(existingUser, newUser)));
// delegate to persistence handler
this.persistenceHandler.replaceUser(user);
this.persistenceHandler.replaceUser(newUser);
return user.asUserRep();
return newUser.asUserRep();
}
@Override
public RoleRep addRole(Certificate certificate, RoleRep roleRep) {
public UserRep removeUser(Certificate certificate, String username) {
// validate who is doing this
assertIsPrivilegeAdmin(certificate);
// validate user actually has this type of privilege
PrivilegeContext prvCtx = getPrivilegeContext(certificate);
prvCtx.assertHasPrivilege(PRIVILEGE_REMOVE_USER);
// first validate role
roleRep.validate();
// validate role does not exist
if (this.persistenceHandler.getRole(roleRep.getName()) != null) {
String msg = MessageFormat.format("Can not add role {0} as it already exists!", roleRep.getName());
throw new PrivilegeException(msg);
// validate user exists
User existingUser = this.persistenceHandler.getUser(username);
if (existingUser == null) {
String msg = "Can not remove User {0} because user does not exist!";
throw new PrivilegeException(MessageFormat.format(msg, username));
}
// create new role from RoleRep
Role role = new Role(roleRep);
// validate this user may remove this user
prvCtx.validateAction(new SimpleRestrictable(PRIVILEGE_REMOVE_USER, new Tuple(null, existingUser)));
// validate policy if not null
validatePolicies(role);
// delegate user removal to persistence handler
this.persistenceHandler.removeUser(username);
// delegate to persistence handler
this.persistenceHandler.addRole(role);
return role.asRoleRep();
}
@Override
public RoleRep replaceRole(Certificate certificate, RoleRep roleRep) {
// validate who is doing this
assertIsPrivilegeAdmin(certificate);
// first validate role
roleRep.validate();
// validate role does exist
if (this.persistenceHandler.getRole(roleRep.getName()) == null) {
String msg = MessageFormat.format("Can not replace role {0} as it does not exist!", roleRep.getName());
throw new PrivilegeException(msg);
}
// create new role from RoleRep
Role role = new Role(roleRep);
// validate policy if not null
validatePolicies(role);
// delegate to persistence handler
this.persistenceHandler.replaceRole(role);
return role.asRoleRep();
}
@Override
public RoleRep addOrReplacePrivilegeOnRole(Certificate certificate, String roleName, PrivilegeRep privilegeRep) {
// validate who is doing this
assertIsPrivilegeAdmin(certificate);
// validate PrivilegeRep
privilegeRep.validate();
// get role
Role role = this.persistenceHandler.getRole(roleName);
if (role == null) {
String msg = MessageFormat.format("Role {0} does not exist!", roleName); //$NON-NLS-1$
throw new PrivilegeException(msg);
}
// validate that policy exists if needed
String policy = privilegeRep.getPolicy();
if (policy != null && !this.policyMap.containsKey(policy)) {
String msg = "Policy {0} for Privilege {1} does not exist"; //$NON-NLS-1$
msg = MessageFormat.format(msg, policy, privilegeRep.getName());
throw new PrivilegeException(msg);
}
// create new role with the additional privilege
IPrivilege newPrivilege = new PrivilegeImpl(privilegeRep);
// copy existing privileges
Set<String> existingPrivilegeNames = role.getPrivilegeNames();
Map<String, IPrivilege> privilegeMap = new HashMap<>(existingPrivilegeNames.size() + 1);
for (String name : existingPrivilegeNames) {
IPrivilege privilege = role.getPrivilege(name);
privilegeMap.put(name, privilege);
}
// add new one
privilegeMap.put(newPrivilege.getName(), newPrivilege);
Role newRole = new Role(role.getName(), privilegeMap);
// delegate role replacement to persistence handler
this.persistenceHandler.replaceRole(newRole);
return newRole.asRoleRep();
return existingUser.asUserRep();
}
@Override
public UserRep addRoleToUser(Certificate certificate, String username, String roleName) {
// validate who is doing this
assertIsPrivilegeAdmin(certificate);
// validate user actually has this type of privilege
PrivilegeContext prvCtx = getPrivilegeContext(certificate);
prvCtx.assertHasPrivilege(PRIVILEGE_ADD_ROLE_TO_USER);
// get user
User user = this.persistenceHandler.getUser(username);
if (user == null) {
User existingUser = this.persistenceHandler.getUser(username);
if (existingUser == null) {
throw new PrivilegeException(MessageFormat.format("User {0} does not exist!", username)); //$NON-NLS-1$
}
// validate that this user may add this role to this user
prvCtx.validateAction(new SimpleRestrictable(PRIVILEGE_ADD_ROLE_TO_USER, new Tuple(existingUser, roleName)));
// check that user not already has role
Set<String> currentRoles = user.getRoles();
Set<String> currentRoles = existingUser.getRoles();
if (currentRoles.contains(roleName)) {
String msg = MessageFormat.format("User {0} already has role {1}", username, roleName); //$NON-NLS-1$
throw new PrivilegeException(msg);
}
// validate that role exists
// validate that the role exists
if (this.persistenceHandler.getRole(roleName) == null) {
String msg = MessageFormat.format("Role {0} does not exist!", roleName); //$NON-NLS-1$
throw new PrivilegeException(msg);
@ -610,8 +590,9 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
Set<String> newRoles = new HashSet<>(currentRoles);
newRoles.add(roleName);
User newUser = new User(user.getUserId(), user.getUsername(), user.getPassword(), user.getFirstname(),
user.getLastname(), user.getUserState(), newRoles, user.getLocale(), user.getProperties());
User newUser = new User(existingUser.getUserId(), existingUser.getUsername(), existingUser.getPassword(),
existingUser.getFirstname(), existingUser.getLastname(), existingUser.getUserState(), newRoles,
existingUser.getLocale(), existingUser.getProperties());
// delegate user replacement to persistence handler
this.persistenceHandler.replaceUser(newUser);
@ -619,94 +600,35 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
return newUser.asUserRep();
}
@Override
public RoleRep removePrivilegeFromRole(Certificate certificate, String roleName, String privilegeName) {
// validate who is doing this
assertIsPrivilegeAdmin(certificate);
// get role
Role role = this.persistenceHandler.getRole(roleName);
if (role == null) {
throw new PrivilegeException(MessageFormat.format("Role {0} does not exist!", roleName)); //$NON-NLS-1$
}
// ignore if role does not have privilege
if (!role.hasPrivilege(privilegeName)) {
String msg = MessageFormat.format("Role {0} does not have Privilege {1}", roleName, privilegeName); //$NON-NLS-1$
throw new PrivilegeException(msg);
}
// create new set of privileges with out the to removed privilege
Set<String> privilegeNames = role.getPrivilegeNames();
Map<String, IPrivilege> newPrivileges = new HashMap<String, IPrivilege>(privilegeNames.size() - 1);
for (String name : privilegeNames) {
IPrivilege privilege = role.getPrivilege(name);
if (!privilege.getName().equals(privilegeName))
newPrivileges.put(privilege.getName(), privilege);
}
// create new role
Role newRole = new Role(role.getName(), newPrivileges);
// delegate user replacement to persistence handler
this.persistenceHandler.replaceRole(newRole);
return newRole.asRoleRep();
}
@Override
public RoleRep removeRole(Certificate certificate, String roleName) {
// validate who is doing this
assertIsPrivilegeAdmin(certificate);
// validate no user is using this role
Set<String> roles = new HashSet<>(Arrays.asList(roleName));
UserRep selector = new UserRep(null, null, null, null, null, roles, null, null);
List<UserRep> usersWithRole = queryUsers(certificate, selector);
if (!usersWithRole.isEmpty()) {
String usersS = usersWithRole.stream().map(UserRep::getUsername).collect(Collectors.joining(", "));
String msg = "The role {0} can not be removed as the following {1} user have the role assigned: {2}";
msg = MessageFormat.format(msg, roleName, usersWithRole.size(), usersS);
throw new PrivilegeException(msg);
}
// delegate role removal to persistence handler
Role removedRole = this.persistenceHandler.removeRole(roleName);
if (removedRole == null) {
String msg = "Can not remove Role {0} because role does not exist!";
throw new PrivilegeException(MessageFormat.format(msg, roleName));
}
// return role rep if it was removed
return removedRole.asRoleRep();
}
@Override
public UserRep removeRoleFromUser(Certificate certificate, String username, String roleName) {
// validate who is doing this
assertIsPrivilegeAdmin(certificate);
// validate user actually has this type of privilege
PrivilegeContext prvCtx = getPrivilegeContext(certificate);
prvCtx.assertHasPrivilege(PRIVILEGE_REMOVE_ROLE_FROM_USER);
// get User
User user = this.persistenceHandler.getUser(username);
if (user == null) {
User existingUser = this.persistenceHandler.getUser(username);
if (existingUser == null) {
throw new PrivilegeException(MessageFormat.format("User {0} does not exist!", username)); //$NON-NLS-1$
}
// validate that this user may remove this role from this user
prvCtx.validateAction(new SimpleRestrictable(PRIVILEGE_REMOVE_ROLE_FROM_USER, new Tuple(existingUser, roleName)));
// ignore if user does not have role
Set<String> currentRoles = user.getRoles();
Set<String> currentRoles = existingUser.getRoles();
if (!currentRoles.contains(roleName)) {
String msg = MessageFormat.format("User {0} does not have role {1}", user.getUsername(), roleName); //$NON-NLS-1$
String msg = MessageFormat.format("User {0} does not have role {1}", existingUser.getUsername(), roleName); //$NON-NLS-1$
throw new PrivilegeException(msg);
}
// create new user
Set<String> newRoles = new HashSet<String>(currentRoles);
newRoles.remove(roleName);
User newUser = new User(user.getUserId(), user.getUsername(), user.getPassword(), user.getFirstname(),
user.getLastname(), user.getUserState(), newRoles, user.getLocale(), user.getProperties());
User newUser = new User(existingUser.getUserId(), existingUser.getUsername(), existingUser.getPassword(),
existingUser.getFirstname(), existingUser.getLastname(), existingUser.getUserState(), newRoles,
existingUser.getLocale(), existingUser.getProperties());
// delegate user replacement to persistence handler
this.persistenceHandler.replaceUser(newUser);
@ -714,23 +636,6 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
return newUser.asUserRep();
}
@Override
public UserRep removeUser(Certificate certificate, String username) {
// validate who is doing this
assertIsPrivilegeAdmin(certificate);
// delegate user removal to persistence handler
User removedUser = this.persistenceHandler.removeUser(username);
if (removedUser == null) {
String msg = "Can not remove User {0} because user does not exist!";
throw new PrivilegeException(MessageFormat.format(msg, username));
}
// return user rep if it was removed
return removedUser.asUserRep();
}
@Override
public UserRep setUserLocale(Certificate certificate, String username, Locale locale) {
@ -742,19 +647,27 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
} else {
// otherwise validate the the certificate is for a privilege admin
assertIsPrivilegeAdmin(certificate);
// validate user actually has this type of privilege
PrivilegeContext prvCtx = getPrivilegeContext(certificate);
prvCtx.assertHasPrivilege(PRIVILEGE_MODIFY_USER);
}
// get User
User user = this.persistenceHandler.getUser(username);
if (user == null) {
User existingUser = this.persistenceHandler.getUser(username);
if (existingUser == null) {
throw new PrivilegeException(MessageFormat.format("User {0} does not exist!", username)); //$NON-NLS-1$
}
// create new user
User newUser = new User(user.getUserId(), user.getUsername(), user.getPassword(), user.getFirstname(),
user.getLastname(), user.getUserState(), user.getRoles(), locale, user.getProperties());
User newUser = new User(existingUser.getUserId(), existingUser.getUsername(), existingUser.getPassword(),
existingUser.getFirstname(), existingUser.getLastname(), existingUser.getUserState(),
existingUser.getRoles(), locale, existingUser.getProperties());
// if the user is not setting their own locale, then make sure this user may set this user's locale
if (!certificate.getUsername().equals(username)) {
PrivilegeContext prvCtx = getPrivilegeContext(certificate);
prvCtx.validateAction(new SimpleRestrictable(PRIVILEGE_MODIFY_USER, new Tuple(existingUser, newUser)));
}
// delegate user replacement to persistence handler
this.persistenceHandler.replaceUser(newUser);
@ -779,13 +692,14 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
} else {
// otherwise validate the the certificate is for a privilege admin
assertIsPrivilegeAdmin(certificate);
// validate user actually has this type of privilege
PrivilegeContext prvCtx = getPrivilegeContext(certificate);
prvCtx.assertHasPrivilege(PRIVILEGE_MODIFY_USER);
}
// get User
User user = this.persistenceHandler.getUser(username);
if (user == null) {
User existingUser = this.persistenceHandler.getUser(username);
if (existingUser == null) {
throw new PrivilegeException(MessageFormat.format("User {0} does not exist!", username)); //$NON-NLS-1$
}
@ -800,8 +714,15 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
}
// create new user
User newUser = new User(user.getUserId(), user.getUsername(), passwordHash, user.getFirstname(),
user.getLastname(), user.getUserState(), user.getRoles(), user.getLocale(), user.getProperties());
User newUser = new User(existingUser.getUserId(), existingUser.getUsername(), passwordHash,
existingUser.getFirstname(), existingUser.getLastname(), existingUser.getUserState(),
existingUser.getRoles(), existingUser.getLocale(), existingUser.getProperties());
// if the user is not setting their own password, then make sure this user may set this user's password
if (!certificate.getUsername().equals(username)) {
PrivilegeContext prvCtx = getPrivilegeContext(certificate);
prvCtx.validateAction(new SimpleRestrictable(PRIVILEGE_MODIFY_USER, new Tuple(existingUser, newUser)));
}
// delegate user replacement to persistence handler
this.persistenceHandler.replaceUser(newUser);
@ -819,18 +740,23 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
@Override
public UserRep setUserState(Certificate certificate, String username, UserState state) {
// validate who is doing this
assertIsPrivilegeAdmin(certificate);
// validate user actually has this type of privilege
PrivilegeContext prvCtx = getPrivilegeContext(certificate);
prvCtx.assertHasPrivilege(PRIVILEGE_MODIFY_USER);
// get User
User user = this.persistenceHandler.getUser(username);
if (user == null) {
User existingUser = this.persistenceHandler.getUser(username);
if (existingUser == null) {
throw new PrivilegeException(MessageFormat.format("User {0} does not exist!", username)); //$NON-NLS-1$
}
// create new user
User newUser = new User(user.getUserId(), user.getUsername(), user.getPassword(), user.getFirstname(),
user.getLastname(), state, user.getRoles(), user.getLocale(), user.getProperties());
User newUser = new User(existingUser.getUserId(), existingUser.getUsername(), existingUser.getPassword(),
existingUser.getFirstname(), existingUser.getLastname(), state, existingUser.getRoles(),
existingUser.getLocale(), existingUser.getProperties());
// validate that this user may modify this user's state
prvCtx.validateAction(new SimpleRestrictable(PRIVILEGE_MODIFY_USER, new Tuple(existingUser, newUser)));
// delegate user replacement to persistence handler
this.persistenceHandler.replaceUser(newUser);
@ -838,6 +764,194 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
return newUser.asUserRep();
}
@Override
public RoleRep addRole(Certificate certificate, RoleRep roleRep) {
// validate user actually has this type of privilege
PrivilegeContext prvCtx = getPrivilegeContext(certificate);
prvCtx.assertHasPrivilege(PRIVILEGE_ADD_ROLE);
// first validate role
roleRep.validate();
// validate role does not exist
if (this.persistenceHandler.getRole(roleRep.getName()) != null) {
String msg = MessageFormat.format("Can not add role {0} as it already exists!", roleRep.getName());
throw new PrivilegeException(msg);
}
// create new role from RoleRep
Role newRole = new Role(roleRep);
// validate that this user may add this new role
prvCtx.validateAction(new SimpleRestrictable(PRIVILEGE_ADD_ROLE, new Tuple(null, newRole)));
// validate policy if not null
validatePolicies(newRole);
// delegate to persistence handler
this.persistenceHandler.addRole(newRole);
return newRole.asRoleRep();
}
@Override
public RoleRep replaceRole(Certificate certificate, RoleRep roleRep) {
// validate user actually has this type of privilege
PrivilegeContext prvCtx = getPrivilegeContext(certificate);
prvCtx.assertHasPrivilege(PRIVILEGE_MODIFY_ROLE);
// first validate role
roleRep.validate();
// validate role does exist
Role existingRole = this.persistenceHandler.getRole(roleRep.getName());
if (existingRole == null) {
String msg = MessageFormat.format("Can not replace role {0} as it does not exist!", roleRep.getName());
throw new PrivilegeException(msg);
}
// create new role from RoleRep
Role newRole = new Role(roleRep);
// validate that this user may modify this role
prvCtx.validateAction(new SimpleRestrictable(PRIVILEGE_MODIFY_ROLE, new Tuple(existingRole, newRole)));
// validate policy if not null
validatePolicies(newRole);
// delegate to persistence handler
this.persistenceHandler.replaceRole(newRole);
return newRole.asRoleRep();
}
@Override
public RoleRep removeRole(Certificate certificate, String roleName) {
// validate user actually has this type of privilege
PrivilegeContext prvCtx = getPrivilegeContext(certificate);
prvCtx.assertHasPrivilege(PRIVILEGE_REMOVE_ROLE);
// validate no user is using this role
Set<String> roles = new HashSet<>(Arrays.asList(roleName));
UserRep selector = new UserRep(null, null, null, null, null, roles, null, null);
List<UserRep> usersWithRole = queryUsers(certificate, selector);
if (!usersWithRole.isEmpty()) {
String usersS = usersWithRole.stream().map(UserRep::getUsername).collect(Collectors.joining(", "));
String msg = "The role {0} can not be removed as the following {1} user have the role assigned: {2}";
msg = MessageFormat.format(msg, roleName, usersWithRole.size(), usersS);
throw new PrivilegeException(msg);
}
// validate role exists
Role existingRole = this.persistenceHandler.getRole(roleName);
if (existingRole == null) {
String msg = "Can not remove Role {0} because role does not exist!";
throw new PrivilegeException(MessageFormat.format(msg, roleName));
}
// validate that this user may remove this role
prvCtx.validateAction(new SimpleRestrictable(PRIVILEGE_REMOVE_ROLE, new Tuple(null, existingRole)));
// delegate role removal to persistence handler
this.persistenceHandler.removeRole(roleName);
return existingRole.asRoleRep();
}
@Override
public RoleRep addOrReplacePrivilegeOnRole(Certificate certificate, String roleName, PrivilegeRep privilegeRep) {
// validate user actually has this type of privilege
PrivilegeContext prvCtx = getPrivilegeContext(certificate);
prvCtx.assertHasPrivilege(PRIVILEGE_MODIFY_ROLE);
// validate PrivilegeRep
privilegeRep.validate();
// get role
Role existingRole = this.persistenceHandler.getRole(roleName);
if (existingRole == null) {
String msg = MessageFormat.format("Role {0} does not exist!", roleName); //$NON-NLS-1$
throw new PrivilegeException(msg);
}
// validate that policy exists if needed
String policy = privilegeRep.getPolicy();
if (policy != null && !this.policyMap.containsKey(policy)) {
String msg = "Policy {0} for Privilege {1} does not exist"; //$NON-NLS-1$
msg = MessageFormat.format(msg, policy, privilegeRep.getName());
throw new PrivilegeException(msg);
}
// create new role with the additional privilege
IPrivilege newPrivilege = new PrivilegeImpl(privilegeRep);
// copy existing privileges
Set<String> existingPrivilegeNames = existingRole.getPrivilegeNames();
Map<String, IPrivilege> privilegeMap = new HashMap<>(existingPrivilegeNames.size() + 1);
for (String name : existingPrivilegeNames) {
IPrivilege privilege = existingRole.getPrivilege(name);
privilegeMap.put(name, privilege);
}
// add new one
privilegeMap.put(newPrivilege.getName(), newPrivilege);
// create new role
Role newRole = new Role(existingRole.getName(), privilegeMap);
// validate that this user may modify this role
prvCtx.validateAction(new SimpleRestrictable(PRIVILEGE_MODIFY_ROLE, new Tuple(existingRole, newRole)));
// delegate role replacement to persistence handler
this.persistenceHandler.replaceRole(newRole);
return newRole.asRoleRep();
}
@Override
public RoleRep removePrivilegeFromRole(Certificate certificate, String roleName, String privilegeName) {
// validate user actually has this type of privilege
PrivilegeContext prvCtx = getPrivilegeContext(certificate);
prvCtx.assertHasPrivilege(PRIVILEGE_MODIFY_ROLE);
// get role
Role existingRole = this.persistenceHandler.getRole(roleName);
if (existingRole == null) {
throw new PrivilegeException(MessageFormat.format("Role {0} does not exist!", roleName)); //$NON-NLS-1$
}
// ignore if role does not have privilege
if (!existingRole.hasPrivilege(privilegeName)) {
String msg = MessageFormat.format("Role {0} does not have Privilege {1}", roleName, privilegeName); //$NON-NLS-1$
throw new PrivilegeException(msg);
}
// create new set of privileges with out the to removed privilege
Set<String> privilegeNames = existingRole.getPrivilegeNames();
Map<String, IPrivilege> newPrivileges = new HashMap<String, IPrivilege>(privilegeNames.size() - 1);
for (String name : privilegeNames) {
IPrivilege privilege = existingRole.getPrivilege(name);
if (!privilege.getName().equals(privilegeName))
newPrivileges.put(privilege.getName(), privilege);
}
// create new role
Role newRole = new Role(existingRole.getName(), newPrivileges);
// validate that this user may modify this role
prvCtx.validateAction(new SimpleRestrictable(PRIVILEGE_MODIFY_ROLE, new Tuple(existingRole, newRole)));
// delegate user replacement to persistence handler
this.persistenceHandler.replaceRole(newRole);
return newRole.asRoleRep();
}
@Override
public Certificate authenticate(String username, byte[] password) {
@ -1068,28 +1182,6 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
return this.privilegeContextMap.get(certificate.getSessionId());
}
@Override
public void assertIsPrivilegeAdmin(Certificate certificate) throws PrivilegeException {
// validate certificate
isCertificateValid(certificate);
// get user object
User user = this.persistenceHandler.getUser(certificate.getUsername());
if (user == null) {
String msg = "Oh boy, how did this happen: No User in user map although the certificate is valid! Certificate: {0}"; //$NON-NLS-1$
msg = MessageFormat.format(msg, certificate);
throw new PrivilegeException(msg);
}
// validate user has PrivilegeAdmin role
if (!user.hasRole(PrivilegeHandler.PRIVILEGE_ADMIN_ROLE)) {
String msg = "User does not have {0} role! Certificate: {1}"; //$NON-NLS-1$
msg = MessageFormat.format(msg, PrivilegeHandler.PRIVILEGE_ADMIN_ROLE, certificate);
throw new AccessDeniedException(msg);
}
}
/**
* This simple implementation validates that the password is not null, and that the password string is not empty
*
@ -1111,11 +1203,22 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
public boolean persist(Certificate certificate) {
// validate who is doing this
assertIsPrivilegeAdmin(certificate);
PrivilegeContext prvCtx = getPrivilegeContext(certificate);
prvCtx.validateAction(new SimpleRestrictable(PRIVILEGE_ACTION, PRIVILEGE_ACTION_PERSIST));
return this.persistenceHandler.persist();
}
@Override
public boolean reload(Certificate certificate) {
// validate who is doing this
PrivilegeContext prvCtx = getPrivilegeContext(certificate);
prvCtx.validateAction(new SimpleRestrictable(PRIVILEGE_ACTION, PRIVILEGE_ACTION_RELOAD));
return this.persistenceHandler.reload();
}
/**
* Initializes the concrete {@link EncryptionHandler}. The passed parameter map contains any configuration this
* {@link PrivilegeHandler} might need. This method may only be called once and this must be enforced by the

View File

@ -41,10 +41,85 @@ import ch.eitchnet.privilege.policy.PrivilegePolicy;
*/
public interface PrivilegeHandler {
///
/**
* PRIVILEGE_ADMIN_ROLE = PrivilegeAdmin: This is the role users must have, if they are allowed to modify objects
* Privilege "PrivilegeAction" which is used for privileges which are not further categorized e.g. s
* {@link #PRIVILEGE_ACTION_PERSIST} and {@link #PRIVILEGE_ACTION_GET_POLICIES}
*/
public static final String PRIVILEGE_ADMIN_ROLE = "PrivilegeAdmin"; //$NON-NLS-1$
public static final String PRIVILEGE_ACTION = "PrivilegeAction";
/**
* For Privilege "PrivilegeAction" value required to be able to persist changes if not exempted by auto persist or
* <code>allAllowed</code>
*/
public static final String PRIVILEGE_ACTION_PERSIST = "Persist";
/**
* For Privilege "PrivilegeAction" value required to be able to reload changes if not exempted by
* <code>allAllowed</code>
*/
public static final String PRIVILEGE_ACTION_RELOAD = "Reload";
/**
* For Privilege "PrivilegeAction" value required to get currently configured policies if not
* <code>allAllowed</code>
*/
public static final String PRIVILEGE_ACTION_GET_POLICIES = "GetPolicies";
///
/**
* Privilege "PrivilegeGetRole" which is used to validate that a user can get a specific role
*/
public static final String PRIVILEGE_GET_ROLE = "PrivilegeGetRole";
/**
* Privilege "PrivilegeAddRole" which is used to validate that a user can add a specific role
*/
public static final String PRIVILEGE_ADD_ROLE = "PrivilegeAddRole";
/**
* Privilege "PrivilegeRemoveRole" which is used to validate that a user can remove a specific role
*/
public static final String PRIVILEGE_REMOVE_ROLE = "PrivilegeRemoveRole";
/**
* Privilege "PrivilegeModifyRole" which is used to validate that a user can modify a specific role. <b>Note:</b>
* This includes modifying of the privileges on the role
*/
public static final String PRIVILEGE_MODIFY_ROLE = "PrivilegeModifyRole";
///
/**
* Privilege "PrivilegeGetUser" which is used to validate that a user can get a specific user
*/
public static final String PRIVILEGE_GET_USER = "PrivilegeGetUser";
/**
* Privilege "PrivilegeAddUser" which is used to validate that a user can add a specific user
*/
public static final String PRIVILEGE_ADD_USER = "PrivilegeAddUser";
/**
* Privilege "PrivilegeRemoveUser" which is used to validate that a user can remove a specific user
*/
public static final String PRIVILEGE_REMOVE_USER = "PrivilegeRemoveUser";
/**
* Privilege "PrivilegeModifyUser" which is used to validate that a user can modify a specific user
*/
public static final String PRIVILEGE_MODIFY_USER = "PrivilegeModifyUser";
/**
* Privilege "PrivilegeAddRoleToUser" which is used to validate that a user can add a specific role to a specific
* user
*/
public static final String PRIVILEGE_ADD_ROLE_TO_USER = "PrivilegeAddRoleToUser";
/**
* Privilege "PrivilegeRemoveRoleFromUser" which is used to validate that a user can remove a specific role from a
* specific user
*/
public static final String PRIVILEGE_REMOVE_ROLE_FROM_USER = "PrivilegeRemoveRoleFromUser";
///
/**
* configuration parameter to define automatic persisting on password change
*/
public static final String PARAM_AUTO_PERSIST_ON_USER_CHANGES_DATA = "autoPersistOnUserChangesData"; //$NON-NLS-1$
/**
* Returns a {@link UserRep} for the given username
@ -469,28 +544,6 @@ public interface PrivilegeHandler {
*/
public PrivilegeContext getPrivilegeContext(Certificate certificate) throws PrivilegeException;
/**
* <p>
* Validates if this {@link Certificate} is for a {@link ch.eitchnet.privilege.model.internal.User} with
* {@link Role} with name {@link PrivilegeHandler#PRIVILEGE_ADMIN_ROLE}
* </p>
*
* <p>
* In other words, this method checks if the given certificate is for a user who has the rights to change objects
* </p>
*
* <p>
* If the user is not the administrator, then a {@link ch.eitchnet.privilege.base.PrivilegeException} is thrown
* </p>
*
* @param certificate
* the {@link Certificate} for which the role should be validated against
*
* @throws AccessDeniedException
* if the user does not not have admin privileges
*/
public void assertIsPrivilegeAdmin(Certificate certificate) throws AccessDeniedException;
/**
* Validate that the given password meets certain requirements. What these requirements are is a decision made by
* the concrete implementation
@ -503,6 +556,23 @@ public interface PrivilegeHandler {
*/
public void validatePassword(byte[] password) throws PrivilegeException;
/**
* <p>
* Informs this {@link PersistenceHandler} to reload the data from the backend
* </p>
*
* <b>Note:</b> It depends on the underlying {@link PersistenceHandler} implementation if data really is read
*
* @param certificate
* the {@link Certificate} of the user which has the privilege to perform this action
*
* @return true if the reload was successful, false if something went wrong
*
* @throws AccessDeniedException
* if the users of the given certificate does not have the privilege to perform this action
*/
public boolean reload(Certificate certificate);
/**
* Persists any changes to the privilege data model. Changes are thus not persisted immediately, but must be
* actively performed

View File

@ -224,22 +224,6 @@ public class XmlPersistenceHandler implements PersistenceHandler {
}
}
// validate we have a user with PrivilegeAdmin access
boolean privilegeAdminExists = false;
for (String username : this.userMap.keySet()) {
User user = this.userMap.get(username);
if (user.hasRole(PrivilegeHandler.PRIVILEGE_ADMIN_ROLE)) {
privilegeAdminExists = true;
break;
}
}
if (!privilegeAdminExists) {
String msg = "No User with role ''{0}'' exists. Privilege modifications will not be possible!"; //$NON-NLS-1$
msg = MessageFormat.format(msg, PrivilegeHandler.PRIVILEGE_ADMIN_ROLE);
logger.warn(msg);
}
return true;
}

View File

@ -16,10 +16,8 @@
package ch.eitchnet.privilege.model;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -73,16 +71,26 @@ public class PrivilegeContext {
return this.privileges.keySet();
}
public void assertHasPrivilege(String privilegeName) {
if (!this.privileges.containsKey(privilegeName)) {
String msg = MessageFormat.format(PrivilegeMessages.getString("Privilege.noprivilege.user"), //$NON-NLS-1$
userRep.getUsername(), privilegeName);
throw new AccessDeniedException(msg);
}
}
public IPrivilege getPrivilege(String privilegeName) {
assertHasPrivilege(privilegeName);
return this.privileges.get(privilegeName);
}
public List<String> getFlatAllowList() {
List<String> allowList = new ArrayList<>();
for (IPrivilege privilege : this.privileges.values()) {
allowList.addAll(privilege.getAllowList());
public PrivilegePolicy getPolicy(String policyName) {
PrivilegePolicy policy = this.policies.get(policyName);
if (policy == null) {
String msg = "The PrivilegePolicy {0} does not exist on the PrivilegeContext!"; //$NON-NLS-1$
throw new PrivilegeException(MessageFormat.format(msg, policyName));
}
return allowList;
return policy;
}
//
@ -115,11 +123,7 @@ public class PrivilegeContext {
// get the policy referenced by the restrictable
String policyName = privilege.getPolicy();
PrivilegePolicy policy = this.policies.get(policyName);
if (policy == null) {
String msg = "The PrivilegePolicy {0} does not exist on the PrivilegeContext!"; //$NON-NLS-1$
throw new PrivilegeException(MessageFormat.format(msg, policyName));
}
PrivilegePolicy policy = getPolicy(policyName);
// delegate to the policy
policy.validateAction(this, privilege, restrictable);

View File

@ -0,0 +1,45 @@
/*
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ch.eitchnet.privilege.model;
import ch.eitchnet.utils.dbc.DBC;
public class SimpleRestrictable implements Restrictable {
private final String name;
private final Object value;
/**
* @param name
* @param value
*/
public SimpleRestrictable(String name, Object value) {
DBC.PRE.assertNotEmpty("name must not be emepty", name);
DBC.PRE.assertNotNull("value must not be null", value);
this.name = name;
this.value = value;
}
@Override
public String getPrivilegeName() {
return this.name;
}
@Override
public Object getPrivilegeValue() {
return this.value;
}
}

View File

@ -17,14 +17,12 @@ package ch.eitchnet.privilege.policy;
import java.text.MessageFormat;
import ch.eitchnet.privilege.base.AccessDeniedException;
import ch.eitchnet.privilege.base.PrivilegeException;
import ch.eitchnet.privilege.i18n.PrivilegeMessages;
import ch.eitchnet.privilege.model.IPrivilege;
import ch.eitchnet.privilege.model.PrivilegeContext;
import ch.eitchnet.privilege.model.Restrictable;
import ch.eitchnet.privilege.model.internal.Role;
import ch.eitchnet.utils.helper.StringHelper;
/**
* This is a simple implementation of {@link PrivilegePolicy} which uses the {@link Restrictable#getPrivilegeName()} to
@ -41,29 +39,7 @@ public class DefaultPrivilege implements PrivilegePolicy {
*/
@Override
public void validateAction(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable) {
if (privilege == null)
throw new PrivilegeException(PrivilegeMessages.getString("Privilege.privilegeNull")); //$NON-NLS-1$
if (restrictable == null)
throw new PrivilegeException(PrivilegeMessages.getString("Privilege.restrictableNull")); //$NON-NLS-1$
// get the PrivilegeName
String privilegeName = restrictable.getPrivilegeName();
if (StringHelper.isEmpty(privilegeName)) {
String msg = PrivilegeMessages.getString("Privilege.privilegeNameEmpty"); //$NON-NLS-1$
throw new PrivilegeException(MessageFormat.format(msg, restrictable));
}
// we want the privileges names to match
if (!privilege.getName().equals(privilegeName)) {
throw new PrivilegeException(MessageFormat.format(
PrivilegeMessages.getString("Privilege.illegalArgument.privilegeNameMismatch"), //$NON-NLS-1$
privilege.getName(), privilegeName));
}
// if everything is allowed, then no need to carry on
if (privilege.isAllAllowed())
return;
PrivilegePolicyHelper.preValidate(privilege, restrictable);
// get the value on which the action is to be performed
Object object = restrictable.getPrivilegeValue();
@ -76,23 +52,12 @@ public class DefaultPrivilege implements PrivilegePolicy {
throw new PrivilegeException(msg);
}
String privilegeValue = (String) object;
// first check values not allowed
if (privilege.isDenied(privilegeValue)) {
// then throw access denied
String msg = MessageFormat.format(PrivilegeMessages.getString("Privilege.accessdenied.noprivilege"), //$NON-NLS-1$
ctx.getUsername(), privilegeName, restrictable.getClass().getName());
throw new AccessDeniedException(msg);
}
// now check values allowed
if (privilege.isAllowed(privilegeValue))
// if everything is allowed, then no need to carry on
if (privilege.isAllAllowed())
return;
// default is not allowed
String msg = MessageFormat.format(PrivilegeMessages.getString("Privilege.accessdenied.noprivilege"), //$NON-NLS-1$
ctx.getUsername(), privilegeName, restrictable.getClass().getName());
throw new AccessDeniedException(msg);
String privilegeValue = (String) object;
PrivilegePolicyHelper.checkByAllowDenyValues(ctx, privilege, restrictable, privilegeValue);
}
}

View File

@ -0,0 +1,80 @@
/*
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ch.eitchnet.privilege.policy;
import java.text.MessageFormat;
import ch.eitchnet.privilege.base.AccessDeniedException;
import ch.eitchnet.privilege.base.PrivilegeException;
import ch.eitchnet.privilege.i18n.PrivilegeMessages;
import ch.eitchnet.privilege.model.IPrivilege;
import ch.eitchnet.privilege.model.PrivilegeContext;
import ch.eitchnet.privilege.model.Restrictable;
import ch.eitchnet.utils.helper.StringHelper;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*/
public class PrivilegePolicyHelper {
public static String preValidate(IPrivilege privilege, Restrictable restrictable) {
if (privilege == null)
throw new PrivilegeException(PrivilegeMessages.getString("Privilege.privilegeNull")); //$NON-NLS-1$
if (restrictable == null)
throw new PrivilegeException(PrivilegeMessages.getString("Privilege.restrictableNull")); //$NON-NLS-1$
// get the PrivilegeName
String privilegeName = restrictable.getPrivilegeName();
if (StringHelper.isEmpty(privilegeName)) {
String msg = PrivilegeMessages.getString("Privilege.privilegeNameEmpty"); //$NON-NLS-1$
throw new PrivilegeException(MessageFormat.format(msg, restrictable));
}
// we want the privileges names to match
if (!privilege.getName().equals(privilegeName)) {
throw new PrivilegeException(MessageFormat.format(
PrivilegeMessages.getString("Privilege.illegalArgument.privilegeNameMismatch"), //$NON-NLS-1$
privilege.getName(), privilegeName));
}
return privilegeName;
}
/**
* @param privilege
* @param privilegeValue
*/
public static void checkByAllowDenyValues(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable,
String privilegeValue) {
// first check values not allowed
if (privilege.isDenied(privilegeValue)) {
// then throw access denied
String msg = MessageFormat.format(PrivilegeMessages.getString("Privilege.accessdenied.noprivilege"), //$NON-NLS-1$
ctx.getUsername(), privilege.getName(), restrictable.getClass().getName());
throw new AccessDeniedException(msg);
}
// now check values allowed
if (privilege.isAllowed(privilegeValue))
return;
// default is not allowed
String msg = MessageFormat.format(PrivilegeMessages.getString("Privilege.accessdenied.noprivilege"), //$NON-NLS-1$
ctx.getUsername(), privilege.getName(), restrictable.getClass().getName());
throw new AccessDeniedException(msg);
}
}

View File

@ -0,0 +1,110 @@
/*
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ch.eitchnet.privilege.policy;
import java.text.MessageFormat;
import ch.eitchnet.privilege.base.PrivilegeException;
import ch.eitchnet.privilege.handler.PrivilegeHandler;
import ch.eitchnet.privilege.i18n.PrivilegeMessages;
import ch.eitchnet.privilege.model.IPrivilege;
import ch.eitchnet.privilege.model.PrivilegeContext;
import ch.eitchnet.privilege.model.Restrictable;
import ch.eitchnet.privilege.model.internal.Role;
import ch.eitchnet.utils.collections.Tuple;
import ch.eitchnet.utils.dbc.DBC;
/**
* TODO
*
* @author Robert von Burg <eitch@eitchnet.ch>
*/
public class RoleAccessPrivilege implements PrivilegePolicy {
@Override
public void validateAction(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable) {
String privilegeName = PrivilegePolicyHelper.preValidate(privilege, restrictable);
// get the value on which the action is to be performed
Object object = restrictable.getPrivilegeValue();
// RoleAccessPrivilege policy expects the privilege value to be a role
if (!(object instanceof Tuple)) {
String msg = Restrictable.class.getName()
+ PrivilegeMessages.getString("Privilege.illegalArgument.nontuple"); //$NON-NLS-1$
msg = MessageFormat.format(msg, restrictable.getClass().getSimpleName());
throw new PrivilegeException(msg);
}
// if everything is allowed, then no need to carry on
if (privilege.isAllAllowed())
return;
Tuple tuple = (Tuple) object;
// get role name as privilege value
Role oldRole = tuple.getFirst();
Role newRole = tuple.getSecond();
switch (privilegeName) {
case PrivilegeHandler.PRIVILEGE_GET_ROLE: {
DBC.INTERIM.assertNull("For " + privilegeName + " first must be null!", oldRole);
DBC.INTERIM.assertNotNull("For " + privilegeName + " second must not be null!", newRole);
String privilegeValue = newRole.getName();
PrivilegePolicyHelper.checkByAllowDenyValues(ctx, privilege, restrictable, privilegeValue);
break;
}
case PrivilegeHandler.PRIVILEGE_ADD_ROLE: {
DBC.INTERIM.assertNull("For " + privilegeName + " first must be null!", oldRole);
DBC.INTERIM.assertNotNull("For " + privilegeName + " second must not be null!", newRole);
String privilegeValue = newRole.getName();
PrivilegePolicyHelper.checkByAllowDenyValues(ctx, privilege, restrictable, privilegeValue);
break;
}
case PrivilegeHandler.PRIVILEGE_MODIFY_ROLE: {
DBC.INTERIM.assertNotNull("For " + privilegeName + " first must not be null!", oldRole);
DBC.INTERIM.assertNotNull("For " + privilegeName + " second must not be null!", newRole);
String privilegeValue = newRole.getName();
DBC.INTERIM.assertEquals("oldRole and newRole names must be the same", oldRole.getName(), privilegeValue);
PrivilegePolicyHelper.checkByAllowDenyValues(ctx, privilege, restrictable, privilegeValue);
break;
}
case PrivilegeHandler.PRIVILEGE_REMOVE_ROLE: {
DBC.INTERIM.assertNull("For " + privilegeName + " first must be null!", oldRole);
DBC.INTERIM.assertNotNull("For " + privilegeName + " second must not be null!", newRole);
String privilegeValue = newRole.getName();
PrivilegePolicyHelper.checkByAllowDenyValues(ctx, privilege, restrictable, privilegeValue);
break;
}
default:
String msg = Restrictable.class.getName()
+ PrivilegeMessages.getString("Privilege.roleAccessPrivilege.unknownPrivilege"); //$NON-NLS-1$
msg = MessageFormat.format(msg, privilegeName);
throw new PrivilegeException(msg);
}
}
}

View File

@ -0,0 +1,139 @@
/*
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ch.eitchnet.privilege.policy;
import java.text.MessageFormat;
import ch.eitchnet.privilege.base.PrivilegeException;
import ch.eitchnet.privilege.handler.PrivilegeHandler;
import ch.eitchnet.privilege.i18n.PrivilegeMessages;
import ch.eitchnet.privilege.model.IPrivilege;
import ch.eitchnet.privilege.model.PrivilegeContext;
import ch.eitchnet.privilege.model.Restrictable;
import ch.eitchnet.privilege.model.internal.User;
import ch.eitchnet.utils.collections.Tuple;
import ch.eitchnet.utils.dbc.DBC;
/**
* TODO
*
* @author Robert von Burg <eitch@eitchnet.ch>
*/
public class UserAccessPrivilege implements PrivilegePolicy {
@Override
public void validateAction(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable) {
String privilegeName = PrivilegePolicyHelper.preValidate(privilege, restrictable);
// get the value on which the action is to be performed
Object object = restrictable.getPrivilegeValue();
// RoleAccessPrivilege policy expects the privilege value to be a role
if (!(object instanceof Tuple)) {
String msg = Restrictable.class.getName()
+ PrivilegeMessages.getString("Privilege.illegalArgument.nontuple"); //$NON-NLS-1$
msg = MessageFormat.format(msg, restrictable.getClass().getSimpleName());
throw new PrivilegeException(msg);
}
// if everything is allowed, then no need to carry on
if (privilege.isAllAllowed())
return;
Tuple tuple = (Tuple) object;
switch (privilegeName) {
case PrivilegeHandler.PRIVILEGE_GET_USER: {
User oldUser = tuple.getFirst();
User newUser = tuple.getSecond();
DBC.INTERIM.assertNull("For " + privilegeName + " first must be null!", oldUser);
DBC.INTERIM.assertNotNull("For " + privilegeName + " second must not be null!", newUser);
String privilegeValue = newUser.getUsername();
PrivilegePolicyHelper.checkByAllowDenyValues(ctx, privilege, restrictable, privilegeValue);
break;
}
case PrivilegeHandler.PRIVILEGE_ADD_USER: {
User oldUser = tuple.getFirst();
User newUser = tuple.getSecond();
DBC.INTERIM.assertNull("For " + privilegeName + " first must be null!", oldUser);
DBC.INTERIM.assertNotNull("For " + privilegeName + " second must not be null!", newUser);
String privilegeValue = newUser.getUsername();
PrivilegePolicyHelper.checkByAllowDenyValues(ctx, privilege, restrictable, privilegeValue);
break;
}
case PrivilegeHandler.PRIVILEGE_REMOVE_USER: {
User oldUser = tuple.getFirst();
User newUser = tuple.getSecond();
DBC.INTERIM.assertNull("For " + privilegeName + " first must be null!", oldUser);
DBC.INTERIM.assertNotNull("For " + privilegeName + " second must not be null!", newUser);
String privilegeValue = newUser.getUsername();
PrivilegePolicyHelper.checkByAllowDenyValues(ctx, privilege, restrictable, privilegeValue);
break;
}
case PrivilegeHandler.PRIVILEGE_MODIFY_USER: {
User oldUser = tuple.getFirst();
User newUser = tuple.getSecond();
DBC.INTERIM.assertNotNull("For " + privilegeName + " first must not be null!", oldUser);
DBC.INTERIM.assertNotNull("For " + privilegeName + " second must not be null!", newUser);
String privilegeValue = newUser.getUsername();
DBC.INTERIM.assertEquals("oldUser and newUser names must be the same", oldUser.getUsername(),
privilegeValue);
PrivilegePolicyHelper.checkByAllowDenyValues(ctx, privilege, restrictable, privilegeValue);
break;
}
case PrivilegeHandler.PRIVILEGE_ADD_ROLE_TO_USER: {
User user = tuple.getFirst();
String roleName = tuple.getSecond();
DBC.INTERIM.assertNotNull("For " + privilegeName + " first must not be null!", user);
DBC.INTERIM.assertNotNull("For " + privilegeName + " second must not be null!", roleName);
PrivilegePolicyHelper.checkByAllowDenyValues(ctx, privilege, restrictable, roleName);
break;
}
case PrivilegeHandler.PRIVILEGE_REMOVE_ROLE_FROM_USER: {
User user = tuple.getFirst();
String roleName = tuple.getSecond();
DBC.INTERIM.assertNotNull("For " + privilegeName + " first must not be null!", user);
DBC.INTERIM.assertNotNull("For " + privilegeName + " second must not be null!", roleName);
PrivilegePolicyHelper.checkByAllowDenyValues(ctx, privilege, restrictable, roleName);
break;
}
default:
String msg = Restrictable.class.getName()
+ PrivilegeMessages.getString("Privilege.userAccessPrivilege.unknownPrivilege"); //$NON-NLS-1$
msg = MessageFormat.format(msg, privilegeName);
throw new PrivilegeException(msg);
}
}
}

View File

@ -169,6 +169,11 @@ public class PrivilegeModelSaxReader extends DefaultHandler {
} else if (qName.equals(XmlConstants.XML_PRIVILEGE)) {
this.privilegeName = attributes.getValue(XmlConstants.XML_ATTR_NAME);
this.privilegePolicy = attributes.getValue(XmlConstants.XML_ATTR_POLICY);
} else if (qName.equals(XmlConstants.XML_ALLOW) || qName.equals(XmlConstants.XML_DENY)
|| qName.equals(XmlConstants.XML_ALL_ALLOWED)) {
// no-op
} else {
throw new IllegalArgumentException("Unhandled tag " + qName);
}
}
@ -267,12 +272,20 @@ public class PrivilegeModelSaxReader extends DefaultHandler {
this.locale = new Locale(this.text.toString().trim());
} else if (qName.equals(XmlConstants.XML_ROLE)) {
this.userRoles.add(this.text.toString().trim());
} else if (qName.equals(XmlConstants.XML_ROLES)) {
// NO-OP
} else if (qName.equals(XmlConstants.XML_PARAMETER)) {
// NO-OP
} else if (qName.equals(XmlConstants.XML_PARAMETERS)) {
// NO-OP
} else if (qName.equals(XmlConstants.XML_USER)) {
User user = new User(this.userId, this.username, this.password, this.firstName, this.lastname,
this.userState, this.userRoles, this.locale, this.parameters);
logger.info(MessageFormat.format("New User: {0}", user)); //$NON-NLS-1$
getUsers().add(user);
} else {
throw new IllegalArgumentException("Unhandled tag " + qName);
}
}
@ -296,6 +309,10 @@ public class PrivilegeModelSaxReader extends DefaultHandler {
String key = attributes.getValue(XmlConstants.XML_ATTR_NAME);
String value = attributes.getValue(XmlConstants.XML_ATTR_VALUE);
this.parameterMap.put(key, value);
} else if (qName.equals(XmlConstants.XML_PROPERTIES)) {
// NO-OP
} else {
throw new IllegalArgumentException("Unhandled tag " + qName);
}
}

View File

@ -1,6 +1,12 @@
Privilege.accessdenied.noprivilege=User {0} does not have Privilege {1} needed for Restrictable {2}
Privilege.illegalArgument.nonstring=\ {1} has returned a non-string privilege value\!
Privilege.illegalArgument.nonstring=\ {0} has returned a non-string privilege value\!
Privilege.illegalArgument.nonrole=\ {0} did not return a Role privilege value\!
Privilege.illegalArgument.nonuser=\ {0} did not return a User privilege value\!
Privilege.illegalArgument.privilegeNameMismatch=The passed privilege has the name {0} but the restrictable is referencing privilege {1}
Privilege.privilegeNameEmpty=The PrivilegeName for the Restrictable is null or empty: {0}
Privilege.privilegeNull=Privilege may not be null\!
Privilege.restrictableNull=Restrictable may not be null\!
Privilege.noprivilege=No Privilege exists with name {0}
Privilege.noprivilege.user=User {0} does not have a Privilege {0}
Privilege.roleAccessPrivilege.unknownPrivilege=Unhandled RoleAccessPrivilege {0}
Privilege.userAccessPrivilege.unknownPrivilege=Unhandled UserAccessPrivilege {0}

View File

@ -21,6 +21,7 @@ import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.File;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@ -40,6 +41,7 @@ import ch.eitchnet.privilege.base.AccessDeniedException;
import ch.eitchnet.privilege.base.PrivilegeException;
import ch.eitchnet.privilege.handler.PrivilegeHandler;
import ch.eitchnet.privilege.helper.PrivilegeInitializationHelper;
import ch.eitchnet.privilege.i18n.PrivilegeMessages;
import ch.eitchnet.privilege.model.Certificate;
import ch.eitchnet.privilege.model.PrivilegeContext;
import ch.eitchnet.privilege.model.PrivilegeRep;
@ -63,6 +65,7 @@ import ch.eitchnet.utils.helper.FileHelper;
@SuppressWarnings("nls")
public class PrivilegeTest {
private static final String ROLE_PRIVILEGE_ADMIN = "PrivilegeAdmin";
private static final String ADMIN = "admin";
private static final byte[] PASS_ADMIN = "admin".getBytes();
private static final String BOB = "bob";
@ -146,7 +149,7 @@ public class PrivilegeTest {
String pwd = System.getProperty("user.dir");
File privilegeConfigFile = new File(pwd + "/config/Privilege.xml");
File privilegeConfigFile = new File(pwd + "/config/PrivilegeConfig.xml");
// initialize privilege
privilegeHandler = PrivilegeInitializationHelper.initializeFromXml(privilegeConfigFile);
@ -579,8 +582,8 @@ public class PrivilegeTest {
// testAddAdminRoleToBob
login(ADMIN, ArraysHelper.copyOf(PASS_ADMIN));
Certificate certificate = this.ctx.getCertificate();
privilegeHandler.addRoleToUser(certificate, BOB, PrivilegeHandler.PRIVILEGE_ADMIN_ROLE);
logger.info("Added " + PrivilegeHandler.PRIVILEGE_ADMIN_ROLE + " to " + ADMIN);
privilegeHandler.addRoleToUser(certificate, BOB, ROLE_PRIVILEGE_ADMIN);
logger.info("Added " + ROLE_PRIVILEGE_ADMIN + " to " + ADMIN);
privilegeHandler.persist(certificate);
} finally {
logout();
@ -602,7 +605,8 @@ public class PrivilegeTest {
privilegeHandler.addUser(certificate, userRep, null);
fail("User bob may not add a user as bob does not have admin rights!");
} catch (PrivilegeException e) {
String msg = "User does not have PrivilegeAdmin role! Certificate: " + certificate;
String msg = MessageFormat.format(PrivilegeMessages.getString("Privilege.noprivilege.user"), //$NON-NLS-1$
BOB, PrivilegeHandler.PRIVILEGE_ADD_USER);
assertEquals(msg, e.getMessage());
} finally {
logout();