// Copyright 2004-2014 Jim Voris // // 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 com.qumasoft.server; import com.qumasoft.qvcslib.QVCSConstants; import com.qumasoft.qvcslib.RoleType; import com.qumasoft.qvcslib.Utility; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; /** * Role Manager. This is a singleton. * @author Jim Voris */ public final class RoleManager implements RoleManagerInterface { // Create our logger object private static final Logger LOGGER = Logger.getLogger("com.qumasoft.server"); private static final RoleManager ROLE_MANAGER = new RoleManager(); private boolean isInitializedFlag = false; private String roleStoreName = null; private RoleStore roleStore = null; private String roleProjectViewStoreName = null; private String roleProjectViewStoreNameOld = null; private RoleProjectViewStore roleProjectViewStore = null; /** * Creates a new instance of the RoleManager. */ private RoleManager() { } /** * Get the role manager singleton. * @return the role manager singleton. */ public static RoleManager getRoleManager() { return ROLE_MANAGER; } @Override public synchronized boolean initialize() { if (!isInitializedFlag) { roleStoreName = System.getProperty("user.dir") + File.separator + QVCSConstants.QVCS_ADMIN_DATA_DIRECTORY + File.separator + QVCSConstants.QVCS_ROLE_STORE_NAME + "dat"; roleProjectViewStoreName = System.getProperty("user.dir") + File.separator + QVCSConstants.QVCS_ADMIN_DATA_DIRECTORY + File.separator + QVCSConstants.QVCS_ROLE_PROJECT_VIEW_STORE_NAME + "dat"; roleProjectViewStoreNameOld = roleProjectViewStoreName + ".old"; loadRoleStore(); isInitializedFlag = true; } return isInitializedFlag; } private void loadRoleStore() { File roleStoreFile; FileInputStream fileStream = null; try { roleStoreFile = new File(roleStoreName); if (roleStoreFile.exists()) { populateRoleProjectViewStoreFromRoleStore(); } else { roleStoreFile = new File(roleProjectViewStoreName); fileStream = new FileInputStream(roleStoreFile); ObjectInputStream inStream = new ObjectInputStream(fileStream); roleProjectViewStore = (RoleProjectViewStore) inStream.readObject(); } } catch (FileNotFoundException e) { // The file doesn't exist yet. Create a default store. roleProjectViewStore = new RoleProjectViewStore(); writeRoleStore(); } catch (IOException | ClassNotFoundException e) { LOGGER.log(Level.WARNING, "Failed to read role store: " + e.getLocalizedMessage()); if (fileStream != null) { try { fileStream.close(); fileStream = null; } catch (IOException ex) { LOGGER.log(Level.WARNING, Utility.expandStackTraceToString(ex)); } } // Serialization failed. Create a default store. roleProjectViewStore = new RoleProjectViewStore(); LOGGER.log(Level.INFO, "Creating default role store."); writeRoleStore(); } finally { if (fileStream != null) { try { fileStream.close(); } catch (IOException e) { LOGGER.log(Level.WARNING, Utility.expandStackTraceToString(e)); } } roleProjectViewStore.dumpMaps(); } } @Override public synchronized void writeRoleStore() { FileOutputStream fileStream = null; try { File storeFile = new File(roleProjectViewStoreName); File oldStoreFile = new File(roleProjectViewStoreNameOld); if (oldStoreFile.exists()) { oldStoreFile.delete(); } if (storeFile.exists()) { storeFile.renameTo(oldStoreFile); } File newStoreFile = new File(roleProjectViewStoreName); // Make sure the needed directories exists if (!newStoreFile.getParentFile().exists()) { newStoreFile.getParentFile().mkdirs(); } fileStream = new FileOutputStream(newStoreFile); ObjectOutputStream outStream = new ObjectOutputStream(fileStream); outStream.writeObject(roleProjectViewStore); } catch (IOException e) { LOGGER.log(Level.WARNING, Utility.expandStackTraceToString(e)); } finally { if (fileStream != null) { try { fileStream.close(); } catch (IOException e) { LOGGER.log(Level.WARNING, Utility.expandStackTraceToString(e)); } } } } @Override public synchronized boolean addUserRole(String callerUserName, String projectName, String userName, RoleType role) { boolean retVal = false; if (initialize()) { retVal = roleProjectViewStore.addProjectViewUser(callerUserName, projectName, userName, role); } if (retVal) { writeRoleStore(); } return retVal; } @Override public synchronized boolean removeUserRole(String callerUserName, String projectName, String userName, RoleType role) { boolean retVal = false; if (initialize()) { retVal = roleProjectViewStore.removeProjectViewUser(callerUserName, projectName, userName, role); } if (retVal) { writeRoleStore(); } return retVal; } /** * Get the list of project users. * @param projectName the project name. * @return the list of users for the given project. */ public synchronized String[] listProjectUsers(String projectName) { String[] projectUsers = null; if (initialize()) { projectUsers = roleProjectViewStore.listProjectUsers(projectName); } return projectUsers; } /** * List user roles for a given project. * @param projectName the project name. * @param userName the user name. * @return a list of the users roles for the given project. */ public synchronized String[] listUserRoles(String projectName, String userName) { String[] userRoles = null; if (initialize()) { userRoles = roleProjectViewStore.listUserRoles(projectName, userName); } return userRoles; } @Override public synchronized boolean removeAllUserRoles(String callerUserName, String projectName, String userName) { boolean retVal = false; String[] userRoles = listUserRoles(projectName, userName); if (userRoles != null) { retVal = true; for (int i = 0; i < userRoles.length && retVal; i++) { retVal = removeUserRole(callerUserName, projectName, userName, getRoleType(userRoles[i])); } } return retVal; } @Override public synchronized boolean removeAllUserRolesInAllProjects(String callerUserName, String userName) { boolean retVal = false; if (initialize()) { String[] projectList = roleProjectViewStore.getProjectList(); if (projectList != null) { retVal = true; for (int i = 0; (i < projectList.length) && retVal; i++) { retVal = removeAllUserRoles(callerUserName, projectList[i], userName); } } } return retVal; } /** * Use this method when deleting a project from the server. This method will remove all user roles associated with that project. * * @param projectName the project name. * @param callerUserName the caller user name. * @return true if things work okay. */ public synchronized boolean removeAllProjectRoles(String projectName, String callerUserName) { boolean retVal = true; String[] projectUsers = listProjectUsers(projectName); for (int i = 0; (i < projectUsers.length) && retVal; i++) { retVal = removeAllUserRoles(callerUserName, projectName, projectUsers[i]); } return retVal; } @Override public RoleType getRoleType(String roleType) { return RolePrivilegesManager.getInstance().getRoleType(roleType); } /** * Get the list of available roles. * @return the list of available roles. */ public String[] getAvailableRoles() { return RolePrivilegesManager.getInstance().getAvailableRoles(); } @Override public synchronized boolean assignUserRoles(String callerUserName, String projectName, String userName, String[] roles) { boolean retVal = false; // Remove any existing roles if (removeAllUserRoles(callerUserName, projectName, userName)) { retVal = true; for (int i = 0; (i < roles.length) && retVal; i++) { retVal = addUserRole(callerUserName, projectName, userName, getRoleType(roles[i])); } } return retVal; } /** * Delete a role. * @param role the role to delete. */ public synchronized void deleteRole(final String role) { if (0 != role.compareTo(ADMIN)) { RolePrivilegesManager.getInstance().deleteRole(role); roleProjectViewStore.deleteRole(role); } } private void populateRoleProjectViewStoreFromRoleStore() throws IOException, ClassNotFoundException { File roleStoreFile = null; FileInputStream fileStream = null; try { roleStoreFile = new File(roleStoreName); fileStream = new FileInputStream(roleStoreFile); ObjectInputStream inStream = new ObjectInputStream(fileStream); roleStore = (RoleStore) inStream.readObject(); roleProjectViewStore = new RoleProjectViewStore(); Set projectKeys = roleStore.getProjectUserMapKeySet(); Iterator j = projectKeys.iterator(); while (j.hasNext()) { String projectName = (String) j.next(); LOGGER.log(Level.INFO, projectName); Map projectUserMap = roleStore.getProjectUserMap(projectName); Set userKeys = projectUserMap.keySet(); Iterator k = userKeys.iterator(); while (k.hasNext()) { String userAndRole = (String) k.next(); int separatorIndex = userAndRole.lastIndexOf('.'); String userRole = userAndRole.substring(1 + separatorIndex); String userName = userAndRole.substring(0, separatorIndex); roleProjectViewStore.addProjectViewUser(ADMIN, projectName, userName, getRoleType(userRole)); LOGGER.log(Level.INFO, "Converting project: " + projectName + " user: " + userName + " role: " + userRole); } } } catch (IOException | ClassNotFoundException e) { LOGGER.log(Level.WARNING, Utility.expandStackTraceToString(e)); throw e; } finally { if (fileStream != null) { try { fileStream.close(); } catch (IOException e) { LOGGER.log(Level.WARNING, Utility.expandStackTraceToString(e)); } // We don't need the old role store anymore if (roleStoreFile != null && roleStoreFile.exists()) { roleStoreFile.delete(); } } writeRoleStore(); roleProjectViewStore.dumpMaps(); } } }