Introduce IndexResolver
This commit introduces IndexResolver as a strategy interface for resolving index values in FindByIndexNameSessionRepository implementations. Resolves: #557
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link DelegatingIndexResolver}.
|
||||
*
|
||||
* @author Vedran Pavic
|
||||
*/
|
||||
class DelegatingIndexResolverTests {
|
||||
|
||||
private DelegatingIndexResolver<MapSession> indexResolver;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
this.indexResolver = new DelegatingIndexResolver<>(new TestIndexResolver("one"), new TestIndexResolver("two"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void resolve() {
|
||||
MapSession session = new MapSession();
|
||||
session.setAttribute("one", "first");
|
||||
session.setAttribute("two", "second");
|
||||
Map<String, String> indexes = this.indexResolver.resolveIndexesFor(session);
|
||||
assertThat(indexes).hasSize(2);
|
||||
assertThat(indexes.get("one")).isEqualTo("first");
|
||||
assertThat(indexes.get("two")).isEqualTo("second");
|
||||
}
|
||||
|
||||
private static class TestIndexResolver implements IndexResolver<MapSession> {
|
||||
|
||||
private final String supportedIndex;
|
||||
|
||||
TestIndexResolver(String supportedIndex) {
|
||||
this.supportedIndex = supportedIndex;
|
||||
}
|
||||
|
||||
public Map<String, String> resolveIndexesFor(MapSession session) {
|
||||
return Collections.singletonMap(this.supportedIndex, session.getAttribute(this.supportedIndex));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.authority.AuthorityUtils;
|
||||
import org.springframework.security.core.context.SecurityContext;
|
||||
import org.springframework.security.core.context.SecurityContextImpl;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link PrincipalNameIndexResolver}.
|
||||
*
|
||||
* @author Vedran Pavic
|
||||
*/
|
||||
class PrincipalNameIndexResolverTests {
|
||||
|
||||
private static final String PRINCIPAL_NAME = "principalName";
|
||||
|
||||
private static final String SPRING_SECURITY_CONTEXT = "SPRING_SECURITY_CONTEXT";
|
||||
|
||||
private PrincipalNameIndexResolver<Session> indexResolver;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
this.indexResolver = new PrincipalNameIndexResolver<>();
|
||||
}
|
||||
|
||||
@Test
|
||||
void resolveFromPrincipalName() {
|
||||
MapSession session = new MapSession();
|
||||
session.setAttribute(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, PRINCIPAL_NAME);
|
||||
assertThat(this.indexResolver.resolveIndexValueFor(session)).isEqualTo(PRINCIPAL_NAME);
|
||||
}
|
||||
|
||||
@Test
|
||||
void resolveFromSpringSecurityContext() {
|
||||
Authentication authentication = new UsernamePasswordAuthenticationToken(PRINCIPAL_NAME, "notused",
|
||||
AuthorityUtils.createAuthorityList("ROLE_USER"));
|
||||
SecurityContext context = new SecurityContextImpl();
|
||||
context.setAuthentication(authentication);
|
||||
MapSession session = new MapSession();
|
||||
session.setAttribute(SPRING_SECURITY_CONTEXT, context);
|
||||
assertThat(this.indexResolver.resolveIndexValueFor(session)).isEqualTo(PRINCIPAL_NAME);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user