[Major] Setting user password, locale and state are now separate privs

This commit is contained in:
Robert von Burg 2015-04-05 00:13:16 +02:00
parent 2607bbef3f
commit 4c6434f475
8 changed files with 211 additions and 39 deletions

View File

@ -81,6 +81,17 @@
<Privilege name="PrivilegeRemoveRoleFromUser" policy="UserAccessPrivilege">
<AllAllowed>true</AllAllowed>
</Privilege>
<Privilege name="PrivilegeSetUserLocale" policy="UserAccessPrivilege">
<AllAllowed>true</AllAllowed>
</Privilege>
<Privilege name="PrivilegeSetUserState" policy="UserAccessPrivilege">
<Allow>ENABLED</Allow>
<Allow>DISABLED</Allow>
<Deny>SYSTEM</Deny>
</Privilege>
<Privilege name="PrivilegeSetUserPassword" policy="UserAccessPrivilege">
<AllAllowed>true</AllAllowed>
</Privilege>
</Role>
<Role name="AppUser">

View File

@ -651,18 +651,9 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
@Override
public UserRep setUserLocale(Certificate certificate, String username, Locale locale) {
// check if certificate is for same user, in which case user is changing their own locale
if (certificate.getUsername().equals(username)) {
// validate the certificate
isCertificateValid(certificate);
} else {
// validate user actually has this type of privilege
PrivilegeContext prvCtx = getPrivilegeContext(certificate);
prvCtx.assertHasPrivilege(PRIVILEGE_MODIFY_USER);
}
// validate user actually has this type of privilege
PrivilegeContext prvCtx = getPrivilegeContext(certificate);
prvCtx.assertHasPrivilege(PRIVILEGE_SET_USER_LOCALE);
// get User
User existingUser = this.persistenceHandler.getUser(username);
@ -677,8 +668,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
// 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)));
prvCtx.validateAction(new SimpleRestrictable(PRIVILEGE_SET_USER_LOCALE, new Tuple(existingUser, newUser)));
}
// delegate user replacement to persistence handler
@ -696,18 +686,9 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
public void setUserPassword(Certificate certificate, String username, byte[] password) {
try {
// check if certificate is for same user, in which case user is changing their own password
if (certificate.getUsername().equals(username)) {
// validate the certificate
isCertificateValid(certificate);
} else {
// validate user actually has this type of privilege
PrivilegeContext prvCtx = getPrivilegeContext(certificate);
prvCtx.assertHasPrivilege(PRIVILEGE_MODIFY_USER);
}
// validate user actually has this type of privilege
PrivilegeContext prvCtx = getPrivilegeContext(certificate);
prvCtx.assertHasPrivilege(PRIVILEGE_SET_USER_PASSWORD);
// get User
User existingUser = this.persistenceHandler.getUser(username);
@ -732,8 +713,8 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
// 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)));
prvCtx.validateAction(new SimpleRestrictable(PRIVILEGE_SET_USER_PASSWORD, new Tuple(existingUser,
newUser)));
}
// delegate user replacement to persistence handler
@ -754,7 +735,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
// validate user actually has this type of privilege
PrivilegeContext prvCtx = getPrivilegeContext(certificate);
prvCtx.assertHasPrivilege(PRIVILEGE_MODIFY_USER);
prvCtx.assertHasPrivilege(PRIVILEGE_SET_USER_STATE);
// get User
User existingUser = this.persistenceHandler.getUser(username);
@ -768,7 +749,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
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)));
prvCtx.validateAction(new SimpleRestrictable(PRIVILEGE_SET_USER_STATE, new Tuple(existingUser, newUser)));
// delegate user replacement to persistence handler
this.persistenceHandler.replaceUser(newUser);

View File

@ -114,6 +114,20 @@ public interface PrivilegeHandler {
* specific user
*/
public static final String PRIVILEGE_REMOVE_ROLE_FROM_USER = "PrivilegeRemoveRoleFromUser";
/**
* Privilege "PRIVILEGE_SET_USER_LOCALE" which is used to validate that a user can set the locale of a user, or
* their own
*/
public static final String PRIVILEGE_SET_USER_LOCALE = "PrivilegeSetUserLocale";
/**
* Privilege "PRIVILEGE_SET_USER_STATE" which is used to validate that a user can set the state of a user
*/
public static final String PRIVILEGE_SET_USER_STATE = "PrivilegeSetUserState";
/**
* Privilege "PRIVILEGE_SET_USER_PASSWORD" which is used to validate that a user can set the password of a user, or
* their own
*/
public static final String PRIVILEGE_SET_USER_PASSWORD = "PrivilegeSetUserPassword";
///

View File

@ -44,6 +44,10 @@ public class RoleAccessPrivilege implements PrivilegePolicy {
// get the value on which the action is to be performed
Object object = restrictable.getPrivilegeValue();
// if the object is null, then it means the validation is that the privilege must exist
if (object == null)
return;
// RoleAccessPrivilege policy expects the privilege value to be a role
if (!(object instanceof Tuple)) {
String msg = Restrictable.class.getName()

View File

@ -43,6 +43,10 @@ public class UserAccessPrivilege implements PrivilegePolicy {
// get the value on which the action is to be performed
Object object = restrictable.getPrivilegeValue();
// if the object is null, then it means the validation is that the privilege must exist
if (object == null)
return;
// RoleAccessPrivilege policy expects the privilege value to be a role
if (!(object instanceof Tuple)) {
String msg = Restrictable.class.getName()
@ -130,11 +134,56 @@ public class UserAccessPrivilege implements PrivilegePolicy {
break;
}
case PrivilegeHandler.PRIVILEGE_SET_USER_STATE: {
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.getUserState().name();
PrivilegePolicyHelper.checkByAllowDenyValues(ctx, privilege, restrictable, privilegeValue);
break;
}
case PrivilegeHandler.PRIVILEGE_SET_USER_LOCALE: {
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();
// user can set their own locale
if (ctx.getUsername().equals(privilegeValue))
return;
PrivilegePolicyHelper.checkByAllowDenyValues(ctx, privilege, restrictable, privilegeValue);
break;
}
case PrivilegeHandler.PRIVILEGE_SET_USER_PASSWORD: {
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();
// user can set their own password
if (ctx.getUsername().equals(privilegeValue))
return;
PrivilegePolicyHelper.checkByAllowDenyValues(ctx, privilege, restrictable, privilegeValue);
break;
}
default:
String msg = Restrictable.class.getName()
+ PrivilegeMessages.getString("Privilege.userAccessPrivilege.unknownPrivilege"); //$NON-NLS-1$
msg = MessageFormat.format(msg, privilegeName);
String msg = PrivilegeMessages.getString("Privilege.userAccessPrivilege.unknownPrivilege"); //$NON-NLS-1$
msg = MessageFormat.format(msg, privilegeName, this.getClass().getName());
throw new PrivilegeException(msg);
}
}

View File

@ -4,10 +4,11 @@ Privilege.illegalArgument.nonrole=\ {0} did not return a Role privilege value\!
Privilege.illegalArgument.noncertificate=\ {0} did not return a Certificate 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.illegalArgument.nontuple=\ {0} did not return a Tuple privilege value\!
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 the privilege {1}
Privilege.roleAccessPrivilege.unknownPrivilege=Unhandled RoleAccessPrivilege {0}
Privilege.userAccessPrivilege.unknownPrivilege=Unhandled UserAccessPrivilege {0}
Privilege.roleAccessPrivilege.unknownPrivilege=Unhandled privilege {0} for policy {1}
Privilege.userAccessPrivilege.unknownPrivilege=Unhandled privilege {0} for policy {1}

View File

@ -28,6 +28,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import org.junit.AfterClass;
import org.junit.Before;
@ -67,6 +68,7 @@ import ch.eitchnet.utils.helper.FileHelper;
public class PrivilegeTest {
private static final String ROLE_PRIVILEGE_ADMIN = "PrivilegeAdmin";
private static final String PRIVILEGE_USER_ACCESS = "UserAccessPrivilege";
private static final String ADMIN = "admin";
private static final byte[] PASS_ADMIN = "admin".getBytes();
private static final String BOB = "bob";
@ -77,6 +79,7 @@ public class PrivilegeTest {
private static final String ROLE_APP_USER = "AppUser";
private static final String ROLE_MY = "MyRole";
private static final String ROLE_MY2 = "MyRole2";
private static final String ROLE_CHANGE_PW = "changePw";
private static final String ROLE_TEMP = "temp";
private static final String ROLE_USER = "user";
private static final byte[] PASS_DEF = "def".getBytes();
@ -487,13 +490,121 @@ public class PrivilegeTest {
addTedAsBob();
failAuthAsTedNoPass();
setPassForTedAsBob();
tedChangesOwnPass();
failSetSystemStateTed();
failTedChangesPwAndLocale();
addChangePwRoleToTed();
tedChangesOwnPassAndLocale();
failTedChangesOtherPwStateAndLocale();
authAsTed();
failPerformRestrictableAsBobNoRoleApp();
addRoleAppToBob();
performRestrictableAsBob();
}
private void failSetSystemStateTed() {
try {
// testEnableUserBob
login(BOB, ArraysHelper.copyOf(PASS_BOB));
Certificate certificate = this.ctx.getCertificate();
try {
privilegeHandler.setUserState(certificate, TED, UserState.SYSTEM);
fail("Should not be able to set user state to SYSTEM");
} catch (AccessDeniedException e) {
// ok
}
} finally {
logout();
}
}
private void failTedChangesOtherPwStateAndLocale() {
try {
// testTedChangesOwnPwd
login(TED, ArraysHelper.copyOf(PASS_TED));
Certificate certificate = this.ctx.getCertificate();
try {
privilegeHandler.setUserPassword(certificate, BOB, ArraysHelper.copyOf(PASS_TED));
fail("Should not be able to set password of other user, as missing privilege");
} catch (AccessDeniedException e) {
// ok
}
try {
privilegeHandler.setUserLocale(certificate, BOB, Locale.FRENCH);
fail("Should not be able to set locale of other user, as missing privilege");
} catch (AccessDeniedException e) {
// ok
}
try {
privilegeHandler.setUserState(certificate, BOB, UserState.DISABLED);
fail("Should not be able to set state of other user, as missing privilege");
} catch (AccessDeniedException e) {
// ok
}
} finally {
logout();
}
}
private void failTedChangesPwAndLocale() {
try {
// testTedChangesOwnPwd
login(TED, ArraysHelper.copyOf(PASS_DEF));
Certificate certificate = this.ctx.getCertificate();
try {
privilegeHandler.setUserPassword(certificate, TED, ArraysHelper.copyOf(PASS_TED));
fail("Should not be able to set password, as missing privilege");
} catch (AccessDeniedException e) {
// ok
}
try {
privilegeHandler.setUserLocale(certificate, TED, Locale.FRENCH);
fail("Should not be able to set locale, as missing privilege");
} catch (AccessDeniedException e) {
// ok
}
try {
privilegeHandler.setUserState(certificate, TED, UserState.ENABLED);
fail("Should not be able to set state, as missing privilege");
} catch (AccessDeniedException e) {
// ok
}
} finally {
logout();
}
}
private void addChangePwRoleToTed() {
try {
// add role user
login(ADMIN, ArraysHelper.copyOf(PASS_ADMIN));
PrivilegeRep passwordRep = new PrivilegeRep(PrivilegeHandler.PRIVILEGE_SET_USER_PASSWORD,
PRIVILEGE_USER_ACCESS, false, Collections.emptySet(), Collections.emptySet());
PrivilegeRep localeRep = new PrivilegeRep(PrivilegeHandler.PRIVILEGE_SET_USER_LOCALE,
PRIVILEGE_USER_ACCESS, false, Collections.emptySet(), Collections.emptySet());
RoleRep roleRep = new RoleRep(ROLE_CHANGE_PW, Arrays.asList(passwordRep, localeRep));
Certificate certificate = this.ctx.getCertificate();
privilegeHandler.addRole(certificate, roleRep);
privilegeHandler.addRoleToUser(certificate, TED, ROLE_CHANGE_PW);
logger.info("Added " + ROLE_CHANGE_PW + " to " + TED);
privilegeHandler.persist(certificate);
} finally {
logout();
}
}
private void performRestrictableAsBob() {
try {
// testPerformRestrictableAsBob
@ -547,12 +658,13 @@ public class PrivilegeTest {
}
}
private void tedChangesOwnPass() {
private void tedChangesOwnPassAndLocale() {
try {
// testTedChangesOwnPwd
login(TED, ArraysHelper.copyOf(PASS_DEF));
Certificate certificate = this.ctx.getCertificate();
privilegeHandler.setUserPassword(certificate, TED, ArraysHelper.copyOf(PASS_TED));
privilegeHandler.setUserLocale(certificate, TED, Locale.FRENCH);
} finally {
logout();
}
@ -666,7 +778,7 @@ public class PrivilegeTest {
try {
// add role user
login(ADMIN, ArraysHelper.copyOf(PASS_ADMIN));
RoleRep roleRep = new RoleRep(ROLE_USER, new ArrayList<PrivilegeRep>());
RoleRep roleRep = new RoleRep(ROLE_USER, new ArrayList<>());
Certificate certificate = this.ctx.getCertificate();
privilegeHandler.addRole(certificate, roleRep);
privilegeHandler.persist(certificate);

View File

@ -212,7 +212,7 @@ public class XmlTest {
// PrivilegeAdmin
Role privilegeAdmin = findRole("PrivilegeAdmin", roles);
assertEquals("PrivilegeAdmin", privilegeAdmin.getName());
assertEquals(11, privilegeAdmin.getPrivilegeNames().size());
assertEquals(14, privilegeAdmin.getPrivilegeNames().size());
IPrivilege privilegeAction = privilegeAdmin.getPrivilege(PrivilegeHandler.PRIVILEGE_ACTION);
assertFalse(privilegeAction.isAllAllowed());
assertEquals(3, privilegeAction.getAllowList().size());