Skip to content
Merged
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
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ tomcat-main/plugins/
tomcat-main/nb-configuration.xml
tomcat-main/nbactions-debug.xml
cspi-schema/dumpedTrees/
cspi-schema/logs/
*.bak
target/
.DS_Store
Expand All @@ -17,4 +18,4 @@ war-entry/tmp/
*.xlsx
.vscode
.factorypath
.flattened-pom.xml
.flattened-pom.xml
22 changes: 22 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,27 @@
# CollectionSpace Application Changelog

## 9.0.0

### Build

* Update to JDK 21

### Settings

* Add password complexity requirements to tenant settings.xml

### Acquisition

* Add alternative identifier group `alternativeIdentifierGroupList/alternativeIdentifierGroup`

### CollectionObject

* Add home location group `homeLocationGroupList/homeLocationGroup`

### Media

* Add repeatable field `mediaPriorityList/mediaPriority`

## 8.3.0

### Authorities
Expand Down
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/requireSpecial
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package org.collectionspace.chain.csp.schema;

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
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.Security;
import java.util.Date;
import java.util.Properties;

Expand Down Expand Up @@ -93,7 +92,6 @@ private Boolean doEmail(String csid, String emailparam, Request in, JSONObject u
else{
recipients[0] = ed.getToAddress();
}
Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
boolean debug = false;

Properties props = new Properties();
Expand Down Expand Up @@ -491,4 +489,4 @@ public void run(Object in, String[] tail) throws UIException {

public void configure() throws ConfigException {}
public void configure(WebUI ui,Spec spec) {}
}
}
45 changes: 4 additions & 41 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@
<name>Root</name>

<properties>
<revision>8.3.1</revision>
<revision>9.0.0-RC.2</revision>
<cspace.services.version>${revision}</cspace.services.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 @@ -45,7 +46,6 @@
<module>cspi-installation</module>

<module>tomcat-main</module>
<module>war-entry</module>
</modules>

<repositories>
Expand Down Expand Up @@ -230,19 +230,9 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<version>3.15.0</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<optimize>true</optimize>
</configuration>
</plugin>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>6.1.26</version>
<configuration>
<contextPath>chain</contextPath>
<release>${java.version}</release>
</configuration>
</plugin>
</plugins>
Expand Down Expand Up @@ -293,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
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@
<field id="comment" datatype="largetext" />
</repeat>
<field id="computedCurrentLocation" authref-in-services="true" />
<repeat id="homeLocationGroupList/homeLocationGroup">
<field id="homeLocation" autocomplete="true" />
<field id="homeLocationNote" />
</repeat>

<repeat id="publishToList" services-type-anonymous="false">
<field id="publishTo" autocomplete="true" ui-type="enum" />
Expand All @@ -130,6 +134,10 @@
<field id="inventoryStatus" autocomplete="true" ui-type="enum" />
</repeat>

<repeat id="mediaPriorityList" services-type-anonymous="false">
<field id="mediaPriority" />
</repeat>

<repeat id="titleGroupList/titleGroup">
<field id="title" mini="list" />
<field id="titleLanguage" autocomplete="true" ui-type="enum" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@

<section id="acquisitionInformation">
<field id="acquisitionReferenceNumber" mini="number,list" />
<repeat id="alternativeIdentifierGroupList/alternativeIdentifierGroup">
<field id="alternativeIdentifier" />
<field id="alternativeIdentifierNote" />
</repeat>
<field id="accessionDateGroup" ui-type="groupfield/structureddate">
</field>
<field id="acquisitionAuthorizer" autocomplete="true" />
Expand Down
Loading