Introduce IndexResolver

This commit introduces IndexResolver as a strategy interface for resolving index values in FindByIndexNameSessionRepository implementations.

Resolves: #557
This commit is contained in:
Vedran Pavic
2019-04-30 21:37:00 +02:00
parent 099be441dd
commit a6f6042831
10 changed files with 364 additions and 122 deletions

View File

@@ -0,0 +1,54 @@
/*
* Copyright 2014-2019 the original author or authors.
*
* Licensed 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
*
* https://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 org.springframework.session;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* An {@link IndexResolver} that resolves indexes using multiple @{link IndexResolver}
* delegates.
*
* @param <S> the type of Session being handled
* @author Vedran Pavic
* @since 2.2.0
*/
public class DelegatingIndexResolver<S extends Session> implements IndexResolver<S> {
private final List<IndexResolver<S>> delegates;
public DelegatingIndexResolver(List<IndexResolver<S>> delegates) {
this.delegates = Collections.unmodifiableList(delegates);
}
@SafeVarargs
public DelegatingIndexResolver(IndexResolver<S>... delegates) {
this(Arrays.asList(delegates));
}
public Map<String, String> resolveIndexesFor(S session) {
Map<String, String> indexes = new HashMap<>();
for (IndexResolver<S> delegate : this.delegates) {
indexes.putAll(delegate.resolveIndexesFor(session));
}
return indexes;
}
}

View File

@@ -0,0 +1,39 @@
/*
* Copyright 2014-2019 the original author or authors.
*
* Licensed 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
*
* https://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 org.springframework.session;
import java.util.Map;
/**
* Strategy interface for resolving the {@link Session}'s indexes.
*
* @param <S> the type of Session being handled
* @author Rob Winch
* @author Vedran Pavic
* @since 2.2.0
* @see FindByIndexNameSessionRepository
*/
public interface IndexResolver<S extends Session> {
/**
* Resolve indexes for the session.
* @param session the session
* @return a map of resolved indexes, never {@code null}
*/
Map<String, String> resolveIndexesFor(S session);
}

View File

@@ -0,0 +1,54 @@
/*
* Copyright 2014-2019 the original author or authors.
*
* Licensed 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
*
* https://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 org.springframework.session;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.standard.SpelExpressionParser;
/**
* {@link IndexResolver} to resolve the principal name from session attribute named
* {@link FindByIndexNameSessionRepository#PRINCIPAL_NAME_INDEX_NAME} or Spring Security
* context stored in the session under {@code SPRING_SECURITY_CONTEXT} attribute.
*
* @param <S> the type of Session being handled
* @author Vedran Pavic
* @since 2.2.0
*/
public class PrincipalNameIndexResolver<S extends Session> extends SingleIndexResolver<S> {
private static final String SPRING_SECURITY_CONTEXT = "SPRING_SECURITY_CONTEXT";
private static final SpelExpressionParser parser = new SpelExpressionParser();
public PrincipalNameIndexResolver() {
super(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME);
}
public String resolveIndexValueFor(S session) {
String principalName = session.getAttribute(getIndexName());
if (principalName != null) {
return principalName;
}
Object authentication = session.getAttribute(SPRING_SECURITY_CONTEXT);
if (authentication != null) {
Expression expression = parser.parseExpression("authentication?.name");
return expression.getValue(authentication, String.class);
}
return null;
}
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright 2014-2019 the original author or authors.
*
* Licensed 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
*
* https://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 org.springframework.session;
import java.util.Collections;
import java.util.Map;
import org.springframework.util.Assert;
/**
* Base class for {@link IndexResolver}s that resolve a single index.
*
* @param <S> the type of Session being handled
* @author Rob Winch
* @author Vedran Pavic
* @since 2.2.0
*/
public abstract class SingleIndexResolver<S extends Session> implements IndexResolver<S> {
private final String indexName;
protected SingleIndexResolver(String indexName) {
Assert.notNull(indexName, "Index name must not be null");
this.indexName = indexName;
}
protected String getIndexName() {
return this.indexName;
}
public abstract String resolveIndexValueFor(S session);
public final Map<String, String> resolveIndexesFor(S session) {
String indexValue = resolveIndexValueFor(session);
return (indexValue != null) ? Collections.singletonMap(this.indexName, indexValue) : Collections.emptyMap();
}
}