/******************************************************************************* * Copyright (c) 2015 MEDEVIT. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * MEDEVIT <office@medevit.at> - initial API and implementation ******************************************************************************/ package ch.elexis.data; import java.util.Arrays; import java.util.List; import java.util.Locale; import ch.elexis.admin.ACE; import ch.elexis.core.data.activator.CoreHub; import ch.elexis.core.jdt.Nullable; import ch.rgw.tools.JdbcLink.Stm; public class Role extends PersistentObject { public static final String TABLENAME = "ROLE"; public static final String FLD_SYSTEM_ROLE = "ISSYSTEMROLE"; public static final String FLD_EXT_I18N_LABEL = "LAB_" + Locale.getDefault().getLanguage(); public static final String FLD_JOINT_RIGHTS = "Rights"; static { addMapping(TABLENAME, FLD_ID, FLD_SYSTEM_ROLE, FLD_EXTINFO, FLD_JOINT_RIGHTS + "=LIST:ROLE_ID:ROLE_RIGHT_JOINT"); initTables(); } public Role(){} protected static void initTables() { if (!tableExists(TABLENAME)) { executeDBInitScriptForClass(Role.class, null); ACE.initializeACEDefaults(false); } } public Role(boolean isSystemRole){ create(null); setSystemRole(false); } protected Role(final String id){ super(id); } public static Role load(final String id){ return new Role(id); } @Override public String getLabel(){ return get(FLD_ID); } @Override protected String getTableName(){ return TABLENAME; } public boolean isSystemRole(){ return getBoolean(FLD_SYSTEM_ROLE); } public void setSystemRole(boolean val){ // ignored, for databinding only } public String getRoleName(){ return get(FLD_ID); } /** * renames the role, which effectively changes the id resulting in a new object returned * * @param rolename * @return */ public @Nullable Role setRoleName(String rolename){ if (verifyRoleNameNotTaken(rolename)) { List<ACE> ar = Arrays.asList(getAssignedAccessRights()); ar.stream().forEachOrdered(a -> revokeAccessRight(a)); set(FLD_ID, rolename); Role r = Role.load(rolename); ar.stream().forEachOrdered(a -> r.grantAccessRight(a)); return r; } return null; } /** * verify whether the proposed rolename is not already in use * * @param rolename * @return <code>true</code> if the given rolename is available for use */ public static boolean verifyRoleNameNotTaken(String rolename){ return new Query<Role>(Role.class, FLD_ID, rolename).execute().size() == 0; } public String getTranslatedLabel(){ return (String) getExtInfoStoredObjectByKey(FLD_EXT_I18N_LABEL); } public void setTranslatedLabel(String translatedLabel){ setExtInfoStoredObjectByKey(FLD_EXT_I18N_LABEL, translatedLabel); } public ACE[] getAssignedAccessRights(){ ACE[] array = ACE.getAllDefinedACElements().stream() .filter(p -> CoreHub.acl.request(this, p)).toArray(size -> new ACE[size]); return array; } /** * @return the {@link Right#ID} of all rights permitted to this role */ private List<String> getAssignedRightsIds(){ return getList(FLD_JOINT_RIGHTS, false); } /** * @param ace * grants the respective right, and all associated child rights if applicable */ public void grantAccessRight(ACE ace){ // check if ace is already granted via a parent right // if it is, just return Right right = Right.getOrCreateRightByACE(ace); if (getAssignedRightsIds().contains(ace.getUniqueHashFromACE())) return; // We could use INSERT IGNORE on mysql addToList(FLD_JOINT_RIGHTS, right.getId()); } /** * * @param ace * revokes the respective right, all associated child rights if applicable */ public void revokeAccessRight(ACE ace){ ace.getChildren(true).stream().map(p -> Right.getOrCreateRightByACE(p)) .forEachOrdered(r -> removeFromList(FLD_JOINT_RIGHTS, r.getId())); } @Override public boolean delete(){ if (isSystemRole()) return false; Arrays.asList(getAssignedAccessRights()).stream().forEachOrdered(a -> revokeAccessRight(a)); Stm stm = getConnection().getStatement(); int res = stm.exec("DELETE FROM " + TABLENAME + " WHERE ID=" + getWrappedId()); getConnection().releaseStatement(stm); return res == 1; } /** * Revokes all rights of this role */ public void revokeAllRightsForRole(){ Stm stm = getConnection().getStatement(); stm.exec("DELETE FROM ROLE_RIGHT_JOINT WHERE ROLE_ID=" + getWrappedId()); getConnection().releaseStatement(stm); } }