From fbd1ed7b28b42ea3b738a36922aa4a19c7fbdd4f Mon Sep 17 00:00:00 2001 From: Michael Ritter Date: Thu, 4 Jan 2024 22:33:25 -0700 Subject: [PATCH] DRYD-1268: UCB Misc/QoL Contribs (#384) Co-authored-by: Richard Millet --- .gitignore | 4 ++ .../src/main/webapp/META-INF/context.xml | 2 +- .../spring/CSpaceUserDetailsService.java | 27 ++--------- .../spring/SpringAuthNContext.java | 4 +- services/authorization-mgt/import/build.xml | 2 +- .../services/common/EmailUtil.java | 2 +- .../services/common/ServiceMain.java | 1 + .../AuthorizationCommon.java | 2 +- .../context/AbstractServiceContextImpl.java | 2 +- .../common/context/ServiceBindingUtils.java | 14 +++--- .../common/relation/RelationResource.java | 1 + .../relation/nuxeo/RelationConstants.java | 4 +- .../services/common/storage/JDBCTools.java | 37 +++++---------- .../client/java/NuxeoConnectorEmbedded.java | 35 ++++++++++++-- .../common/config/PropertyItemUtils.java | 47 +++++++++---------- 15 files changed, 94 insertions(+), 90 deletions(-) diff --git a/.gitignore b/.gitignore index c2a6a58d8..db5b3c75a 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,7 @@ m2-settings.xml *.log.* cspace-app-perflog.csv .flattened-pom.xml +bin +*.diff +logged_schemas +logs diff --git a/services/JaxRsServiceProvider/src/main/webapp/META-INF/context.xml b/services/JaxRsServiceProvider/src/main/webapp/META-INF/context.xml index 92518bba5..e17f81759 100644 --- a/services/JaxRsServiceProvider/src/main/webapp/META-INF/context.xml +++ b/services/JaxRsServiceProvider/src/main/webapp/META-INF/context.xml @@ -8,7 +8,7 @@ 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. --> - diff --git a/services/authentication/service/src/main/java/org/collectionspace/authentication/spring/CSpaceUserDetailsService.java b/services/authentication/service/src/main/java/org/collectionspace/authentication/spring/CSpaceUserDetailsService.java index 754c588f8..a0974dc77 100644 --- a/services/authentication/service/src/main/java/org/collectionspace/authentication/spring/CSpaceUserDetailsService.java +++ b/services/authentication/service/src/main/java/org/collectionspace/authentication/spring/CSpaceUserDetailsService.java @@ -15,28 +15,6 @@ * https://source.collectionspace.org/collection-space/LICENSE.txt - * 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. - *//** - * This document is a part of the source code and related artifacts - * for CollectionSpace, an open source collections management system - * for museums and related institutions: - - * http://www.collectionspace.org - * http://wiki.collectionspace.org - - * Copyright 2009 University of California at Berkeley - - * Licensed under the Educational Community License (ECL), Version 2.0. - * You may not use this file except in compliance with this License. - - * You may obtain a copy of the ECL 2.0 License at - - * https://source.collectionspace.org/collection-space/LICENSE.txt - * 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. @@ -84,6 +62,11 @@ public class CSpaceUserDetailsService implements UserDetailsService { salt = realm.getSalt(username); requireSSO = realm.isRequireSSO(username); tenants = getTenants(username); + if (tenants == null || tenants.isEmpty()) { + String msg = String.format("The account '%s' is not associated with any tenants. " + + "Please contact your administrator.", username); + throw new AccountException(msg); + } grantedAuthorities = getAuthorities(username); } catch (AccountNotFoundException e) { diff --git a/services/authentication/service/src/main/java/org/collectionspace/authentication/spring/SpringAuthNContext.java b/services/authentication/service/src/main/java/org/collectionspace/authentication/spring/SpringAuthNContext.java index 309f856ba..5550dc70c 100644 --- a/services/authentication/service/src/main/java/org/collectionspace/authentication/spring/SpringAuthNContext.java +++ b/services/authentication/service/src/main/java/org/collectionspace/authentication/spring/SpringAuthNContext.java @@ -83,7 +83,9 @@ public class SpringAuthNContext implements AuthNContext { CSpaceUser cspaceUser = getUser(); if (cspaceUser != null) { - result = getCurrentTenant().getId(); + if (getCurrentTenant() != null) { + result = getCurrentTenant().getId(); + } } else { String username = getUserId(); if (username.equals(AuthN.ANONYMOUS_USER)) { diff --git a/services/authorization-mgt/import/build.xml b/services/authorization-mgt/import/build.xml index b0b53a92e..321097576 100644 --- a/services/authorization-mgt/import/build.xml +++ b/services/authorization-mgt/import/build.xml @@ -111,7 +111,7 @@ - + diff --git a/services/common/src/main/java/org/collectionspace/services/common/EmailUtil.java b/services/common/src/main/java/org/collectionspace/services/common/EmailUtil.java index 7ad5de4ae..f4e5cf027 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/EmailUtil.java +++ b/services/common/src/main/java/org/collectionspace/services/common/EmailUtil.java @@ -28,7 +28,7 @@ public class EmailUtil { public static void main(String [] args) { String username = "collectionspace.lyrasis@gmail.com"; - String password = "CSpace11-GG"; + String password = "bogus_password"; String recipient = "remillet@gmail.com"; Properties props = new Properties(); diff --git a/services/common/src/main/java/org/collectionspace/services/common/ServiceMain.java b/services/common/src/main/java/org/collectionspace/services/common/ServiceMain.java index 0ce3d507c..2b9604064 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/ServiceMain.java +++ b/services/common/src/main/java/org/collectionspace/services/common/ServiceMain.java @@ -163,6 +163,7 @@ public class ServiceMain { //celebrate success initFailed = false; } catch (Exception e) { + newInstance.release(); // attempt to release resources acquired during initialization attempt instance = null; if (e instanceof RuntimeException) { throw (RuntimeException) e; diff --git a/services/common/src/main/java/org/collectionspace/services/common/authorization_mgt/AuthorizationCommon.java b/services/common/src/main/java/org/collectionspace/services/common/authorization_mgt/AuthorizationCommon.java index 09545a4dd..91c920708 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/authorization_mgt/AuthorizationCommon.java +++ b/services/common/src/main/java/org/collectionspace/services/common/authorization_mgt/AuthorizationCommon.java @@ -1304,7 +1304,7 @@ public class AuthorizationCommon { } if (result.contains("{{link}}") == false) { - logger.warn("The tenant's password reset message does not contain a required '{{link}}' marker."); + logger.error("The tenant's password reset message does not contain a required '{{link}}' marker."); result = null; } diff --git a/services/common/src/main/java/org/collectionspace/services/common/context/AbstractServiceContextImpl.java b/services/common/src/main/java/org/collectionspace/services/common/context/AbstractServiceContextImpl.java index 25caaab68..7921a8e5d 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/context/AbstractServiceContextImpl.java +++ b/services/common/src/main/java/org/collectionspace/services/common/context/AbstractServiceContextImpl.java @@ -626,7 +626,7 @@ public abstract class AbstractServiceContextImpl // to specify sort ordering, pagination, etc. // MultivaluedMap queryParameters = this.getQueryParams(); - if (queryParameters != null) { + if (queryParameters != null && !queryParameters.isEmpty()) { docFilter.setSortOrder(queryParameters); docFilter.setPagination(queryParameters); String workflowWhereClause = buildWorkflowWhereClause(queryParameters); diff --git a/services/common/src/main/java/org/collectionspace/services/common/context/ServiceBindingUtils.java b/services/common/src/main/java/org/collectionspace/services/common/context/ServiceBindingUtils.java index 219a1880f..9404590b1 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/context/ServiceBindingUtils.java +++ b/services/common/src/main/java/org/collectionspace/services/common/context/ServiceBindingUtils.java @@ -116,12 +116,14 @@ public class ServiceBindingUtils { String propName, boolean qualify) { List values = new ArrayList(); ServiceObjectType objectType = serviceBinding.getObject(); - List objectPartTypes = objectType.getPart(); - for (ObjectPartType objectPartType : objectPartTypes) { - List propNodeList = objectPartType.getProperties(); - PropertyItemUtils.getPropertyValuesByNameInNodeList(propNodeList, - propName, (qualify?(objectPartType.getLabel()+":"):null), values); - } + if (objectType != null) { + List objectPartTypes = objectType.getPart(); + for (ObjectPartType objectPartType : objectPartTypes) { + List propNodeList = objectPartType.getProperties(); + PropertyItemUtils.getPropertyValuesByNameInNodeList(propNodeList, propName, + (qualify ? objectPartType.getLabel() + ":" : null), values); + } + } return values; } diff --git a/services/common/src/main/java/org/collectionspace/services/common/relation/RelationResource.java b/services/common/src/main/java/org/collectionspace/services/common/relation/RelationResource.java index 46bf5587b..503b0826e 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/relation/RelationResource.java +++ b/services/common/src/main/java/org/collectionspace/services/common/relation/RelationResource.java @@ -92,6 +92,7 @@ public class RelationResource extends NuxeoBasedResource { return this.getList(parentCtx, parentCtx.getUriInfo()); } + @Override public RelationsCommonList getList(ServiceContext parentCtx, UriInfo uriInfo) { MultivaluedMap queryParams = uriInfo.getQueryParameters(); diff --git a/services/common/src/main/java/org/collectionspace/services/common/relation/nuxeo/RelationConstants.java b/services/common/src/main/java/org/collectionspace/services/common/relation/nuxeo/RelationConstants.java index 798da03d2..3f5d5a809 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/relation/nuxeo/RelationConstants.java +++ b/services/common/src/main/java/org/collectionspace/services/common/relation/nuxeo/RelationConstants.java @@ -54,6 +54,6 @@ public class RelationConstants { public final static String TYPE_SCHEMA_NAME = COMMON_SCHEMA_NAME; public final static String TYPE_FIELD_NAME = IRelationsManager.RELATIONSHIP_TYPE; - public final static String AFFECTS_TYPE = RelationshipType.AFFECTS.toString(); - public final static String BROADER_TYPE = RelationshipType.HAS_BROADER.toString(); + public final static String AFFECTS_TYPE = RelationshipType.AFFECTS.value(); + public final static String BROADER_TYPE = RelationshipType.HAS_BROADER.value(); } diff --git a/services/common/src/main/java/org/collectionspace/services/common/storage/JDBCTools.java b/services/common/src/main/java/org/collectionspace/services/common/storage/JDBCTools.java index 311bf37cb..0c3e0adce 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/storage/JDBCTools.java +++ b/services/common/src/main/java/org/collectionspace/services/common/storage/JDBCTools.java @@ -594,47 +594,32 @@ public class JDBCTools { /** * Create a database user, if that user doesn't already exist. * - * @param conn a database connection. + * @param dataSourceName the datasource for the connection + * @param repositoryName the repository name for the connection + * @param cspaceInstanceId the cspace instance id for the connection * @param dbType a database product type. * @param username the name of the database user to create. * @param userPW the initial password for that database user. */ public static void createNewDatabaseUser(String dataSourceName, String repositoryName, String cspaceInstanceId, DatabaseProductType dbType, String username, String userPW) throws Exception { - Statement stmt = null; - Connection conn = null; if (dbType != DatabaseProductType.POSTGRESQL) { throw new UnsupportedOperationException("createNewDatabaseUser only supports PostgreSQL"); } - try { + + String sql = null; + try (Connection conn = getConnection(dataSourceName, repositoryName, cspaceInstanceId); + Statement stmt = conn.createStatement()) { if (hasDatabaseUser(dataSourceName, repositoryName, cspaceInstanceId, dbType, username)) { - if (logger.isDebugEnabled()) { - logger.debug("User: " + username + " already exists."); - } + logger.debug("User: {} already exists.", username); } else { - conn = getConnection(dataSourceName, repositoryName, cspaceInstanceId); - stmt = conn.createStatement(); - String sql = "CREATE ROLE " + username + " WITH PASSWORD '" + userPW + "' LOGIN"; + sql = "CREATE ROLE " + username + " WITH PASSWORD '" + userPW + "' LOGIN"; stmt.executeUpdate(sql); - if (logger.isDebugEnabled()) { - logger.debug("Created User: " + username); - } + logger.debug("Created User: {}", username); } } catch (Exception e) { - logger.error("createNewDatabaseUser failed on exception: " + e.getLocalizedMessage()); + logger.error("createNewDatabaseUser failed with exception:", e); throw e; - } finally { - try { - if (stmt != null) { - stmt.close(); - } - if (conn != null) { - conn.close(); - } - } catch (SQLException sqle) { - // nothing we can do here except log - logger.warn("SQL Exception when closing statement/connection: " + sqle.getLocalizedMessage()); - } } } diff --git a/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/NuxeoConnectorEmbedded.java b/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/NuxeoConnectorEmbedded.java index 9f15b782b..0fca95e1c 100644 --- a/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/NuxeoConnectorEmbedded.java +++ b/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/NuxeoConnectorEmbedded.java @@ -5,6 +5,12 @@ import java.io.IOException; import java.util.Hashtable; import java.util.Iterator; +import java.sql.Driver; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.util.Enumeration; + +import javax.management.JMException; import javax.servlet.ServletContext; import org.apache.catalina.util.ServerInfo; @@ -43,6 +49,7 @@ public class NuxeoConnectorEmbedded { private volatile boolean initialized = false; // use volatile for lazy // initialization in // singleton + private ClassLoader classLoader; public NuxeoFrameworkBootstrap fb; private ServletContext servletContext; private RepositoryClientConfigType repositoryClientConfig; @@ -112,14 +119,14 @@ public class NuxeoConnectorEmbedded { + nuxeoHomeDir.getCanonicalPath()); } - ClassLoader cl = NuxeoConnectorEmbedded.class.getClassLoader(); + classLoader = NuxeoConnectorEmbedded.class.getClassLoader(); - fb = new NuxeoFrameworkBootstrap(cl, nuxeoHomeDir); + fb = new NuxeoFrameworkBootstrap(classLoader, nuxeoHomeDir); fb.setHostName("Tomcat"); fb.setHostVersion(ServerInfo.getServerNumber()); fb.initialize(); - fb.start(new MutableClassLoaderDelegate(cl)); + fb.start(new MutableClassLoaderDelegate(classLoader)); // Test to see if we can connect to the default repository boolean transactionStarted = false; @@ -133,7 +140,7 @@ public class NuxeoConnectorEmbedded { try { Repository defaultRepo = Framework.getService(RepositoryManager.class).getDefaultRepository(); coreSession = CoreInstance.openCoreSession(defaultRepo.getName(), new SystemPrincipal(null)); - } catch (Throwable t) { + } catch (Throwable t) { logger.error(t.getMessage()); throw new RuntimeException("Could not start the Nuxeo EP Framework", t); } finally { @@ -147,6 +154,25 @@ public class NuxeoConnectorEmbedded { } } + private void stopNuxeoEP() { + try { + fb.stop(new MutableClassLoaderDelegate(classLoader)); + Enumeration drivers = DriverManager.getDrivers(); + while (drivers.hasMoreElements()) { + Driver driver = drivers.nextElement(); + try { + DriverManager.deregisterDriver(driver); + logger.info("Deregister JDBC driver: {}", driver); + } catch (SQLException e) { + logger.error("Error deregistering JDBC driver {}", driver, e); + } + } + } catch (IllegalArgumentException | ReflectiveOperationException | JMException e) { + logger.error("CollectionSpace was unable to shutdown Nuxeo cleanly.", e); + } + } + + /** * release releases resources occupied by Nuxeo remoting client runtime * @@ -156,6 +182,7 @@ public class NuxeoConnectorEmbedded { if (initialized == true) { try { client.tryDisconnect(); + stopNuxeoEP(); } catch (Exception e) { logger.error("Failed to disconnect Nuxeo connection.", e); throw e; diff --git a/services/config/src/main/java/org/collectionspace/services/common/config/PropertyItemUtils.java b/services/config/src/main/java/org/collectionspace/services/common/config/PropertyItemUtils.java index cf93b2db5..e9567abe8 100644 --- a/services/config/src/main/java/org/collectionspace/services/common/config/PropertyItemUtils.java +++ b/services/config/src/main/java/org/collectionspace/services/common/config/PropertyItemUtils.java @@ -96,37 +96,36 @@ public class PropertyItemUtils { return getPropertyValuesByName(propItems, propName, qualPrefix, null); } - /** - * @param propNodeList the Item list to search for the named property - * @param propName the name of the property of interest - * @param qualPrefix a namespace qualifier prefix (with ':') to prepend, or null - * @param values and existing list to append values to. If null, a new one will be created. - * @return values, or that is null, a new List of string values found for the named property - */ - public static List getPropertyValuesByName( - List propItems, String propName, String qualPrefix, - List values ) { - - if (values == null) { - values = new ArrayList(); - } + /** + * @param propName the name of the property of interest + * @param qualPrefix a namespace qualifier prefix (with ':') to prepend, or null + * @param values and existing list to append values to. If null, a new one will be created. + * @return values, or that is null, a new List of string values found for the named property + */ + public static List getPropertyValuesByName( + List propItems, String propName, String qualPrefix, + List values ) { + + if (values == null) { + values = new ArrayList(); + } - if (propItems != null) { - for (PropertyItemType propItem : propItems) { - if (propName.equals(propItem.getKey())) { - // TODO - the trim() belongs here, not down a few lines. - String value = propItem.getValue(); + if (propItems != null) { + for (PropertyItemType propItem : propItems) { + if (propName.equals(propItem.getKey())) { + // TODO - the trim() belongs here, not down a few lines. + String value = propItem.getValue(); - if (value != null) { - values.add((qualPrefix != null) ? (qualPrefix + value) : value.trim()); - } + if (value != null) { + values.add((qualPrefix != null) ? (qualPrefix + value) : value.trim()); } } } - - return values; } + return values; + } + /** * @param propNodeList the wrapping list node from JAXB * @param propName the property to set -- 2.47.3