[java-sp-server] branch main updated: Freshen up code and check in some WIP on config.
Scott Cantor
cantor.2 at osu.edu
Tue Jan 31 20:50:52 UTC 2023
This is an automated email from the git hooks/post-receive script.
scantor pushed a commit to branch main
in repository java-sp-server.
View the commit online:
http://git.shibboleth.net/view/?p=java-sp-server.git;a=commit;h=2ce4e34671336a5647d263993cc99f62aa8f88b3
The following commit(s) were added to refs/heads/main by this push:
new 2ce4e34 Freshen up code and check in some WIP on config.
2ce4e34 is described below
commit 2ce4e34671336a5647d263993cc99f62aa8f88b3
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Tue Jan 31 15:50:46 2023 -0500
Freshen up code and check in some WIP on config.
---
pom.xml | 4 +-
sp-bom/pom.xml | 14 ++-
.../net/shibboleth/sp/conf/global-system.xml | 2 -
sp-saml-api/.checkstyle | 10 ++
sp-saml-api/.gitignore | 1 +
{sp-session-api => sp-saml-api}/pom.xml | 15 ++-
sp-saml-impl/.checkstyle | 10 ++
sp-saml-impl/.gitignore | 1 +
{sp-session-api => sp-saml-impl}/pom.xml | 8 +-
.../AbstractConditionalProfileConfiguration.java | 68 +++++++++++++
.../sp/config/AbstractProfileConfiguration.java | 104 +++++++++++++++++++
.../net/shibboleth/sp/config/AssertingParty.java | 55 ++++++++++
.../sp/config/ConditionalProfileConfiguration.java | 38 +++++++
.../shibboleth/sp/config/ProfileConfiguration.java | 42 ++++++++
.../net/shibboleth/sp/config/package-info.java | 21 ++++
.../src/main/java/net/shibboleth/sp/ddf/DDF.java | 111 ++++++++++++++++-----
.../sp/ddf/RemotedHttpServletRequest.java | 57 ++++++++---
.../sp/ddf/RemotedHttpServletResponse.java | 57 ++++++-----
.../java/net/shibboleth/sp/ddf/DDFSupportTest.java | 6 +-
.../test/java/net/shibboleth/sp/ddf/DDFTest.java | 17 ++--
.../sp/ddf/RemotedHttpServletRequestTest.java | 1 +
.../sp/ddf/RemotedHttpServletResponseTest.java | 1 +
sp-server-impl/pom.xml | 2 +-
sp-session-api/pom.xml | 7 ++
.../sp/session/AbstractRemotableSPSession.java | 98 ++++++++++++++++++
.../shibboleth/sp/session/RemotableSPSession.java | 38 +++++++
.../java/net/shibboleth/sp/session/SPSession.java | 105 +++++++++++++++++++
.../shibboleth/sp/session/SessionException.java | 61 +++++++++++
.../net/shibboleth/sp/session/package-info.java | 21 ++++
29 files changed, 887 insertions(+), 88 deletions(-)
diff --git a/pom.xml b/pom.xml
index 10de363..4f58701 100644
--- a/pom.xml
+++ b/pom.xml
@@ -20,7 +20,7 @@
<shib-metadata.version>5.0.0-SNAPSHOT</shib-metadata.version>
<opensaml.version>5.0.0-SNAPSHOT</opensaml.version>
<shib-shared.version>9.0.0-SNAPSHOT</shib-shared.version>
- <spring-int.version>6.0.0-RC1</spring-int.version>
+ <spring-int.version>6.0.1</spring-int.version>
<checkstyle.configLocation>${project.basedir}/resources/checkstyle.xml</checkstyle.configLocation>
</properties>
@@ -62,6 +62,8 @@
<module>sp-bom</module>
<module>sp-conf</module>
<module>sp-conf-impl</module>
+ <module>sp-saml-api</module>
+ <module>sp-saml-impl</module>
<module>sp-server-api</module>
<module>sp-server-impl</module>
<module>sp-session-api</module>
diff --git a/sp-bom/pom.xml b/sp-bom/pom.xml
index 6d5a4a7..9ddf6af 100644
--- a/sp-bom/pom.xml
+++ b/sp-bom/pom.xml
@@ -17,6 +17,11 @@
<dependencyManagement>
<dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>sp-saml-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>sp-server-api</artifactId>
@@ -30,12 +35,17 @@
<dependency>
<groupId>${project.groupId}</groupId>
- <artifactId>idp-server-impl</artifactId>
+ <artifactId>sp-saml-impl</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>sp-server-impl</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
- <artifactId>idp-session-impl</artifactId>
+ <artifactId>sp-session-impl</artifactId>
<version>${project.version}</version>
</dependency>
diff --git a/sp-conf-impl/src/main/resources/net/shibboleth/sp/conf/global-system.xml b/sp-conf-impl/src/main/resources/net/shibboleth/sp/conf/global-system.xml
index f6e954d..3810a1c 100644
--- a/sp-conf-impl/src/main/resources/net/shibboleth/sp/conf/global-system.xml
+++ b/sp-conf-impl/src/main/resources/net/shibboleth/sp/conf/global-system.xml
@@ -23,8 +23,6 @@
<bean class="net.shibboleth.shared.spring.config.BooleanToPredicateConverter" />
<bean class="net.shibboleth.shared.spring.config.StringBooleanToPredicateConverter" />
<bean class="net.shibboleth.shared.spring.config.StringToResourceConverter" />
- <bean class="net.shibboleth.shared.spring.config.FunctionToFunctionConverter" />
- <bean class="net.shibboleth.shared.spring.config.PredicateToPredicateConverter" />
<bean class="net.shibboleth.shared.spring.config.StringToDurationConverter" />
<bean class="net.shibboleth.shared.spring.config.StringToPeriodConverter" />
</set>
diff --git a/sp-saml-api/.checkstyle b/sp-saml-api/.checkstyle
new file mode 100644
index 0000000..5bae456
--- /dev/null
+++ b/sp-saml-api/.checkstyle
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<fileset-config file-format-version="1.2.0" simple-config="true" sync-formatter="false">
+ <local-check-config name="Shibboleth Checkstyle" location="/java-sp-server/resources/checkstyle.xml" type="project" description="">
+ <additional-data name="protect-config-file" value="false"/>
+ </local-check-config>
+ <fileset name="all" enabled="true" check-config-name="Shibboleth Checkstyle" local="true">
+ <file-match-pattern match-pattern="." include-pattern="true"/>
+ </fileset>
+</fileset-config>
diff --git a/sp-saml-api/.gitignore b/sp-saml-api/.gitignore
new file mode 100644
index 0000000..b83d222
--- /dev/null
+++ b/sp-saml-api/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/sp-session-api/pom.xml b/sp-saml-api/pom.xml
similarity index 76%
copy from sp-session-api/pom.xml
copy to sp-saml-api/pom.xml
index c064e97..268dfed 100644
--- a/sp-session-api/pom.xml
+++ b/sp-saml-api/pom.xml
@@ -9,18 +9,25 @@
<version>0.0.1-SNAPSHOT</version>
</parent>
- <artifactId>sp-session-api</artifactId>
- <description>SP Session API.</description>
- <name>Shibboleth SP :: Processing Hub :: Session API</name>
+ <artifactId>sp-saml-api</artifactId>
+ <description>SP SAML API.</description>
+ <name>Shibboleth SP :: Processing Hub :: SAML API</name>
<packaging>jar</packaging>
<properties>
<checkstyle.configLocation>${project.basedir}/../resources/checkstyle.xml</checkstyle.configLocation>
- <automatic.module.name>net.shibboleth.sp.session</automatic.module.name>
+ <automatic.module.name>net.shibboleth.sp.saml</automatic.module.name>
</properties>
<dependencies>
<!-- Compile dependencies -->
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>sp-server-api</artifactId>
+ <version>${project.version}</version>
+ <scope>compile</scope>
+ </dependency>
+
<dependency>
<groupId>net.shibboleth</groupId>
<artifactId>shib-attribute-api</artifactId>
diff --git a/sp-saml-impl/.checkstyle b/sp-saml-impl/.checkstyle
new file mode 100644
index 0000000..5bae456
--- /dev/null
+++ b/sp-saml-impl/.checkstyle
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<fileset-config file-format-version="1.2.0" simple-config="true" sync-formatter="false">
+ <local-check-config name="Shibboleth Checkstyle" location="/java-sp-server/resources/checkstyle.xml" type="project" description="">
+ <additional-data name="protect-config-file" value="false"/>
+ </local-check-config>
+ <fileset name="all" enabled="true" check-config-name="Shibboleth Checkstyle" local="true">
+ <file-match-pattern match-pattern="." include-pattern="true"/>
+ </fileset>
+</fileset-config>
diff --git a/sp-saml-impl/.gitignore b/sp-saml-impl/.gitignore
new file mode 100644
index 0000000..b83d222
--- /dev/null
+++ b/sp-saml-impl/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/sp-session-api/pom.xml b/sp-saml-impl/pom.xml
similarity index 85%
copy from sp-session-api/pom.xml
copy to sp-saml-impl/pom.xml
index c064e97..76e23c1 100644
--- a/sp-session-api/pom.xml
+++ b/sp-saml-impl/pom.xml
@@ -9,14 +9,14 @@
<version>0.0.1-SNAPSHOT</version>
</parent>
- <artifactId>sp-session-api</artifactId>
- <description>SP Session API.</description>
- <name>Shibboleth SP :: Processing Hub :: Session API</name>
+ <artifactId>sp-saml-impl</artifactId>
+ <description>SP SAML Implememntation.</description>
+ <name>Shibboleth SP :: Processing Hub :: SAML Implementation</name>
<packaging>jar</packaging>
<properties>
<checkstyle.configLocation>${project.basedir}/../resources/checkstyle.xml</checkstyle.configLocation>
- <automatic.module.name>net.shibboleth.sp.session</automatic.module.name>
+ <automatic.module.name>net.shibboleth.sp.saml.impl</automatic.module.name>
</properties>
<dependencies>
diff --git a/sp-server-api/src/main/java/net/shibboleth/sp/config/AbstractConditionalProfileConfiguration.java b/sp-server-api/src/main/java/net/shibboleth/sp/config/AbstractConditionalProfileConfiguration.java
new file mode 100644
index 0000000..146da74
--- /dev/null
+++ b/sp-server-api/src/main/java/net/shibboleth/sp/config/AbstractConditionalProfileConfiguration.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You 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 net.shibboleth.sp.config;
+
+import java.util.function.Predicate;
+
+import javax.annotation.Nonnull;
+
+import net.shibboleth.shared.annotation.ParameterName;
+import net.shibboleth.shared.annotation.constraint.NotEmpty;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.logic.PredicateSupport;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+/**
+ * Base class for {@link ConditionalProfileConfiguration} implementations.
+ *
+ * @since 3.4.0
+ */
+public abstract class AbstractConditionalProfileConfiguration extends AbstractProfileConfiguration
+ implements ConditionalProfileConfiguration {
+
+ /** Activation condition. */
+ @Nonnull private Predicate<ProfileRequestContext> activationCondition;
+
+ /**
+ * Constructor.
+ *
+ * @param id ID of the communication profile, never null or empty
+ */
+ public AbstractConditionalProfileConfiguration(@Nonnull @NotEmpty @ParameterName(name="id") final String id) {
+ super(id);
+
+ activationCondition = PredicateSupport.alwaysTrue();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ @Nonnull public Predicate<ProfileRequestContext> getActivationCondition() {
+ return activationCondition;
+ }
+
+ /**
+ * Set an activation condition to control this profile.
+ *
+ * @param condition condition to apply
+ */
+ public void setActivationCondition(@Nonnull final Predicate<ProfileRequestContext> condition) {
+ activationCondition = Constraint.isNotNull(condition, "Activation condition cannot be null");
+ }
+
+}
\ No newline at end of file
diff --git a/sp-server-api/src/main/java/net/shibboleth/sp/config/AbstractProfileConfiguration.java b/sp-server-api/src/main/java/net/shibboleth/sp/config/AbstractProfileConfiguration.java
new file mode 100644
index 0000000..9b7567a
--- /dev/null
+++ b/sp-server-api/src/main/java/net/shibboleth/sp/config/AbstractProfileConfiguration.java
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You 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 net.shibboleth.sp.config;
+
+import java.util.Objects;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import net.shibboleth.shared.annotation.ParameterName;
+import net.shibboleth.shared.annotation.constraint.NotEmpty;
+import net.shibboleth.shared.component.AbstractIdentifiableInitializableComponent;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.logic.FunctionSupport;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.opensaml.security.config.SecurityConfiguration;
+
+/** Base class for {@link ProfileConfiguration} implementations. */
+public abstract class AbstractProfileConfiguration extends AbstractIdentifiableInitializableComponent
+ implements ProfileConfiguration {
+
+ /** Lookup function to supply securityConfiguration property. */
+ @Nonnull private Function<ProfileRequestContext,SecurityConfiguration> securityConfigurationLookupStrategy;
+
+ /**
+ * Constructor.
+ *
+ * @param id ID of the communication profile, never null or empty
+ */
+ public AbstractProfileConfiguration(@Nonnull @NotEmpty @ParameterName(name="id") final String id) {
+ setId(id);
+ securityConfigurationLookupStrategy = FunctionSupport.constant(null);
+ }
+
+ /** {@inheritDoc} */
+ @Nullable public SecurityConfiguration getSecurityConfiguration(
+ @Nullable final ProfileRequestContext profileRequestContext) {
+ return securityConfigurationLookupStrategy.apply(profileRequestContext);
+ }
+
+ /**
+ * Sets the security configuration for this profile.
+ *
+ * @param configuration security configuration for this profile
+ */
+ public void setSecurityConfiguration(@Nullable final SecurityConfiguration configuration) {
+ securityConfigurationLookupStrategy = FunctionSupport.constant(configuration);
+ }
+
+ /**
+ * Set a lookup strategy for the security configuration.
+ *
+ * @param strategy lookup strategy
+ *
+ * @since 3.3.0
+ */
+ public void setSecurityConfigurationLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext,SecurityConfiguration> strategy) {
+ securityConfigurationLookupStrategy = Constraint.isNotNull(strategy, "Lookup strategy cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public int hashCode() {
+ return getId().hashCode();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj == null) {
+ return false;
+ }
+
+ if (!(obj instanceof AbstractProfileConfiguration)) {
+ return false;
+ }
+
+ final AbstractProfileConfiguration other = (AbstractProfileConfiguration) obj;
+ return Objects.equals(getId(), other.getId());
+ }
+
+}
\ No newline at end of file
diff --git a/sp-server-api/src/main/java/net/shibboleth/sp/config/AssertingParty.java b/sp-server-api/src/main/java/net/shibboleth/sp/config/AssertingParty.java
new file mode 100644
index 0000000..b5b9960
--- /dev/null
+++ b/sp-server-api/src/main/java/net/shibboleth/sp/config/AssertingParty.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You 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 net.shibboleth.sp.config;
+
+import java.util.Map;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import net.shibboleth.shared.annotation.constraint.NonnullElements;
+import net.shibboleth.shared.annotation.constraint.NotLive;
+import net.shibboleth.shared.annotation.constraint.Unmodifiable;
+
+/**
+ * Package of options exposed for configuring behavior when dealing with particular sources
+ * of identity.
+ *
+ * <p>Historically referred to as a "relying party", renamed for better accuracy.</p>
+ */
+public interface AssertingParty {
+
+ // TODO: This is entirely speculative but I lean toward this being pretty minimal and not
+ // particularly connected to the "existing" <RelyingParty> settings/concept in the SP.
+ // Rather, this is for hub-side controlled settings geared around technical protocol
+ // settings subject to IT control, modulo a few overrideable options at runtime that
+ // the agent would supply while making subsequent calls.
+
+ /**
+ * Get map of profile configurations keyed by profile ID.
+ *
+ * @param profileRequestContext profile request context
+ *
+ * @return map of profile configurations
+ */
+ @Nonnull @NonnullElements @NotLive @Unmodifiable Map<String,ProfileConfiguration> getProfileConfigurations(
+ @Nullable final ProfileRequestContext profileRequestContext);
+
+}
\ No newline at end of file
diff --git a/sp-server-api/src/main/java/net/shibboleth/sp/config/ConditionalProfileConfiguration.java b/sp-server-api/src/main/java/net/shibboleth/sp/config/ConditionalProfileConfiguration.java
new file mode 100644
index 0000000..ac0e41d
--- /dev/null
+++ b/sp-server-api/src/main/java/net/shibboleth/sp/config/ConditionalProfileConfiguration.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You 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 net.shibboleth.sp.config;
+
+import java.util.function.Predicate;
+
+import javax.annotation.Nonnull;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+/**
+ * A {@link ProfileConfiguration} supporting an activation condition.
+ */
+public interface ConditionalProfileConfiguration extends ProfileConfiguration {
+
+ /**
+ * Get the condition controlling enablement of this profile.
+ *
+ * @return condition controlling enablement of this profile
+ */
+ @Nonnull Predicate<ProfileRequestContext> getActivationCondition();
+
+}
\ No newline at end of file
diff --git a/sp-server-api/src/main/java/net/shibboleth/sp/config/ProfileConfiguration.java b/sp-server-api/src/main/java/net/shibboleth/sp/config/ProfileConfiguration.java
new file mode 100644
index 0000000..0f5f78c
--- /dev/null
+++ b/sp-server-api/src/main/java/net/shibboleth/sp/config/ProfileConfiguration.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You 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 net.shibboleth.sp.config;
+
+import javax.annotation.Nullable;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.opensaml.security.config.SecurityConfiguration;
+
+import net.shibboleth.shared.component.IdentifiedComponent;
+
+/**
+ * Interface for profile-specific configuration used to customize SP behavior.
+ */
+public interface ProfileConfiguration extends IdentifiedComponent {
+
+ /**
+ * Gets the applicable {@link SecurityConfiguration}.
+ *
+ * @param profileRequestContext profile request context
+ *
+ * @return the profile's security configuration
+ */
+ @Nullable SecurityConfiguration getSecurityConfiguration(
+ @Nullable final ProfileRequestContext profileRequestContext);
+
+}
\ No newline at end of file
diff --git a/sp-server-api/src/main/java/net/shibboleth/sp/config/package-info.java b/sp-server-api/src/main/java/net/shibboleth/sp/config/package-info.java
new file mode 100644
index 0000000..160ee73
--- /dev/null
+++ b/sp-server-api/src/main/java/net/shibboleth/sp/config/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You 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.
+ */
+
+/**
+ * Core configuration interfaces and classes.
+ */
+package net.shibboleth.sp.config;
\ No newline at end of file
diff --git a/sp-server-api/src/main/java/net/shibboleth/sp/ddf/DDF.java b/sp-server-api/src/main/java/net/shibboleth/sp/ddf/DDF.java
index c106a62..86549ca 100644
--- a/sp-server-api/src/main/java/net/shibboleth/sp/ddf/DDF.java
+++ b/sp-server-api/src/main/java/net/shibboleth/sp/ddf/DDF.java
@@ -37,6 +37,7 @@ import net.shibboleth.shared.annotation.constraint.NonnullElements;
import net.shibboleth.shared.annotation.constraint.NotEmpty;
import net.shibboleth.shared.annotation.constraint.NotLive;
import net.shibboleth.shared.annotation.constraint.Unmodifiable;
+import net.shibboleth.shared.collection.CollectionSupport;
import net.shibboleth.shared.logic.Constraint;
@@ -324,19 +325,23 @@ public class DDF implements Iterable<DDF> {
break;
case DDF_INT:
+ assert value instanceof Integer;
dup.integer((Integer) value);
break;
case DDF_LONG:
+ assert value instanceof Long;
dup.longinteger((Long) value);
break;
case DDF_FLOAT:
+ assert value instanceof Double;
dup.floating((Double) value);
break;
case DDF_STRUCT:
dup.structure();
+ assert value instanceof Map;
for (final DDF ddf : ((Map<String,DDF>) value).values()) {
dup.add(ddf.copy());
}
@@ -344,6 +349,7 @@ public class DDF implements Iterable<DDF> {
case DDF_LIST:
dup.list();
+ assert value instanceof List;
for (final DDF ddf : (List<DDF>) value) {
dup.add(ddf.copy());
}
@@ -377,7 +383,8 @@ public class DDF implements Iterable<DDF> {
* @return this object
*/
@Nonnull public DDF name(@Nullable @NotEmpty final String n) {
- if (!isnull() && (parent == null || !parent.isstruct())) {
+ final DDF p = parent;
+ if (!isnull() && (p == null || !p.isstruct())) {
if (n != null) {
name = Constraint.isNotEmpty(n.substring(0,Integer.min(n.length(), 255)), "Name cannot be empty");
} else {
@@ -513,8 +520,10 @@ public class DDF implements Iterable<DDF> {
case DDF_INT:
return (Integer) value;
case DDF_LONG:
+ assert value instanceof Long;
return ((Long) value).intValue();
case DDF_FLOAT:
+ assert value instanceof Double;
return ((Double) value).intValue();
case DDF_STRING:
try {
@@ -524,8 +533,10 @@ public class DDF implements Iterable<DDF> {
return null;
}
case DDF_STRUCT:
+ assert value instanceof Map;
return ((Map<?,?>) value).size();
case DDF_LIST:
+ assert value instanceof List;
return ((List<?>) value).size();
default:
break;
@@ -546,10 +557,12 @@ public class DDF implements Iterable<DDF> {
switch(type) {
case DDF_INT:
+ assert value instanceof Integer;
return ((Integer) value).longValue();
case DDF_LONG:
return (Long) value;
case DDF_FLOAT:
+ assert value instanceof Double;
return ((Double) value).longValue();
case DDF_STRING:
try {
@@ -559,8 +572,10 @@ public class DDF implements Iterable<DDF> {
return null;
}
case DDF_STRUCT:
+ assert value instanceof Map;
return (long) ((Map<?,?>) value).size();
case DDF_LIST:
+ assert value instanceof List;
return (long) ((List<?>) value).size();
default:
break;
@@ -581,8 +596,10 @@ public class DDF implements Iterable<DDF> {
switch(type) {
case DDF_INT:
+ assert value instanceof Integer;
return ((Integer) value).doubleValue();
case DDF_LONG:
+ assert value instanceof Long;
return ((Long) value).doubleValue();
case DDF_FLOAT:
return (Double) value;
@@ -594,8 +611,10 @@ public class DDF implements Iterable<DDF> {
return null;
}
case DDF_STRUCT:
+ assert value instanceof Map;
return (double) ((Map<?,?>) value).size();
case DDF_LIST:
+ assert value instanceof List;
return (double) ((List<?>) value).size();
default:
break;
@@ -818,7 +837,7 @@ public class DDF implements Iterable<DDF> {
*
* @return this object
*/
- @Nonnull public DDF pointer(@Nonnull final Object val) {
+ @Nonnull public DDF pointer(@Nullable final Object val) {
empty();
value = val;
type = DDFType.DDF_POINTER;
@@ -848,11 +867,14 @@ public class DDF implements Iterable<DDF> {
if (child.name == null) {
return child;
}
+ assert child.name != null;
getmember(child.name).destroy();
child.remove();
+ assert value instanceof Map;
((Map<String,DDF>) value).put(child.name, child);
} else {
child.remove();
+ assert value instanceof List;
((List<DDF>) value).add(child);
}
@@ -880,6 +902,7 @@ public class DDF implements Iterable<DDF> {
child.remove();
@SuppressWarnings("unchecked")
final List<DDF> list = (List<DDF>) value;
+ assert list != null;
list.add(list.indexOf(before), child);
child.parent = this;
return child;
@@ -906,7 +929,7 @@ public class DDF implements Iterable<DDF> {
@SuppressWarnings("unchecked")
final List<DDF> list = (List<DDF>) value;
-
+ assert list != null;
final int i = list.indexOf(after);
if (i == list.size() - 1) {
list.add(child);
@@ -925,11 +948,14 @@ public class DDF implements Iterable<DDF> {
*/
@SuppressWarnings("unchecked")
@Nonnull public DDF remove() {
- if (parent != null) {
- if (parent.isstruct()) {
- ((Map<String,DDF>) parent.value).remove(name);
+ final DDF p = parent;
+ if (p != null) {
+ if (p.isstruct()) {
+ assert p.value instanceof Map;
+ ((Map<String,DDF>) p.value).remove(name);
} else {
- ((List<DDF>) parent.value).remove(this);
+ assert p.value instanceof List;
+ ((List<DDF>) p.value).remove(this);
}
parent = null;
@@ -954,10 +980,11 @@ public class DDF implements Iterable<DDF> {
@SuppressWarnings("unchecked")
@Nonnull @NonnullElements @Unmodifiable @NotLive public Map<String,DDF> asMap() {
if (isstruct()) {
- return Map.copyOf((Map<String,DDF>) value);
+ assert value instanceof Map;
+ return CollectionSupport.copyToMap((Map<String,DDF>) value);
}
- return Collections.emptyMap();
+ return CollectionSupport.emptyMap();
}
/**
@@ -968,12 +995,14 @@ public class DDF implements Iterable<DDF> {
@SuppressWarnings("unchecked")
@Nonnull @NonnullElements @Unmodifiable @NotLive public List<DDF> asList() {
if (isstruct()) {
- return List.copyOf(((Map<String,DDF>) value).values());
+ assert value instanceof Map;
+ return CollectionSupport.copyToList(((Map<String,DDF>) value).values());
} else if (islist()) {
- return List.copyOf((List<DDF>) value);
+ assert value instanceof List;
+ return CollectionSupport.copyToList((List<DDF>) value);
}
- return Collections.emptyList();
+ return CollectionSupport.emptyList();
}
/**
@@ -1000,6 +1029,7 @@ public class DDF implements Iterable<DDF> {
base.structure();
}
+ assert segment != null;
DDF node = base.getmember(segment);
if (node.isnull()) {
node = base.add(new DDF(segment));
@@ -1043,14 +1073,21 @@ public class DDF implements Iterable<DDF> {
} catch(final NumberFormatException e) {
index = 0;
}
- if (current.islist() && index < ((List<DDF>) current.value).size()) {
- current = ((List<DDF>) current.value).get(index);
+ if (current.islist()) {
+ assert current.value instanceof List;
+ final List<DDF> currentValue = (List<DDF>) current.value;
+ if (index < currentValue.size()) {
+ current = currentValue.get(index);
+ } else {
+ return new DDF();
+ }
} else {
return new DDF();
}
i++;
} else if (current.isstruct()) {
// Access the named element and advance the path.
+ assert current.value instanceof Map;
current = ((Map<String,DDF>) current.value).get(tokens[i]);
if (current == null) {
return new DDF();
@@ -1058,6 +1095,7 @@ public class DDF implements Iterable<DDF> {
i++;
} else if (current.islist()) {
// Access first element of list, don't advance the path.
+ assert current.value instanceof List;
current = ((List<DDF>) current.value).get(0);
if (current == null) {
return new DDF();
@@ -1067,6 +1105,7 @@ public class DDF implements Iterable<DDF> {
}
}
+ assert current != null;
return current;
}
@@ -1099,7 +1138,7 @@ public class DDF implements Iterable<DDF> {
if (other.name != null) {
return false;
}
- } else if (!name.equals(other.name)) {
+ } else if (name != null && !name.equals(other.name)) {
return false;
}
@@ -1111,7 +1150,7 @@ public class DDF implements Iterable<DDF> {
if (other.value != null) {
return false;
}
- } else if (!value.equals(other.value)) {
+ } else if (value != null && !value.equals(other.value)) {
return false;
}
@@ -1124,10 +1163,24 @@ public class DDF implements Iterable<DDF> {
public int hashCode() {
final int prime = 31;
int result = 1;
- result = prime * result + ((name == null) ? 0 : name.hashCode());
- result = prime * result + ((parent == null) ? 0 : parent.hashCode());
+ if (name != null) {
+ result = name.hashCode() + prime * result;
+ } else {
+ result = prime * result;
+ }
+
+ if (parent != null) {
+ result = parent.hashCode() + prime * result;
+ } else {
+ result = prime * result;
+ }
result = prime * result + ((type == null) ? 0 : type.hashCode());
- result = prime * result + ((value == null) ? 0 : value.hashCode());
+
+ if (value != null) {
+ result = value.hashCode() + prime * result;
+ } else {
+ result = prime * result;
+ }
return result;
}
@@ -1176,7 +1229,8 @@ public class DDF implements Iterable<DDF> {
}
builder.append(" = ");
if (value != null) {
- builder.append('"').append(((String) value).replace("\"", "\\\"")).append('"');
+ final String valueCopy = (String) value;
+ builder.append('"').append(valueCopy.replace("\"", "\\\"")).append('"');
} else {
builder.append("null");
}
@@ -1189,8 +1243,9 @@ public class DDF implements Iterable<DDF> {
}
builder.append(" = ");
if (value != null) {
+ final byte[] valueCopy = (byte[]) value;
builder.append('{');
- for (final byte b : (byte[]) value) {
+ for (final byte b : valueCopy) {
builder.append(Integer.toHexString(b)).append(", ");
}
builder.append('}');
@@ -1229,6 +1284,7 @@ public class DDF implements Iterable<DDF> {
builder.append(' ').append(name);
}
builder.append(" = {");
+ assert value instanceof Map;
if (!((Map<?,?>) value).isEmpty()) {
builder.append('\n');
for (final DDF child : this) {
@@ -1242,13 +1298,15 @@ public class DDF implements Iterable<DDF> {
break;
case DDF_LIST:
- builder.append("DDF[").append(((List<?>) value).size()).append(']');
+ assert value instanceof List;
+ final List<?> valueCopy = (List<?>) value;
+ builder.append("DDF[").append(valueCopy.size()).append(']');
if (name != null) {
builder.append(' ').append(name);
}
builder.append(" = {");
- if (!((List<?>) value).isEmpty()) {
+ if (!valueCopy.isEmpty()) {
builder.append('\n');
for (final DDF child : this) {
child.dump(builder, indent + 2);
@@ -1310,6 +1368,7 @@ public class DDF implements Iterable<DDF> {
os.write(Integer.toString(type.getValue()).getBytes("UTF8"));
if (value != null) {
os.write(' ');
+ assert value instanceof String;
encode(os, ((String) value).getBytes("UTF-8"));
}
os.write('\n');
@@ -1319,6 +1378,7 @@ public class DDF implements Iterable<DDF> {
os.write(Integer.toString(type.getValue()).getBytes("UTF8"));
if (value != null) {
os.write(' ');
+ assert value instanceof byte[];
encode(os, (byte[]) value);
}
os.write('\n');
@@ -1327,6 +1387,7 @@ public class DDF implements Iterable<DDF> {
case DDF_INT:
os.write(Integer.toString(type.getValue()).getBytes("UTF8"));
os.write(' ');
+ assert value instanceof Integer;
os.write(Integer.toString((Integer) value).getBytes("UTF8"));
os.write('\n');
break;
@@ -1334,6 +1395,7 @@ public class DDF implements Iterable<DDF> {
case DDF_LONG:
os.write(Integer.toString(type.getValue()).getBytes("UTF8"));
os.write(' ');
+ assert value instanceof Long;
os.write(Long.toString((Long) value).getBytes("UTF8"));
os.write('\n');
break;
@@ -1341,11 +1403,13 @@ public class DDF implements Iterable<DDF> {
case DDF_FLOAT:
os.write(Integer.toString(type.getValue()).getBytes("UTF8"));
os.write(' ');
+ assert value instanceof Double;
os.write(Double.toString((Double) value).getBytes("UTF8"));
os.write('\n');
break;
case DDF_STRUCT:
+ assert value instanceof Map;
@SuppressWarnings("unchecked")
final Collection<DDF> members = ((Map<String,DDF>) value).values();
os.write(Integer.toString(type.getValue()).getBytes("UTF8"));
@@ -1358,6 +1422,7 @@ public class DDF implements Iterable<DDF> {
break;
case DDF_LIST:
+ assert value instanceof List;
@SuppressWarnings("unchecked")
final Collection<DDF> children = (List<DDF>) value;
os.write(Integer.toString(type.getValue()).getBytes("UTF8"));
diff --git a/sp-server-api/src/main/java/net/shibboleth/sp/ddf/RemotedHttpServletRequest.java b/sp-server-api/src/main/java/net/shibboleth/sp/ddf/RemotedHttpServletRequest.java
index 4daa0ca..069d1ba 100644
--- a/sp-server-api/src/main/java/net/shibboleth/sp/ddf/RemotedHttpServletRequest.java
+++ b/sp-server-api/src/main/java/net/shibboleth/sp/ddf/RemotedHttpServletRequest.java
@@ -48,6 +48,7 @@ import jakarta.servlet.AsyncContext;
import jakarta.servlet.DispatcherType;
import jakarta.servlet.ReadListener;
import jakarta.servlet.RequestDispatcher;
+import jakarta.servlet.ServletConnection;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletInputStream;
@@ -60,6 +61,7 @@ import jakarta.servlet.http.HttpSession;
import jakarta.servlet.http.HttpUpgradeHandler;
import jakarta.servlet.http.Part;
import net.shibboleth.shared.annotation.constraint.NonnullElements;
+import net.shibboleth.shared.collection.CollectionSupport;
import net.shibboleth.shared.collection.Pair;
import net.shibboleth.shared.logic.Constraint;
import net.shibboleth.shared.net.URISupport;
@@ -192,7 +194,7 @@ public class RemotedHttpServletRequest implements HttpServletRequest {
/** {@inheritDoc} */
public Map<String, String[]> getParameterMap() {
if (parameters == null) {
- parameters = new HashMap<>();
+ final Map<String, String[]> parameterMap = new HashMap<>();
final Multimap<String,String> multimap = ArrayListMultimap.create();
final String qs = getQueryString();
if (qs != null) {
@@ -213,13 +215,30 @@ public class RemotedHttpServletRequest implements HttpServletRequest {
}
for (final Map.Entry<String,Collection<String>> entry : multimap.asMap().entrySet()) {
- parameters.put(entry.getKey(), entry.getValue().toArray(new String[entry.getValue().size()]));
+ parameterMap.put(entry.getKey(), entry.getValue().toArray(new String[entry.getValue().size()]));
}
+
+ parameters = parameterMap;
}
return parameters;
}
+ /** {@inheritDoc} */
+ public String getRequestId() {
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ public String getProtocolRequestId() {
+ return "";
+ }
+
+ /** {@inheritDoc} */
+ public ServletConnection getServletConnection() {
+ throw new UnsupportedOperationException();
+ }
+
/** {@inheritDoc} */
public String getProtocol() {
final String protocol = obj.getmember("protocol").string();
@@ -269,7 +288,7 @@ public class RemotedHttpServletRequest implements HttpServletRequest {
/** {@inheritDoc} */
public Locale getLocale() {
- throw new UnsupportedOperationException();
+ throw new UnsupportedOperationException();
}
/** {@inheritDoc} */
@@ -287,11 +306,6 @@ public class RemotedHttpServletRequest implements HttpServletRequest {
throw new UnsupportedOperationException();
}
- /** {@inheritDoc} */
- public String getRealPath(final String path) {
- throw new UnsupportedOperationException();
- }
-
/** {@inheritDoc} */
public int getRemotePort() {
throw new UnsupportedOperationException();
@@ -371,25 +385,32 @@ public class RemotedHttpServletRequest implements HttpServletRequest {
if (name.endsWith("_fgwars")) {
name.substring(0, name.length() - 7);
}
+ assert cookies != null;
cookies.add(new Cookie(name, nvpair[1]));
}
}
} else {
- cookies = Collections.emptyList();
+ cookies = CollectionSupport.emptyList();
}
} else {
- cookies = Collections.emptyList();
+ cookies = CollectionSupport.emptyList();
}
}
+ assert cookies != null;
if (cookies.isEmpty()) {
return null;
}
+
+ assert cookies != null;
return cookies.toArray(new Cookie[cookies.size()]);
}
/** {@inheritDoc} */
public long getDateHeader(final String name) {
+ if (name == null) {
+ return -1;
+ }
final DDF h = obj.getmember("headers").getmember(name);
if (h.isstring()) {
try {
@@ -409,11 +430,17 @@ public class RemotedHttpServletRequest implements HttpServletRequest {
/** {@inheritDoc} */
public String getHeader(final String name) {
+ if (name == null) {
+ return null;
+ }
return decodeUnsafeString(obj.getmember("headers").getmember(name).unsafe_string());
}
/** {@inheritDoc} */
public Enumeration<String> getHeaders(final String name) {
+ if (name == null) {
+ return Collections.emptyEnumeration();
+ }
final String s = decodeUnsafeString(obj.getmember("headers").getmember(name).unsafe_string());
if (s != null) {
return Collections.enumeration(Collections.singletonList(s));
@@ -428,6 +455,9 @@ public class RemotedHttpServletRequest implements HttpServletRequest {
/** {@inheritDoc} */
public int getIntHeader(final String name) {
+ if (name == null) {
+ return -1;
+ }
final DDF h = obj.getmember("headers").getmember(name);
if (h.isstring()) {
return Integer.parseInt(decodeUnsafeString(h.unsafe_string()));
@@ -532,11 +562,6 @@ public class RemotedHttpServletRequest implements HttpServletRequest {
return false;
}
- /** {@inheritDoc} */
- public boolean isRequestedSessionIdFromUrl() {
- return false;
- }
-
/** {@inheritDoc} */
public boolean authenticate(final HttpServletResponse response) throws IOException, ServletException {
throw new UnsupportedOperationException();
@@ -684,5 +709,7 @@ public class RemotedHttpServletRequest implements HttpServletRequest {
return delegate.markSupported();
}
}
+
+ /** {@inheritDoc} */
}
\ No newline at end of file
diff --git a/sp-server-api/src/main/java/net/shibboleth/sp/ddf/RemotedHttpServletResponse.java b/sp-server-api/src/main/java/net/shibboleth/sp/ddf/RemotedHttpServletResponse.java
index d960f41..8960bb1 100644
--- a/sp-server-api/src/main/java/net/shibboleth/sp/ddf/RemotedHttpServletResponse.java
+++ b/sp-server-api/src/main/java/net/shibboleth/sp/ddf/RemotedHttpServletResponse.java
@@ -223,16 +223,6 @@ public class RemotedHttpServletResponse implements HttpServletResponse {
return url;
}
- /** {@inheritDoc} */
- public String encodeUrl(final String url) {
- return url;
- }
-
- /** {@inheritDoc} */
- public String encodeRedirectUrl(final String url) {
- return url;
- }
-
/** {@inheritDoc} */
public void sendError(final int sc, final String msg) throws IOException {
throw new UnsupportedOperationException();
@@ -257,37 +247,49 @@ public class RemotedHttpServletResponse implements HttpServletResponse {
/** {@inheritDoc} */
public void setDateHeader(final String name, final long date) {
- unsetHeader(name);
- addDateHeader(name, date);
+ if (name != null) {
+ unsetHeader(name);
+ addDateHeader(name, date);
+ }
}
/** {@inheritDoc} */
public void addDateHeader(final String name, final long date) {
- final SimpleDateFormat formatter = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz");
- formatter.setTimeZone(TimeZone.getTimeZone("GMT"));
- addHeader(name, formatter.format(Date.from(Instant.ofEpochMilli(date))));
+ if (name != null) {
+ final SimpleDateFormat formatter = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz");
+ formatter.setTimeZone(TimeZone.getTimeZone("GMT"));
+ addHeader(name, formatter.format(Date.from(Instant.ofEpochMilli(date))));
+ }
}
/** {@inheritDoc} */
public void setHeader(final String name, final String value) {
- unsetHeader(name);
- addHeader(name, value);
+ if (name != null) {
+ unsetHeader(name);
+ addHeader(name, value);
+ }
}
/** {@inheritDoc} */
public void addHeader(final String name, final String value) {
- getHeaderList().add(new DDF(name).string(value));
+ if (name != null) {
+ getHeaderList().add(new DDF(name).string(value));
+ }
}
/** {@inheritDoc} */
public void setIntHeader(final String name, final int value) {
- unsetHeader(name);
- addIntHeader(name, value);
+ if (name != null) {
+ unsetHeader(name);
+ addIntHeader(name, value);
+ }
}
/** {@inheritDoc} */
public void addIntHeader(final String name, final int value) {
- getHeaderList().add(new DDF(name).integer(value));
+ if (name != null) {
+ getHeaderList().add(new DDF(name).integer(value));
+ }
}
/** {@inheritDoc} */
@@ -295,12 +297,6 @@ public class RemotedHttpServletResponse implements HttpServletResponse {
obj.addmember("response.status").integer(sc);
}
- /** {@inheritDoc} */
- public void setStatus(final int sc, final String sm) {
- setStatus(sc);
- obj.addmember("response.status_message").string(sm);
- }
-
/** {@inheritDoc} */
public int getStatus() {
final Integer i = obj.getmember("response.status").integer();
@@ -318,7 +314,10 @@ public class RemotedHttpServletResponse implements HttpServletResponse {
if (header.orElseThrow().isstring()) {
return header.orElseThrow().string();
}
- return header.orElseThrow().integer().toString();
+ final Integer i = header.orElseThrow().integer();
+ if (i != null) {
+ return i.toString();
+ }
}
return null;
@@ -385,7 +384,7 @@ public class RemotedHttpServletResponse implements HttpServletResponse {
private int offset;
/** Wrapped array. */
- private final byte[] buffer;
+ @Nonnull private final byte[] buffer;
/**
* Constructor.
diff --git a/sp-server-api/src/test/java/net/shibboleth/sp/ddf/DDFSupportTest.java b/sp-server-api/src/test/java/net/shibboleth/sp/ddf/DDFSupportTest.java
index f6dfca9..3cb397a 100644
--- a/sp-server-api/src/test/java/net/shibboleth/sp/ddf/DDFSupportTest.java
+++ b/sp-server-api/src/test/java/net/shibboleth/sp/ddf/DDFSupportTest.java
@@ -56,7 +56,10 @@ public class DDFSupportTest {
*/
@AfterClass
public void tearDown() {
- parserPool.destroy();
+ if (parserPool != null) {
+ parserPool.destroy();
+ parserPool = null;
+ }
}
/**
@@ -67,6 +70,7 @@ public class DDFSupportTest {
*/
@Test
public void test() throws XMLParserException, IOException {
+ assert parserPool != null;
final Document doc = parserPool.parse(getClass().getResourceAsStream("zork.xml"));
final DDF ddf = DDFSupport.fromElement(doc.getDocumentElement());
diff --git a/sp-server-api/src/test/java/net/shibboleth/sp/ddf/DDFTest.java b/sp-server-api/src/test/java/net/shibboleth/sp/ddf/DDFTest.java
index 923024f..095baac 100644
--- a/sp-server-api/src/test/java/net/shibboleth/sp/ddf/DDFTest.java
+++ b/sp-server-api/src/test/java/net/shibboleth/sp/ddf/DDFTest.java
@@ -35,6 +35,7 @@ import net.shibboleth.shared.collection.Pair;
/**
* DDF unit tests.
*/
+ at SuppressWarnings("javadoc")
public class DDFTest {
@Test
@@ -130,7 +131,9 @@ public class DDFTest {
assertEquals(obj.integer(), Integer.valueOf(3));
for (final DDF el : obj) {
- switch (el.name()) {
+ final String name = el.name();
+ assert name != null;
+ switch (name) {
case "foo":
assertEquals(el.string(), "bar");
break;
@@ -158,7 +161,9 @@ public class DDFTest {
obj.addbefore(new DDF("foo4"), obj.getmember("[2]"));
assertEquals(obj.integer(), Integer.valueOf(5));
- assertTrue(obj.getmember("[2]").name().equals("foo4"));
+ final String name = obj.getmember("[2]").name();
+ assert name != null;
+ assertTrue(name.equals("foo4"));
assertTrue(obj.asList().get(4).remove().ispointer());
assertEquals(obj.integer(), Integer.valueOf(4));
@@ -172,8 +177,8 @@ public class DDFTest {
obj.add(new DDF("foo", "bar"));
assertEquals(obj.integer(), Integer.valueOf(1));
- assertTrue(obj.getmember("foo").name().equals("foo"));
- assertTrue(obj.getmember("foo").string().equals("bar"));
+ assertEquals(obj.getmember("foo").name(), "foo");
+ assertEquals(obj.getmember("foo").string(), "bar");
obj.addmember("foo2").integer(42);
assertEquals(obj.integer(), Integer.valueOf(2));
@@ -182,8 +187,8 @@ public class DDFTest {
assertEquals(obj.integer(), Integer.valueOf(2));
assertTrue(obj.getmember("foo2").isstruct());
assertEquals(obj.getmember("foo2").integer(), Integer.valueOf(1));
- assertTrue(obj.getmember("foo2").getmember("foo3").string().equals("bar3"));
- assertTrue(obj.getmember("foo2.foo3").string().equals("bar3"));
+ assertEquals(obj.getmember("foo2").getmember("foo3").string(), "bar3");
+ assertEquals(obj.getmember("foo2.foo3").string(), "bar3");
}
@Test
diff --git a/sp-server-api/src/test/java/net/shibboleth/sp/ddf/RemotedHttpServletRequestTest.java b/sp-server-api/src/test/java/net/shibboleth/sp/ddf/RemotedHttpServletRequestTest.java
index 8bf34ff..2470ebd 100644
--- a/sp-server-api/src/test/java/net/shibboleth/sp/ddf/RemotedHttpServletRequestTest.java
+++ b/sp-server-api/src/test/java/net/shibboleth/sp/ddf/RemotedHttpServletRequestTest.java
@@ -31,6 +31,7 @@ import org.testng.reporters.Files;
/**
* Unit test for {@link RemotedHttpServletRequest}.
*/
+ at SuppressWarnings("javadoc")
public class RemotedHttpServletRequestTest {
private DDF obj;
diff --git a/sp-server-api/src/test/java/net/shibboleth/sp/ddf/RemotedHttpServletResponseTest.java b/sp-server-api/src/test/java/net/shibboleth/sp/ddf/RemotedHttpServletResponseTest.java
index 4de6dcb..338ff2f 100644
--- a/sp-server-api/src/test/java/net/shibboleth/sp/ddf/RemotedHttpServletResponseTest.java
+++ b/sp-server-api/src/test/java/net/shibboleth/sp/ddf/RemotedHttpServletResponseTest.java
@@ -33,6 +33,7 @@ import org.testng.annotations.Test;
/**
* Unit test for {@link RemotedHttpServletResponse}.
*/
+ at SuppressWarnings("javadoc")
public class RemotedHttpServletResponseTest {
private DDF obj;
diff --git a/sp-server-impl/pom.xml b/sp-server-impl/pom.xml
index ee247d8..eb3352f 100644
--- a/sp-server-impl/pom.xml
+++ b/sp-server-impl/pom.xml
@@ -20,7 +20,7 @@
</properties>
<dependencies>
- <!-- compile dependencies -->
+ <!-- Compile dependencies -->
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>sp-server-api</artifactId>
diff --git a/sp-session-api/pom.xml b/sp-session-api/pom.xml
index c064e97..6818c7c 100644
--- a/sp-session-api/pom.xml
+++ b/sp-session-api/pom.xml
@@ -21,6 +21,13 @@
<dependencies>
<!-- Compile dependencies -->
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>sp-server-api</artifactId>
+ <version>${project.version}</version>
+ <scope>compile</scope>
+ </dependency>
+
<dependency>
<groupId>net.shibboleth</groupId>
<artifactId>shib-attribute-api</artifactId>
diff --git a/sp-session-api/src/main/java/net/shibboleth/sp/session/AbstractRemotableSPSession.java b/sp-session-api/src/main/java/net/shibboleth/sp/session/AbstractRemotableSPSession.java
new file mode 100644
index 0000000..cd57e3b
--- /dev/null
+++ b/sp-session-api/src/main/java/net/shibboleth/sp/session/AbstractRemotableSPSession.java
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You 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 net.shibboleth.sp.session;
+
+import java.time.Instant;
+import java.util.Collection;
+
+import javax.annotation.Nonnull;
+
+import com.google.common.collect.Multimap;
+
+import net.shibboleth.idp.attribute.IdPAttribute;
+import net.shibboleth.shared.annotation.constraint.NonnullElements;
+import net.shibboleth.shared.annotation.constraint.NotEmpty;
+import net.shibboleth.shared.annotation.constraint.NotLive;
+import net.shibboleth.shared.annotation.constraint.Unmodifiable;
+import net.shibboleth.sp.ddf.DDF;
+
+/**
+ * Abstract base class for a {@link RemotableSPSession}.
+ */
+public abstract class AbstractRemotableSPSession implements RemotableSPSession {
+
+ /** Underlying object housing session. */
+ @Nonnull final DDF obj;
+
+ /**
+ * Constructor.
+ *
+ * @param id session identifier
+ */
+ protected AbstractRemotableSPSession(@Nonnull @NotEmpty final String id) {
+ obj = new DDF(id);
+ }
+
+ /** {@inheritDoc} */
+ @Nonnull @NotEmpty public String getId() {
+ return obj.name();
+ }
+
+ /** {@inheritDoc} */
+ @Nonnull public Instant getCreation() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Nonnull public Instant getLastActivity() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Nonnull public Instant getExpiration() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Nonnull @NonnullElements @NotLive @Unmodifiable public Multimap<String,IdPAttribute> getAttributes() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ public void addAttributes(@Nonnull @NonnullElements final Collection<IdPAttribute> attributes) {
+ // TODO Auto-generated method stub
+
+ }
+
+ /** {@inheritDoc} */
+ public void removeAttribute(@Nonnull @NonnullElements final Collection<IdPAttribute> attributes) {
+ // TODO Auto-generated method stub
+
+ }
+
+ /** {@inheritDoc} */
+ @Nonnull public DDF serialize() throws SessionException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+}
\ No newline at end of file
diff --git a/sp-session-api/src/main/java/net/shibboleth/sp/session/RemotableSPSession.java b/sp-session-api/src/main/java/net/shibboleth/sp/session/RemotableSPSession.java
new file mode 100644
index 0000000..a7efab2
--- /dev/null
+++ b/sp-session-api/src/main/java/net/shibboleth/sp/session/RemotableSPSession.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You 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 net.shibboleth.sp.session;
+
+import javax.annotation.Nonnull;
+
+import net.shibboleth.sp.ddf.DDF;
+
+/**
+ * Extension for sessions that can generate a {@link DDF} representation.
+ */
+public interface RemotableSPSession extends SPSession {
+
+ /**
+ * Serialize the session to a {@link DDF}.
+ *
+ * @return the serialized session
+ *
+ * @throws SessionException if unable to serialize
+ */
+ @Nonnull DDF serialize() throws SessionException;
+
+}
\ No newline at end of file
diff --git a/sp-session-api/src/main/java/net/shibboleth/sp/session/SPSession.java b/sp-session-api/src/main/java/net/shibboleth/sp/session/SPSession.java
new file mode 100644
index 0000000..38f950a
--- /dev/null
+++ b/sp-session-api/src/main/java/net/shibboleth/sp/session/SPSession.java
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You 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 net.shibboleth.sp.session;
+
+import java.time.Instant;
+import java.util.Collection;
+
+import javax.annotation.Nonnull;
+import javax.annotation.concurrent.ThreadSafe;
+
+import com.google.common.collect.Multimap;
+
+import net.shibboleth.idp.attribute.IdPAttribute;
+import net.shibboleth.shared.annotation.constraint.NonnullElements;
+import net.shibboleth.shared.annotation.constraint.NotEmpty;
+import net.shibboleth.shared.annotation.constraint.NotLive;
+import net.shibboleth.shared.annotation.constraint.Unmodifiable;
+import net.shibboleth.shared.component.IdentifiedComponent;
+
+/**
+ * A service provider session belonging to a particular subject and client device.
+ */
+ at ThreadSafe
+public interface SPSession extends IdentifiedComponent {
+
+ /**
+ * Get the time when this session was created.
+ *
+ * @return time this session was created
+ */
+ @Nonnull Instant getCreation();
+
+ /**
+ * Get the last activity time for the session.
+ *
+ * <p>This is generally an approximation based on periodic
+ * updating of the value by external agents.</p>
+ *
+ * @return last activity for the session
+ */
+ @Nonnull Instant getLastActivity();
+
+ /**
+ * Get the expected expiration time of the session.
+ *
+ * @return expiration time
+ */
+ @Nonnull Instant getExpiration();
+
+ /**
+ * Get indexed map of {@link IdPAttribute} objects associated with this session.
+ *
+ * @return unmodifiable attribute map
+ */
+ @Nonnull @NonnullElements @NotLive @Unmodifiable public Multimap<String,IdPAttribute> getAttributes();
+
+ /**
+ * Add new {@link IdPAttribute} objects to the session.
+ *
+ * @param attributes attributes to add
+ */
+ void addAttributes(@Nonnull @NonnullElements final Collection<IdPAttribute> attributes);
+
+ /**
+ * Remove {@link IdPAttribute} objects from the session.
+ *
+ * @param attributes attributes to remove
+ */
+ void removeAttribute(@Nonnull @NonnullElements final Collection<IdPAttribute> attributes);
+
+ /**
+ * Test the session's validity based on the supplied client address, possibly binding it
+ * to the session if appropriate.
+ *
+ * @param address client address for validation
+ *
+ * @return true iff the session is valid for the specified client address
+ * @throws SessionException if an error occurs binding the address to the session
+ */
+ boolean checkAddress(@Nonnull @NotEmpty final String address) throws SessionException;
+
+ /**
+ * Test the session's validity based on inactivity, while updating the last activity time.
+ *
+ * @return true iff the session is still valid
+ * @throws SessionException if an error occurs updating the activity time
+ */
+ boolean checkTimeout() throws SessionException;
+
+}
\ No newline at end of file
diff --git a/sp-session-api/src/main/java/net/shibboleth/sp/session/SessionException.java b/sp-session-api/src/main/java/net/shibboleth/sp/session/SessionException.java
new file mode 100644
index 0000000..65c955e
--- /dev/null
+++ b/sp-session-api/src/main/java/net/shibboleth/sp/session/SessionException.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You 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 net.shibboleth.sp.session;
+
+import javax.annotation.Nullable;
+
+/** Exception indicating a problem with the session layer. */
+public class SessionException extends Exception {
+
+ /** Serial UUID. */
+ private static final long serialVersionUID = 8243844915411488275L;
+
+ /** Constructor. */
+ public SessionException() {
+
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param message exception message
+ */
+ public SessionException(@Nullable final String message) {
+ super(message);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param wrappedException exception to be wrapped by this one
+ */
+ public SessionException(@Nullable final Exception wrappedException) {
+ super(wrappedException);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param message exception message
+ * @param wrappedException exception to be wrapped by this one
+ */
+ public SessionException(@Nullable final String message, @Nullable final Exception wrappedException) {
+ super(message, wrappedException);
+ }
+
+}
\ No newline at end of file
diff --git a/sp-session-api/src/main/java/net/shibboleth/sp/session/package-info.java b/sp-session-api/src/main/java/net/shibboleth/sp/session/package-info.java
new file mode 100644
index 0000000..ae1c4b6
--- /dev/null
+++ b/sp-session-api/src/main/java/net/shibboleth/sp/session/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You 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.
+ */
+
+/**
+ * SP Session APIs.
+ */
+package net.shibboleth.sp.session;
\ No newline at end of file
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list