Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import java.util.Arrays;
import java.util.Set;

import org.apache.commons.io.FileUtils;
import org.collectionspace.chain.csp.persistence.services.TenantSpec;
import org.collectionspace.chain.csp.persistence.services.TenantSpec.RemoteClient;
import org.collectionspace.chain.csp.schema.EmailData;
Expand All @@ -16,6 +17,7 @@
import org.collectionspace.chain.csp.schema.Group;
import org.collectionspace.chain.csp.schema.Instance;
import org.collectionspace.chain.csp.schema.Option;
import org.collectionspace.chain.csp.schema.PasswordComplexityData;
import org.collectionspace.chain.csp.schema.Record;
import org.collectionspace.chain.csp.schema.Repeat;
import org.collectionspace.chain.csp.schema.Spec;
Expand All @@ -31,7 +33,6 @@
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.commons.io.FileUtils;

public class ServiceBindingsGeneration {
private static final Logger log = LoggerFactory.getLogger(ServiceBindingsGeneration.class);
Expand Down Expand Up @@ -200,6 +201,8 @@ private String doServiceBindingsCommon(String serviceBindingVersion) {
// Set the bindings for email notifications
makeEmailBindings(ele);

makePasswordComplexityBindings(ele);

makeUiBindings(ele);

// add in <tenant:properties> if required
Expand Down Expand Up @@ -452,7 +455,6 @@ private void makeEmailBindings(Element tenantBindingElement) {
// into seconds; otherwise, ignore the 'daysvalid' field and use the configured 'tokenExpirationSeconds' value.
//
Element ele = passwordResetElement.addElement(new QName("tokenExpirationSeconds", nstenant));
Integer secondsValid = emailData.getTokenExpirationDays() * 60 * 60 * 24; // Convert days into seconds
ele.addText(emailData.getTokenExpirationSeconds().toString());
}

Expand All @@ -473,6 +475,39 @@ private void makeEmailBindings(Element tenantBindingElement) {
}
}

private void makePasswordComplexityBindings(Element tenantBindings) {
PasswordComplexityData passwordComplexityData = spec.getPasswordComplexityData();
if (passwordComplexityData != null && passwordComplexityData.isEnabled()) {
final var root = tenantBindings.addElement(new QName("passwordRequirementConfig", nstenant));

// passwordComplexity/enabled
root.addElement(new QName("enabled", nstenant))
.addText(String.valueOf(passwordComplexityData.isEnabled()));

// passwordComplexity/minLength
passwordComplexityData.getMinLength().ifPresent(minLength ->
root.addElement(new QName("minLength", nstenant))
.addText(String.valueOf(minLength))
);

// passwordComplexity/requireLowerCase
root.addElement(new QName("requireLowerCase", nstenant))
.addText(String.valueOf(passwordComplexityData.requireLowerCase()));

// passwordComplexity/requireUpperCase
root.addElement(new QName("requireUpperCase", nstenant))
.addText(String.valueOf(passwordComplexityData.requireUpperCase()));

// passwordComplexity/requireDigit
root.addElement(new QName("requireDigit", nstenant))
.addText(String.valueOf(passwordComplexityData.requireDigit()));

// passwordComplexity/requireLowerCase
root.addElement(new QName("requireSpecial", nstenant))
.addText(String.valueOf(passwordComplexityData.requireSpecial()));
}
}

private void makeUiBindings(Element tenantBindingElement) {
UiData uiData = spec.getUiData();
String baseUrl = (uiData != null) ? uiData.getBaseURL() : null;
Expand Down
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package org.collectionspace.chain.csp.schema;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

import org.collectionspace.chain.csp.config.ReadOnlySection;

public class PasswordComplexityData {
final boolean enabled;

final Integer minLength;
final boolean requireLowerCase;
final boolean requireUpperCase;
final boolean requireDigit;
final boolean requireSpecial;

public PasswordComplexityData(ReadOnlySection section) {
enabled = Boolean.parseBoolean((String) section.getValue("/enabled"));

minLength = parseIntFromSection(section, "/min-length");
requireLowerCase = Boolean.parseBoolean((String) section.getValue("/require-lower-case"));
requireUpperCase = Boolean.parseBoolean((String) section.getValue("/require-upper-case"));
requireDigit = Boolean.parseBoolean((String) section.getValue("/require-digit"));
requireSpecial = Boolean.parseBoolean((String) section.getValue("/require-special"));
}

private Integer parseIntFromSection(ReadOnlySection section, String path) {
final var asString = (String) section.getValue(path);
return asString == null ? null : Integer.parseInt(asString);
}

public boolean isEnabled() {
return enabled;
}

public boolean requireLowerCase() {
return requireLowerCase;
}

public boolean requireUpperCase() {
return requireUpperCase;
}

public boolean requireDigit() {
return requireDigit;
}

public boolean requireSpecial() {
return requireSpecial;
}

public Optional<Integer> getMinLength() {
return Optional.ofNullable(minLength);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ public class Spec implements CSP, Configurable {
private EmailData ed;
private AdminData adminData;
private UiData uiData;
private PasswordComplexityData passwordComplexityData;

@Override
public String getName() { return "schema"; }
Expand Down Expand Up @@ -114,6 +115,16 @@ public Object populate(Object parent, ReadOnlySection section) {
}
});

rules.addRule(SECTIONED, new String[] {"password-complexity"}, SECTION_PREFIX + "password-complexity", null,
new RuleTarget() {
@Override
public Object populate(Object parent, ReadOnlySection section) {
passwordComplexityData = new PasswordComplexityData(section);
return this;
}
});


rules.addRule(SECTIONED,new String[]{"ui"},SECTION_PREFIX+"ui",null,new RuleTarget(){
@Override
public Object populate(Object parent, ReadOnlySection section) {
Expand Down Expand Up @@ -445,6 +456,10 @@ public Object populate(Object parent, ReadOnlySection section) {

}

public PasswordComplexityData getPasswordComplexityData() {
return passwordComplexityData;
}

public EmailData getEmailData() { return ed.getEmailData(); }
public UiData getUiData() { return uiData != null ? uiData.getUiData() : null; }
public AdminData getAdminData() { return adminData.getAdminData(); }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ public Object populate(Object parent, ReadOnlySection milestone) throws Exceptio
String tenantId = (String)milestone.getValue("/tenantId");
String tenantName = (String)milestone.getValue("/tenantName");

RemoteClient remoteClient = tenantSpec.new RemoteClient(name, url, username, password, ssl, auth, tenantId, tenantName);
RemoteClient remoteClient = new TenantSpec.RemoteClient(name, url, username, password, ssl, auth, tenantId, tenantName);
tenantSpec.addRemoteClient(remoteClient);

return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public class TenantSpec {
private Set<String> defaultlanguages = new LinkedHashSet<String>();
private Set<String> defaultdateformats = new LinkedHashSet<String>();

public class RemoteClient {
public static class RemoteClient {
private String name;
private String url;
private String user;
Expand Down
29 changes: 1 addition & 28 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<properties>
<revision>9.0.0-SNAPSHOT</revision>
<cspace.services.version>${revision}</cspace.services.version>
<java.version>17</java.version>
<java.version>21</java.version>
<temp.war.location>${basedir}/tmp</temp.war.location>
<cspace.tool.csmake>csmake</cspace.tool.csmake>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
Expand Down Expand Up @@ -283,33 +283,6 @@
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<id>check-environment-vars</id>
<phase>validate</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<!-- <fail unless="${env.JEE_PORT}"
message="Required environment variable JEE_PORT has not been set. Use 8180 as a default value." /> -->
<property environment="env"></property>
<fail message="Failed to set JEE_PORT environment variable. Set it using 8180 as a default value.">
<condition>
<not>
<isset property="env.JEE_PORT"></isset>
</not>
</condition>
</fail>
</tasks>
</configuration>
</execution>
</executions>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
Expand Down
36 changes: 22 additions & 14 deletions tomcat-main/src/main/resources/defaults/settings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,23 @@
<password>Administrator</password>
<tenant>1</tenant>
<tenantname>core</tenantname>
<cookievalidformins>60</cookievalidformins>
<!--
termLists, autocomplete instance lists, specs, and schemas,
static UI elements, etc will cache for a month (60*60*24*30) by default
-->
<cookievalidformins>60</cookievalidformins>
<!--
termLists, autocomplete instance lists, specs, and schemas,
static UI elements, etc will cache for a month (60*60*24*30) by default
-->
<termlist-cache-timeout>2592000</termlist-cache-timeout>
<autocompletelist-cache-timeout>2592000</autocompletelist-cache-timeout>
<reportlist-cache-timeout>2592000</reportlist-cache-timeout>
<!-- This is for user-uploaded media, not static UI images -->
<!-- This is for user-uploaded media, not static UI images -->
<uploaded-media-cache-timeout>2592000</uploaded-media-cache-timeout>
<uispecschema-cache-timeout>2592000</uispecschema-cache-timeout>
<ui-html-cache-timeout>2592000</ui-html-cache-timeout>
<ui-css-cache-timeout>2592000</ui-css-cache-timeout>
<ui-js-cache-timeout>2592000</ui-js-cache-timeout>
<!-- This is for static UI images like icons, not uploaded images -->
<ui-media-cache-timeout>2592000</ui-media-cache-timeout>
<!-- This is for the message bundles properties -->
<ui-js-cache-timeout>2592000</ui-js-cache-timeout>
<!-- This is for static UI images like icons, not uploaded images -->
<ui-media-cache-timeout>2592000</ui-media-cache-timeout>
<!-- This is for the message bundles properties -->
<ui-props-cache-timeout>2592000</ui-props-cache-timeout>
</admin>
<email>
Expand All @@ -43,14 +43,22 @@
</token>
<subject>CollectionSpace Password reset request</subject>
<message>Hello {{greeting}},\n\r\n\rYou've started the process to reset your CollectionSpace account password. To finish resetting your password, go to the Reset Password page {{link}} on CollectionSpace.\n\r\n\rIf clicking the link doesn't work, copy and paste the following link into your browser address bar and click Go.\n\r\n\r{{link}}\n\r Thanks,\n\r\n\r CollectionSpace Administrator\n\r\n\rPlease do not reply to this email. This mailbox is not monitored and you will not receive a response. For assistance, contact your CollectionSpace Administrator directly.</message>
</passwordreset>
</passwordreset>
</email>
<password-complexity>
<enabled>true</enabled>
<min-length>6</min-length>
<require-lower-case>true</require-lower-case>
<require-upper-case>true</require-upper-case>
<require-digit>true</require-digit>
<require-special>true</require-special>
</password-complexity>
<persistence>
<service>
<url>http://localhost:@JEE_PORT@/cspace-services</url>
<config-tenant></config-tenant>
<config-bindings></config-bindings>
<ims-url>/collectionspace/tenant/core/</ims-url> <!-- XXX should be in separate IMS section -->
<config-tenant></config-tenant>
<config-bindings></config-bindings>
<ims-url>/collectionspace/tenant/core/</ims-url> <!-- XXX should be in separate IMS section -->
</service>
</persistence>
</settings>