diff --git a/src/main/java/ch/eitchnet/privilege/policy/UserAccessWithSameOrganisationPrivilege.java b/src/main/java/ch/eitchnet/privilege/policy/UserAccessWithSameOrganisationPrivilege.java new file mode 100644 index 000000000..599c4a7c3 --- /dev/null +++ b/src/main/java/ch/eitchnet/privilege/policy/UserAccessWithSameOrganisationPrivilege.java @@ -0,0 +1,115 @@ +/* + * Copyright 2015 Robert von Burg + * + * 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.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; +import ch.eitchnet.utils.helper.StringHelper; + +/** + * Validates that any access to a privilege User is done only by users in the same organisation + * + * @author Robert von Burg + */ +public class UserAccessWithSameOrganisationPrivilege extends UserAccessPrivilege { + + private static final String PARAM_ORGANISATION = "organisation"; + + @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); + } + + // get user organisation + String userOrg = ctx.getCertificate().getProperty(PARAM_ORGANISATION); + if (StringHelper.isEmpty(userOrg)) { + throw new AccessDeniedException("No organisation configured for user " + ctx.getUsername()); + } + + Tuple tuple = (Tuple) object; + + switch (privilegeName) { + case PrivilegeHandler.PRIVILEGE_GET_USER: + case PrivilegeHandler.PRIVILEGE_ADD_USER: + case PrivilegeHandler.PRIVILEGE_MODIFY_USER: + case PrivilegeHandler.PRIVILEGE_REMOVE_USER: { + + // make sure old user has same organisation + User oldUser = tuple.getFirst(); + if (oldUser != null) { + String oldOrg = oldUser.getProperty(PARAM_ORGANISATION); + if (!userOrg.equals(oldOrg)) { + throw new AccessDeniedException("User " + ctx.getUsername() + + " may not access users outside of their organisation: " + userOrg + " / " + oldOrg); + } + } + + // make sure new user has same organisation + User newUser = tuple.getSecond(); + DBC.INTERIM.assertNotNull("For " + privilegeName + " second must not be null!", newUser); + String newdOrg = newUser.getProperty(PARAM_ORGANISATION); + if (!userOrg.equals(newdOrg)) { + throw new AccessDeniedException("User " + ctx.getUsername() + + " may not access users outside of their organisations: " + userOrg + " / " + newdOrg); + } + + break; + } + case PrivilegeHandler.PRIVILEGE_ADD_ROLE_TO_USER: + case PrivilegeHandler.PRIVILEGE_REMOVE_ROLE_FROM_USER: { + + User user = tuple.getFirst(); + DBC.INTERIM.assertNotNull("For " + privilegeName + " first must not be null!", user); + String org = user.getProperty(PARAM_ORGANISATION); + if (!userOrg.equals(org)) { + throw new AccessDeniedException("User " + ctx.getUsername() + + " may not access users outside of their organisation: " + userOrg + " / " + org); + } + + break; + } + + default: + String msg = Restrictable.class.getName() + + PrivilegeMessages.getString("Privilege.userAccessPrivilege.unknownPrivilege"); //$NON-NLS-1$ + msg = MessageFormat.format(msg, privilegeName); + throw new PrivilegeException(msg); + } + + // now delegate the rest of the validation to the super class + super.validateAction(ctx, privilege, restrictable); + } +} diff --git a/src/main/java/ch/eitchnet/privilege/policy/UsernameFromCertificateWithSameOrganisationPrivilege.java b/src/main/java/ch/eitchnet/privilege/policy/UsernameFromCertificateWithSameOrganisationPrivilege.java new file mode 100644 index 000000000..124addf28 --- /dev/null +++ b/src/main/java/ch/eitchnet/privilege/policy/UsernameFromCertificateWithSameOrganisationPrivilege.java @@ -0,0 +1,79 @@ +/* + * Copyright 2013 Robert von Burg + * + * 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.Certificate; +import ch.eitchnet.privilege.model.IPrivilege; +import ch.eitchnet.privilege.model.PrivilegeContext; +import ch.eitchnet.privilege.model.Restrictable; +import ch.eitchnet.utils.helper.StringHelper; + +/** + *

+ * This {@link PrivilegePolicy} expects a {@link Certificate} as {@link Restrictable#getPrivilegeValue()} and uses the + * basic Allow and Deny to detect if the username of the certificate is allowed. + *

+ * + *

+ * The {@link Certificate} as privilegeValue is not to be confused with the {@link Certificate} of the current user. + * This certificate is of the user to which access is request, i.e. modifying the session of a logged in user. + *

+ * + * @author Robert von Burg + */ +public class UsernameFromCertificateWithSameOrganisationPrivilege extends UsernameFromCertificatePrivilege { + + private static final String PARAM_ORGANISATION = "organisation"; + + @Override + public void validateAction(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable) { + 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 Certificate)) { + String msg = Restrictable.class.getName() + + PrivilegeMessages.getString("Privilege.illegalArgument.noncertificate"); //$NON-NLS-1$ + msg = MessageFormat.format(msg, restrictable.getClass().getSimpleName()); + throw new PrivilegeException(msg); + } + + // get object + Certificate cert = (Certificate) object; + + // get user organisation + String userOrg = ctx.getCertificate().getProperty(PARAM_ORGANISATION); + if (StringHelper.isEmpty(userOrg)) { + throw new AccessDeniedException("No organisation configured for user " + ctx.getUsername()); + } + // assert same organisation + String org = cert.getProperty(PARAM_ORGANISATION); + if (!userOrg.equals(org)) { + throw new AccessDeniedException("User " + ctx.getUsername() + + " may not access users outside of their organisation: " + userOrg + " / " + org); + } + + // now delegate the rest of the validation to the super class + super.validateAction(ctx, privilege, restrictable); + } +}