diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/RemoveObsoletePermissions.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/RemoveObsoletePermissions.java new file mode 100644 index 000000000..b673e2423 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/RemoveObsoletePermissions.java @@ -0,0 +1,114 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.servlet.setup; + +import static edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils.WhichService.CONFIGURATION; + +import javax.servlet.ServletContext; +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.hp.hpl.jena.ontology.OntModel; +import com.hp.hpl.jena.query.Dataset; +import com.hp.hpl.jena.update.GraphStore; +import com.hp.hpl.jena.update.GraphStoreFactory; +import com.hp.hpl.jena.update.UpdateAction; +import com.hp.hpl.jena.update.UpdateFactory; +import com.hp.hpl.jena.update.UpdateRequest; + +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; +import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceDataset; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; +import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils; +import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; + +/** + * A handful of Permissions were removed between release 1.6 and 1.7. Remove + * them from the User Accounts model. + */ +public class RemoveObsoletePermissions implements ServletContextListener { + private static final Log log = LogFactory + .getLog(RemoveObsoletePermissions.class); + + static final String[] OBSOLETE_PERMISSIONS = { + "java:edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission#RebuildVClassGroupCache", + "java:edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission#ManageTabs", + "java:edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission#UseMiscellaneousEditorPages", + "java:edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission#ManagePortals" }; + static final String UPDATE_TEMPLATE = "" // + + "DELETE WHERE { \n" + + " GRAPH {\n" + + " ?s ?p <%s> .\n" + " } \n" + "}"; + + @Override + public void contextInitialized(ServletContextEvent sce) { + ServletContext ctx = sce.getServletContext(); + StartupStatus ss = StartupStatus.getBean(ctx); + + try { + Updater updater = new Updater(ctx); + updater.update(); + if (updater.statementsRemoved() == 0L) { + ss.info(this, "User accounts model contained no statements " + + "referencing obsolete permissions."); + } else { + ss.info(this, String.format( + "Adjusted the user accounts model. " + + "Removed %s statements referencing " + + "%s obsolete permissions.", + updater.statementsRemoved(), + OBSOLETE_PERMISSIONS.length)); + } + } catch (Exception e) { + ss.fatal(this, "Failed to update URIs of PermissionSets " + + "on User Accounts", e); + } + } + + @Override + public void contextDestroyed(ServletContextEvent sce) { + // Nothing to tear down. + } + + private static class Updater { + private final ServletContext ctx; + + private long statementsRemoved; + + public Updater(ServletContext ctx) { + this.ctx = ctx; + + } + + public void update() { + OntModel model = ModelAccess.on(ctx).getUserAccountsModel(); + long statementsAtStart = model.size(); + + RDFService rdfService = RDFServiceUtils.getRDFServiceFactory(ctx, + CONFIGURATION).getRDFService(); + for (String permissionUri : OBSOLETE_PERMISSIONS) { + removeStatements(rdfService, permissionUri); + } + + statementsRemoved = statementsAtStart - model.size(); + } + + private void removeStatements(RDFService rdfService, + String permissionUri) { + String updateString = String.format(UPDATE_TEMPLATE, permissionUri); + log.debug(updateString); + UpdateRequest parsed = UpdateFactory.create(updateString); + Dataset ds = new RDFServiceDataset(rdfService); + GraphStore graphStore = GraphStoreFactory.create(ds); + UpdateAction.execute(parsed, graphStore); + } + + public long statementsRemoved() { + return statementsRemoved; + } + + } +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdatePermissionSetUris.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdatePermissionSetUris.java deleted file mode 100644 index e8a66561e..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdatePermissionSetUris.java +++ /dev/null @@ -1,270 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.servlet.setup; - -import static edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary.VITRO_AUTH; - -import java.io.File; -import java.io.IOException; -import java.io.PrintWriter; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.servlet.ServletContext; -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; - -import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; -import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; -import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; -import edu.cornell.mannlib.vitro.webapp.dao.UserAccountsDao; -import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; -import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; - -/** - * The URIs for Admin, Curator, Editor and SelfEditor changed from 1.4 to 1.5. - * - * If the old ones are still in the User Accounts Model, replace them with the - * new ones. - */ -public class UpdatePermissionSetUris implements ServletContextListener { - - @Override - public void contextInitialized(ServletContextEvent sce) { - ServletContext ctx = sce.getServletContext(); - StartupStatus ss = StartupStatus.getBean(ctx); - Stats stats = new Stats(); - - try { - Updater updater = new Updater(ctx, stats); - if (updater.isThereAnythingToDo()) { - updater.update(); - ss.info(this, "Updated " + stats.updatedUris - + "URIs of PermissionSets on " + stats.updatedUsers - + "User Accounts, out of a total of " - + stats.allUserAccounts + " User Accounts."); - } else { - ss.info(this, "URIs of PermissionSets were up to date on all " - + stats.allUserAccounts + " User Accounts."); - } - } catch (Exception e) { - ss.fatal(this, "Failed to update URIs of PermissionSets " - + "on User Accounts", e); - } - } - - @Override - public void contextDestroyed(ServletContextEvent sce) { - // Nothing to tear down. - } - - // ---------------------------------------------------------------------- - // The Updater class - // ---------------------------------------------------------------------- - - private static class Updater { - private static final String OLD_ADMIN_URI = "http://permissionSet-50"; - private static final String OLD_CURATOR_URI = "http://permissionSet-5"; - private static final String OLD_EDITOR_URI = "http://permissionSet-4"; - private static final String OLD_SELF_EDITOR_URI = "http://permissionSet-1"; - private static final String NEW_ADMIN_URI = VITRO_AUTH + "ADMIN"; - private static final String NEW_CURATOR_URI = VITRO_AUTH + "CURATOR"; - private static final String NEW_EDITOR_URI = VITRO_AUTH + "EDITOR"; - private static final String NEW_SELF_EDITOR_URI = VITRO_AUTH - + "SELF_EDITOR"; - - private static final Map updateMap = buildUpdateMap(); - - private static Map buildUpdateMap() { - Map map = new HashMap(); - map.put(OLD_ADMIN_URI, NEW_ADMIN_URI); - map.put(OLD_CURATOR_URI, NEW_CURATOR_URI); - map.put(OLD_EDITOR_URI, NEW_EDITOR_URI); - map.put(OLD_SELF_EDITOR_URI, NEW_SELF_EDITOR_URI); - return Collections.unmodifiableMap(map); - } - - private final ServletContext ctx; - private final Stats stats; - private final UserAccountsDao userAccountsDao; - - private Journal journal; - - public Updater(ServletContext ctx, Stats stats) { - this.ctx = ctx; - this.stats = stats; - - WebappDaoFactory wadf = ModelAccess.on(ctx).getWebappDaoFactory(); - userAccountsDao = wadf.getUserAccountsDao(); - } - - /** - * If none of the existing Users have Permission Sets with the obsolete - * URIs, then we don't do anything. We don't even create a Journal. - */ - public boolean isThereAnythingToDo() { - Collection allUserAccounts = userAccountsDao - .getAllUserAccounts(); - stats.allUserAccounts = allUserAccounts.size(); - - for (UserAccount user : allUserAccounts) { - for (String psUri : user.getPermissionSetUris()) { - if (updateMap.keySet().contains(psUri)) { - return true; - } - } - } - return false; - } - - public void update() throws IOException { - journal = new Journal(ctx); - try { - for (UserAccount user : userAccountsDao.getAllUserAccounts()) { - updateUserAccount(user); - } - } finally { - journal.close(); - } - } - - private void updateUserAccount(UserAccount user) { - boolean updated = false; - List newUris = new ArrayList(); - - for (String oldUri : user.getPermissionSetUris()) { - if (updateMap.keySet().contains(oldUri)) { - String newUri = updateMap.get(oldUri); - newUris.add(newUri); - - updated = true; - stats.updatedUris++; - journal.noteUpdate(user, oldUri, newUri); - } else { - newUris.add(oldUri); - } - } - - if (updated) { - user.setPermissionSetUris(newUris); - userAccountsDao.updateUserAccount(user); - - stats.updatedUsers++; - } - } - - } - - // ---------------------------------------------------------------------- - // The Stats class - // ---------------------------------------------------------------------- - - private static class Stats { - int allUserAccounts; - int updatedUsers; - int updatedUris; - } - - // ---------------------------------------------------------------------- - // The Journal class - // ---------------------------------------------------------------------- - - private static class Journal { - private final File file; - private final PrintWriter w; - private int errorCount; - - Journal(ServletContext ctx) throws IOException { - String homeDirectoryPath = ConfigurationProperties.getBean(ctx) - .getProperty("vitro.home"); - if (homeDirectoryPath == null) { - throw new IllegalStateException( - "No value found for vitro.home"); - } - File homeDirectory = new File(homeDirectoryPath); - confirmIsDirectory(homeDirectory); - - File upgradeDirectory = createDirectory(homeDirectory, "upgrade/permissions"); - String filename = timestampedFilename("UpgradePermissionSetUris", - ".txt"); - this.file = new File(upgradeDirectory, filename); - - this.w = new PrintWriter(this.file); - } - - public String getPath() { - return file.getAbsolutePath(); - } - - public void note(String... notes) { - w.println(); - for (String note : notes) { - w.println("# " + note); - } - } - - public void noteUpdate(UserAccount user, String oldPermissionSetUri, - String newPermissionSetUri) { - note(String.format("For user %1$s, replaced '%2$s' with '%3$s'", - user.getUri(), oldPermissionSetUri, newPermissionSetUri)); - } - - public void close() { - w.println("upgrade complete with " + errorCount + " errors."); - w.close(); - } - - private void confirmIsDirectory(File home) { - if (!home.exists()) { - throw new IllegalStateException("Vitro home directory '" - + home.getPath() + "' does not exist."); - } - if (!home.isDirectory()) { - throw new IllegalStateException("Vitro home '" + home.getPath() - + "' is not a directory."); - } - if (!home.canWrite()) { - throw new IllegalStateException( - "Can't write to Vitro home directory '" - + home.getPath() + "'."); - } - } - - private File createDirectory(File home, String name) { - File newDir = new File(home, name); - if (!newDir.exists()) { - newDir.mkdirs(); - if (!newDir.exists()) { - throw new IllegalStateException( - "Failed to create the upgrade directory '" - + newDir.getPath() + "'"); - } - } - - if (!newDir.isDirectory()) { - throw new IllegalStateException("Upgrade directory '" - + newDir.getPath() + "' is not a directory."); - } - if (!newDir.canWrite()) { - throw new IllegalStateException( - "Can't write to Upgrade directory '" + newDir.getPath() - + "'."); - } - - return newDir; - } - - private String timestampedFilename(String prefix, String suffix) { - SimpleDateFormat sdf = new SimpleDateFormat( - "yyyy-MM-dd'T'HH-mm-sss"); - return prefix + "." + sdf.format(new Date()) + suffix; - } - } - -} diff --git a/webapp/web/WEB-INF/resources/startup_listeners.txt b/webapp/web/WEB-INF/resources/startup_listeners.txt index c33071954..c36f47a9f 100644 --- a/webapp/web/WEB-INF/resources/startup_listeners.txt +++ b/webapp/web/WEB-INF/resources/startup_listeners.txt @@ -35,8 +35,8 @@ edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorageSetup edu.cornell.mannlib.vitro.webapp.web.images.PlaceholderUtil$Setup -# Update the URIs on Permission Sets on UserAccounts from model (1.4) to 1.5. -edu.cornell.mannlib.vitro.webapp.servlet.setup.UpdatePermissionSetUris +# Some permissions were removed in release 1.7 +edu.cornell.mannlib.vitro.webapp.servlet.setup.RemoveObsoletePermissions edu.cornell.mannlib.vitro.webapp.servlet.setup.FileGraphSetup