You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2018/12/17 09:13:22 UTC
[isis] branch v2 updated: ISIS-2040: module 'security': API
changes: use streams instead of lists
This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a commit to branch v2
in repository https://gitbox.apache.org/repos/asf/isis.git
The following commit(s) were added to refs/heads/v2 by this push:
new ff40048 ISIS-2040: module 'security': API changes: use streams instead of lists
ff40048 is described below
commit ff40048cd63527aa640b82c61cdf4d20410f4a95
Author: Andi Huber <ah...@apache.org>
AuthorDate: Mon Dec 17 10:13:15 2018 +0100
ISIS-2040: module 'security': API changes: use streams instead of lists
improvements
- no need to wrap list of roles with unmodifiable
- for roles use HashSets instead of Lists
Task-Url: https://issues.apache.org/jira/browse/ISIS-2040
---
.../isis/applib/services/sudo/SudoService.java | 6 +--
.../isis/commons/internal/base/_NullSafe.java | 24 +++++++--
.../services/user/UserServiceDefault.java | 61 ++++++++++++----------
.../standard/AuthorizationManagerStandard.java | 21 ++++----
.../shiro/ShiroAuthenticatorOrAuthorizor.java | 31 ++++++-----
.../AuthenticationSessionProviderDefault.java | 4 +-
.../runtime/services/sudo/SudoServiceDefault.java | 11 ++--
.../SimpleSessionEncodabilityTestAbstract.java | 21 ++++++--
.../authentication/AuthenticationRequest.java | 39 ++++++++++++--
.../AuthenticationRequestAbstract.java | 23 ++++----
.../authentication/AuthenticationSession.java | 15 +++++-
.../AuthenticationSessionAbstract.java | 50 ++++++++----------
.../AuthenticationRequestLogonFixture.java | 6 +--
.../authentication/health/HealthAuthSession.java | 4 +-
.../AuthenticationRequestSingleUser.java | 14 +----
.../standard/AuthenticatorAbstract.java | 2 +-
.../authentication/standard/SimpleSession.java | 25 ++++++---
.../server/resources/UserReprRenderer.java | 7 +--
.../wicket/AuthenticatedWebSessionForIsis.java | 23 ++++----
19 files changed, 229 insertions(+), 158 deletions(-)
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/sudo/SudoService.java b/core/applib/src/main/java/org/apache/isis/applib/services/sudo/SudoService.java
index 9c6118b..f7a62df 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/sudo/SudoService.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/sudo/SudoService.java
@@ -61,13 +61,13 @@ public interface SudoService {
* Executes the supplied block, with the {@link DomainObjectContainer} returning the specified user with the specified roles.
*/
@Programmatic
- void sudo(String username, List<String> roles, final Runnable runnable);
+ void sudo(String username, Iterable<String> roles, final Runnable runnable);
/**
* Executes the supplied block, with the {@link DomainObjectContainer} returning the specified user with the specified roles.
*/
@Programmatic
- <T> T sudo(String username, List<String> roles, final Callable<T> callable);
+ <T> T sudo(String username, Iterable<String> roles, final Callable<T> callable);
/**
* Allows the {@link SudoService} to notify other services/components that the effective user has been changed.
@@ -83,7 +83,7 @@ public interface SudoService {
* </p>
*/
@Programmatic
- void runAs(String username, List<String> roles);
+ void runAs(String username, Iterable<String> roles);
/**
*
diff --git a/core/commons/src/main/java/org/apache/isis/commons/internal/base/_NullSafe.java b/core/commons/src/main/java/org/apache/isis/commons/internal/base/_NullSafe.java
index 5b63a99..d53eba5 100644
--- a/core/commons/src/main/java/org/apache/isis/commons/internal/base/_NullSafe.java
+++ b/core/commons/src/main/java/org/apache/isis/commons/internal/base/_NullSafe.java
@@ -29,6 +29,8 @@ import java.util.Spliterators;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
+import javax.annotation.Nullable;
+
/**
* <h1>- internal use only -</h1>
* <p>
@@ -56,7 +58,7 @@ public final class _NullSafe {
* @param array
* @return non-null stream object
*/
- public static <T> Stream<T> stream(final T[] array) {
+ public static <T> Stream<T> stream(@Nullable final T[] array) {
return array!=null ? Stream.of(array) : Stream.empty();
}
@@ -67,7 +69,7 @@ public final class _NullSafe {
* @param nullable
* @return non-null stream object
*/
- public static <T> Stream<T> streamNullable(final T nullable) {
+ public static <T> Stream<T> streamNullable(@Nullable final T nullable) {
return nullable != null ? Stream.of(nullable) : Stream.empty();
}
@@ -77,7 +79,7 @@ public final class _NullSafe {
* @param coll
* @return non-null stream object
*/
- public static <T> Stream<T> stream(final Collection<T> coll){
+ public static <T> Stream<T> stream(@Nullable final Collection<T> coll){
return coll!=null ? coll.stream() : Stream.empty();
}
@@ -87,7 +89,7 @@ public final class _NullSafe {
* @param iterable
* @return non-null stream object
*/
- public static <T> Stream<T> stream(final Iterable<T> iterable){
+ public static <T> Stream<T> stream(@Nullable final Iterable<T> iterable){
return iterable!=null ? stream(iterable.iterator()) : Stream.empty();
}
@@ -97,7 +99,7 @@ public final class _NullSafe {
* @param iterator
* @return non-null stream object
*/
- public static <T> Stream<T> stream(final Iterator<T> iterator){
+ public static <T> Stream<T> stream(@Nullable final Iterator<T> iterator){
return iterator!=null
? StreamSupport.stream(
Spliterators.spliteratorUnknownSize(iterator, Spliterator.ORDERED),
@@ -106,6 +108,16 @@ public final class _NullSafe {
}
/**
+ * If {@code stream} is {@code null} returns the empty stream,
+ * otherwise returns the stream argument.
+ * @param stream
+ * @return non-null stream object
+ */
+ public static <T> Stream<T> stream(@Nullable final Stream<T> stream) {
+ return stream!=null ? stream : Stream.empty();
+ }
+
+ /**
* If {@code enumeration} is {@code null} returns the empty stream,
* otherwise returns a stream of the enumeration's elements.
* @param enumeration
@@ -232,4 +244,6 @@ public final class _NullSafe {
+
+
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/user/UserServiceDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/user/UserServiceDefault.java
index ed34ddd..8d477b4 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/user/UserServiceDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/user/UserServiceDefault.java
@@ -19,9 +19,13 @@
package org.apache.isis.core.metamodel.services.user;
-import java.util.ArrayList;
import java.util.List;
+import java.util.Set;
+import java.util.SortedSet;
import java.util.Stack;
+import java.util.TreeSet;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
import javax.inject.Inject;
@@ -35,6 +39,8 @@ import org.apache.isis.applib.services.user.UserService;
import org.apache.isis.core.security.authentication.AuthenticationSession;
import org.apache.isis.core.security.authentication.AuthenticationSessionProvider;
+import static org.apache.isis.commons.internal.base._NullSafe.stream;
+
@DomainService(
nature = NatureOfService.DOMAIN,
menuOrder = "" + Integer.MAX_VALUE
@@ -51,12 +57,12 @@ public class UserServiceDefault implements UserService {
final String username = userAndRoleOverrides.user;
- final List<String> roles;
+ final Stream<String> roles;
if (userAndRoleOverrides.roles != null) {
- roles = userAndRoleOverrides.roles;
+ roles = userAndRoleOverrides.streamRoles();
} else {
// preserve the roles if were not overridden
- roles = previousRoles();
+ roles = streamPreviousRoles();
}
final List<RoleMemento> roleMementos = asRoleMementos(roles);
@@ -69,25 +75,23 @@ public class UserServiceDefault implements UserService {
}
}
- private List<String> previousRoles() {
- final List<String> roles;
-
+ private Stream<String> streamPreviousRoles() {
final AuthenticationSession session =
authenticationSessionProvider.getAuthenticationSession();
- roles = session.getRoles();
- return roles;
+
+ return session.streamRoles();
}
public static class UserAndRoleOverrides {
final String user;
- final List<String> roles;
+ final Set<String> roles;
UserAndRoleOverrides(final String user) {
this(user, null);
}
- UserAndRoleOverrides(final String user, final List<String> roles) {
+ UserAndRoleOverrides(final String user, final Set<String> roles) {
this.user = user;
this.roles = roles;
}
@@ -96,8 +100,8 @@ public class UserServiceDefault implements UserService {
return user;
}
- public List<String> getRoles() {
- return roles;
+ public Stream<String> streamRoles() {
+ return stream(roles);
}
}
@@ -109,9 +113,14 @@ public class UserServiceDefault implements UserService {
};
- private void overrideUserAndRoles(final String user, final List<String> rolesIfAny) {
- final List<String> roles = rolesIfAny != null ? rolesIfAny : inheritRoles();
- this.overrides.get().push(new UserAndRoleOverrides(user, roles));
+ private void overrideUserAndRoles(final String user, final Iterable<String> rolesIfAny) {
+
+ final Stream<String> roles = rolesIfAny != null
+ ? stream(rolesIfAny)
+ : inheritRoles();
+
+ final SortedSet<String> rolesSorted = roles.collect(Collectors.toCollection(TreeSet::new));
+ this.overrides.get().push(new UserAndRoleOverrides(user, rolesSorted));
}
private void resetOverrides() {
@@ -129,20 +138,18 @@ public class UserServiceDefault implements UserService {
: null;
}
- private List<String> inheritRoles() {
+ private Stream<String> inheritRoles() {
final UserAndRoleOverrides currentOverridesIfAny = currentOverridesIfAny();
return currentOverridesIfAny != null
- ? currentOverridesIfAny.getRoles()
- : authenticationSessionProvider.getAuthenticationSession().getRoles();
+ ? currentOverridesIfAny.streamRoles()
+ : authenticationSessionProvider.getAuthenticationSession().streamRoles();
}
- private static List<RoleMemento> asRoleMementos(final List<String> roles) {
- final List<RoleMemento> mementos = new ArrayList<RoleMemento>();
- if (roles != null) {
- for (final String role : roles) {
- mementos.add(new RoleMemento(role));
- }
- }
+ private static List<RoleMemento> asRoleMementos(final Stream<String> roles) {
+ final List<RoleMemento> mementos = stream(roles)
+ .map(RoleMemento::new)
+ .collect(Collectors.toList());
+
return mementos;
}
@@ -154,7 +161,7 @@ public class UserServiceDefault implements UserService {
public static class SudoServiceSpi implements SudoService.Spi {
@Override
- public void runAs(final String username, final List<String> roles) {
+ public void runAs(final String username, final Iterable<String> roles) {
userServiceDefault.overrideUserAndRoles(username, roles);
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/runtime/authorization/standard/AuthorizationManagerStandard.java b/core/metamodel/src/main/java/org/apache/isis/core/runtime/authorization/standard/AuthorizationManagerStandard.java
index b02f198..0c33591 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/runtime/authorization/standard/AuthorizationManagerStandard.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/runtime/authorization/standard/AuthorizationManagerStandard.java
@@ -19,8 +19,6 @@
package org.apache.isis.core.runtime.authorization.standard;
-import java.util.List;
-
import org.apache.isis.applib.Identifier;
import org.apache.isis.applib.services.sudo.SudoService;
import org.apache.isis.core.metamodel.progmodel.ProgrammingModel;
@@ -72,11 +70,12 @@ public class AuthorizationManagerStandard extends AuthorizationManagerAbstract {
if (authorizor.isUsableInAnyRole(identifier)) {
return true;
}
- for (final String roleName : session.getRoles()) {
- if (authorizor.isUsableInRole(roleName, identifier)) {
- return true;
- }
+
+ if(session.streamRoles()
+ .anyMatch(roleName->authorizor.isUsableInRole(roleName, identifier)) ) {
+ return true;
}
+
return false;
}
@@ -97,17 +96,15 @@ public class AuthorizationManagerStandard extends AuthorizationManagerAbstract {
if (authorizor.isVisibleInAnyRole(identifier)) {
return true;
}
- for (final String roleName : session.getRoles()) {
- if (authorizor.isVisibleInRole(roleName, identifier)) {
- return true;
- }
+ if(session.streamRoles()
+ .anyMatch(roleName->authorizor.isVisibleInRole(roleName, identifier)) ) {
+ return true;
}
return false;
}
private static boolean containsSudoSuperuserRole(final AuthenticationSession session) {
- final List<String> roles = session.getRoles();
- return roles != null && roles.contains(SudoService.ACCESS_ALL_ROLE);
+ return session.hasRole(SudoService.ACCESS_ALL_ROLE);
}
private boolean isPerspectiveMember(final Identifier identifier) {
diff --git a/core/plugins/security-shiro/src/main/java/org/apache/isis/security/shiro/ShiroAuthenticatorOrAuthorizor.java b/core/plugins/security-shiro/src/main/java/org/apache/isis/security/shiro/ShiroAuthenticatorOrAuthorizor.java
index d2a3e46..d62391e 100644
--- a/core/plugins/security-shiro/src/main/java/org/apache/isis/security/shiro/ShiroAuthenticatorOrAuthorizor.java
+++ b/core/plugins/security-shiro/src/main/java/org/apache/isis/security/shiro/ShiroAuthenticatorOrAuthorizor.java
@@ -20,8 +20,8 @@ package org.apache.isis.security.shiro;
import java.util.Collection;
import java.util.Collections;
-import java.util.List;
import java.util.Set;
+import java.util.stream.Stream;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.UnavailableSecurityManagerException;
@@ -44,7 +44,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.isis.applib.Identifier;
-import org.apache.isis.commons.internal.collections._Lists;
+import org.apache.isis.commons.internal.collections._Sets;
import org.apache.isis.core.security.authentication.AuthenticationRequest;
import org.apache.isis.core.security.authentication.AuthenticationRequestPassword;
import org.apache.isis.core.security.authentication.AuthenticationSession;
@@ -162,12 +162,19 @@ public class ShiroAuthenticatorOrAuthorizor implements Authenticator, Authorizor
}
}
- AuthenticationSession authenticationSessionFor(AuthenticationRequest request, String code, AuthenticationToken token, Subject currentSubject) {
- List<String> roles = getRoles(currentSubject, token);
- // copy over any roles passed in
- // (this is used by the Wicket viewer, for example).
- roles.addAll(request.getRoles());
-
+ AuthenticationSession authenticationSessionFor(
+ AuthenticationRequest request,
+ String code,
+ AuthenticationToken token,
+ Subject currentSubject) {
+
+ final Stream<String> roles = Stream.concat(
+ streamRoles(currentSubject, token),
+
+ // copy over any roles passed in
+ // (this is used by the Wicket viewer, for example).
+ request.streamRoles());
+
return new SimpleSession(request.getName(), roles, code);
}
@@ -176,12 +183,12 @@ public class ShiroAuthenticatorOrAuthorizor implements Authenticator, Authorizor
* in the future that might obtain the list of roles for a principal from
* somewhere other than Shiro's {@link RealmSecurityManager}.
*/
- protected List<String> getRoles(final Subject subject, final AuthenticationToken token) {
- final List<String> roles = _Lists.newArrayList();
+ protected Stream<String> streamRoles(final Subject subject, final AuthenticationToken token) {
+ final Set<String> roles = _Sets.newHashSet();
RealmSecurityManager securityManager = getSecurityManager();
if(securityManager == null) {
- return roles;
+ return Stream.empty();
}
final Set<String> realmNames = realmNamesOf(subject);
@@ -200,7 +207,7 @@ public class ShiroAuthenticatorOrAuthorizor implements Authenticator, Authorizor
}
}
}
- return roles;
+ return roles.stream();
}
private static Set<String> realmNamesOf(final Subject subject) {
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/authsess/AuthenticationSessionProviderDefault.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/authsess/AuthenticationSessionProviderDefault.java
index 0321983..555f580 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/authsess/AuthenticationSessionProviderDefault.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/authsess/AuthenticationSessionProviderDefault.java
@@ -16,7 +16,7 @@
*/
package org.apache.isis.core.runtime.services.authsess;
-import java.util.List;
+import java.util.stream.Stream;
import org.apache.isis.applib.annotation.DomainService;
import org.apache.isis.applib.annotation.NatureOfService;
@@ -50,7 +50,7 @@ public class AuthenticationSessionProviderDefault implements AuthenticationSessi
if(userAndRoleOverrides != null) {
final String user = userAndRoleOverrides.getUser();
- final List<String> roles = userAndRoleOverrides.getRoles();
+ final Stream<String> roles = userAndRoleOverrides.streamRoles();
return new SimpleSession(user, roles);
}
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/sudo/SudoServiceDefault.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/sudo/SudoServiceDefault.java
index e6eaf00..e8974ab 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/sudo/SudoServiceDefault.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/sudo/SudoServiceDefault.java
@@ -26,7 +26,6 @@ import org.apache.isis.applib.annotation.DomainService;
import org.apache.isis.applib.annotation.NatureOfService;
import org.apache.isis.applib.annotation.Programmatic;
import org.apache.isis.applib.services.sudo.SudoService;
-import org.apache.isis.applib.services.user.UserService;
@DomainService(
nature = NatureOfService.DOMAIN,
@@ -60,7 +59,7 @@ public class SudoServiceDefault implements SudoService {
@Programmatic
@Override
- public void sudo(final String username, final List<String> roles, final Runnable runnable) {
+ public void sudo(final String username, final Iterable<String> roles, final Runnable runnable) {
try {
runAs(username, roles);
runnable.run();
@@ -71,7 +70,7 @@ public class SudoServiceDefault implements SudoService {
@Programmatic
@Override
- public <T> T sudo(final String username, final List<String> roles, final Callable<T> callable) {
+ public <T> T sudo(final String username, final Iterable<String> roles, final Callable<T> callable) {
try {
runAs(username, roles);
return callable.call();
@@ -82,7 +81,7 @@ public class SudoServiceDefault implements SudoService {
}
}
- private void runAs(final String username, final List<String> roles) {
+ private void runAs(final String username, final Iterable<String> roles) {
if(spiServices != null) {
for (SudoService.Spi spiService : spiServices) {
spiService.runAs(username, roles);
@@ -98,10 +97,6 @@ public class SudoServiceDefault implements SudoService {
}
}
-
- @javax.inject.Inject
- private UserService userService;
-
@javax.inject.Inject
private List<Spi> spiServices;
diff --git a/core/runtime/src/test/java/org/apache/isis/core/runtime/authentication/standard/SimpleSessionEncodabilityTestAbstract.java b/core/runtime/src/test/java/org/apache/isis/core/runtime/authentication/standard/SimpleSessionEncodabilityTestAbstract.java
index 0886aae..af88f6a 100644
--- a/core/runtime/src/test/java/org/apache/isis/core/runtime/authentication/standard/SimpleSessionEncodabilityTestAbstract.java
+++ b/core/runtime/src/test/java/org/apache/isis/core/runtime/authentication/standard/SimpleSessionEncodabilityTestAbstract.java
@@ -19,13 +19,17 @@
package org.apache.isis.core.runtime.authentication.standard;
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertThat;
+import java.util.stream.Stream;
+import org.apache.isis.commons.internal.collections._Arrays;
import org.apache.isis.core.commons.encoding.EncodabilityContractTest;
import org.apache.isis.core.security.authentication.standard.SimpleSession;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertThat;
+
public abstract class SimpleSessionEncodabilityTestAbstract extends EncodabilityContractTest {
@Override
@@ -34,7 +38,16 @@ public abstract class SimpleSessionEncodabilityTestAbstract extends Encodability
final SimpleSession original = (SimpleSession) originalEncodable;
assertThat(decoded.getUserName(), is(equalTo(original.getUserName())));
- assertThat(decoded.getRoles(), is(equalTo(original.getRoles())));
+ assertArrayEquals(
+ orderedArray(decoded.streamRoles()),
+ orderedArray(original.streamRoles()));
}
+ // -- HELPER
+
+ private final String[] orderedArray(Stream<String> stream) {
+ return stream.sorted()
+ .collect(_Arrays.toArray(String.class));
+ }
+
}
diff --git a/core/security/src/main/java/org/apache/isis/core/security/authentication/AuthenticationRequest.java b/core/security/src/main/java/org/apache/isis/core/security/authentication/AuthenticationRequest.java
index e9ce204..1d7599a 100644
--- a/core/security/src/main/java/org/apache/isis/core/security/authentication/AuthenticationRequest.java
+++ b/core/security/src/main/java/org/apache/isis/core/security/authentication/AuthenticationRequest.java
@@ -19,14 +19,43 @@
package org.apache.isis.core.security.authentication;
-import java.util.List;
+import java.util.Collection;
+import java.util.stream.Stream;
-public interface AuthenticationRequest {
+import javax.annotation.Nullable;
+
+import static org.apache.isis.commons.internal.base._NullSafe.stream;
- String getName();
+public interface AuthenticationRequest {
- List<String> getRoles();
+ /**
+ * Account's name.
+ * @return nullable
+ */
+ public @Nullable String getName();
- void setRoles(List<String> roles);
+ /**
+ * Account's roles as Stream.
+ * @return non-null
+ * @since 2.0.0-M2
+ */
+ public Stream<String> streamRoles();
+
+ /**
+ * Add a role to associate with the account. Null or empty roles are ignored.
+ * @param role
+ * @since 2.0.0-M2
+ */
+ public void addRole(@Nullable String role);
+
+ /**
+ * Add a roles to associate with the account. Null or empty roles are ignored.
+ * @param roles
+ * @since 2.0.0-M2
+ */
+ public default void addRoles(@Nullable Collection<String> roles) {
+ stream(roles)
+ .forEach(this::addRole);
+ }
}
diff --git a/core/security/src/main/java/org/apache/isis/core/security/authentication/AuthenticationRequestAbstract.java b/core/security/src/main/java/org/apache/isis/core/security/authentication/AuthenticationRequestAbstract.java
index 8d7fd8d..0b62ef9 100644
--- a/core/security/src/main/java/org/apache/isis/core/security/authentication/AuthenticationRequestAbstract.java
+++ b/core/security/src/main/java/org/apache/isis/core/security/authentication/AuthenticationRequestAbstract.java
@@ -19,15 +19,16 @@
package org.apache.isis.core.security.authentication;
-import java.util.Collections;
-import java.util.List;
+import java.util.Set;
+import java.util.stream.Stream;
-import org.apache.isis.commons.internal.collections._Lists;
+import org.apache.isis.commons.internal.base._Strings;
+import org.apache.isis.commons.internal.collections._Sets;
public abstract class AuthenticationRequestAbstract implements AuthenticationRequest {
private final String name;
- private final List<String> roles = _Lists.newArrayList();
+ private final Set<String> roles = _Sets.newHashSet();
public AuthenticationRequestAbstract(final String name) {
this.name = name;
@@ -39,14 +40,16 @@ public abstract class AuthenticationRequestAbstract implements AuthenticationReq
}
@Override
- public List<String> getRoles() {
- return Collections.unmodifiableList(roles);
+ public Stream<String> streamRoles() {
+ return roles.stream();
}
-
+
@Override
- public void setRoles(final List<String> roles) {
- this.roles.clear();
- this.roles.addAll(roles);
+ public void addRole(String role) {
+ if(_Strings.isNullOrEmpty(role)) {
+ return; // ignore
+ }
+ this.roles.add(role);
}
}
diff --git a/core/security/src/main/java/org/apache/isis/core/security/authentication/AuthenticationSession.java b/core/security/src/main/java/org/apache/isis/core/security/authentication/AuthenticationSession.java
index 59a4f62..2424d32 100644
--- a/core/security/src/main/java/org/apache/isis/core/security/authentication/AuthenticationSession.java
+++ b/core/security/src/main/java/org/apache/isis/core/security/authentication/AuthenticationSession.java
@@ -20,7 +20,7 @@
package org.apache.isis.core.security.authentication;
import java.io.Serializable;
-import java.util.List;
+import java.util.stream.Stream;
import org.apache.isis.applib.security.UserMemento;
import org.apache.isis.core.commons.encoding.Encodable;
@@ -39,8 +39,16 @@ public interface AuthenticationSession extends Encodable, Serializable {
/**
* The roles this user belongs to
+ * @since 2.0.0-M2
*/
- List<String> getRoles();
+ Stream<String> streamRoles();
+
+ /**
+ * Whether this user has specified {@code role}
+ * @param role
+ * @since 2.0.0-M2
+ */
+ boolean hasRole(String role);
/**
* A unique code given to this session during authentication.
@@ -69,4 +77,7 @@ public interface AuthenticationSession extends Encodable, Serializable {
MessageBroker getMessageBroker();
UserMemento createUserMemento();
+
+
+
}
diff --git a/core/security/src/main/java/org/apache/isis/core/security/authentication/AuthenticationSessionAbstract.java b/core/security/src/main/java/org/apache/isis/core/security/authentication/AuthenticationSessionAbstract.java
index 0c7b56d..19d1ada 100644
--- a/core/security/src/main/java/org/apache/isis/core/security/authentication/AuthenticationSessionAbstract.java
+++ b/core/security/src/main/java/org/apache/isis/core/security/authentication/AuthenticationSessionAbstract.java
@@ -21,21 +21,25 @@ package org.apache.isis.core.security.authentication;
import java.io.IOException;
import java.io.Serializable;
-import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Stream;
import org.apache.isis.applib.security.RoleMemento;
import org.apache.isis.applib.security.UserMemento;
import org.apache.isis.applib.util.ToString;
+import org.apache.isis.commons.internal.base._Strings;
import org.apache.isis.commons.internal.collections._Lists;
+import org.apache.isis.commons.internal.collections._Sets;
import org.apache.isis.core.commons.encoding.DataInputExtended;
import org.apache.isis.core.commons.encoding.DataOutputExtended;
+import static org.apache.isis.commons.internal.base._NullSafe.stream;
+
public abstract class AuthenticationSessionAbstract implements AuthenticationSession, Serializable {
private static final long serialVersionUID = 1L;
@@ -43,22 +47,24 @@ public abstract class AuthenticationSessionAbstract implements AuthenticationSes
// -- Constructor, fields
private final String name;
- private final List<String> roles = new ArrayList<String>();
+ private final Set<String> roles = _Sets.newHashSet();
private final String validationCode;
private final Map<String, Object> attributeByName = new HashMap<String, Object>();
private final MessageBroker messageBroker;
-
- @SuppressWarnings("unchecked")
public AuthenticationSessionAbstract(final String name, final String code) {
- this(name, Collections.EMPTY_LIST, code);
+ this(name, Stream.of(), code);
}
- public AuthenticationSessionAbstract(final String name, final List<String> roles, final String validationCode) {
+ public AuthenticationSessionAbstract(final String name, final Stream<String> roleStream, final String validationCode) {
this.name = name;
- this.roles.addAll(roles);
+
+ stream(roleStream)
+ .filter(_Strings::isNotEmpty)
+ .forEach(this.roles::add);
+
this.validationCode = validationCode;
this.messageBroker = new MessageBroker();
// nothing to do
@@ -72,8 +78,6 @@ public abstract class AuthenticationSessionAbstract implements AuthenticationSes
// nothing to do
}
-
-
// -- encode
@Override
@@ -83,8 +87,6 @@ public abstract class AuthenticationSessionAbstract implements AuthenticationSes
output.writeUTF(validationCode);
}
-
-
// -- User Name
@Override
@@ -97,20 +99,18 @@ public abstract class AuthenticationSessionAbstract implements AuthenticationSes
return Objects.equals(userName, getUserName());
}
-
-
// -- Roles
- /**
- * Can be overridden.
- */
@Override
- public List<String> getRoles() {
- return Collections.unmodifiableList(roles);
+ public Stream<String> streamRoles() {
+ return roles.stream();
}
-
-
+ @Override
+ public boolean hasRole(String role) {
+ return roles.contains(role);
+ }
+
// -- Validation Code
@Override
@@ -118,8 +118,6 @@ public abstract class AuthenticationSessionAbstract implements AuthenticationSes
return validationCode;
}
-
-
// -- Attributes
@Override
@@ -132,8 +130,6 @@ public abstract class AuthenticationSessionAbstract implements AuthenticationSes
attributeByName.put(attributeName, attribute);
}
-
-
// -- MessageBroker
@Override
@@ -141,14 +137,12 @@ public abstract class AuthenticationSessionAbstract implements AuthenticationSes
return messageBroker;
}
-
-
// -- createUserMemento
@Override
public UserMemento createUserMemento() {
final List<RoleMemento> roles = _Lists.newArrayList();
- for (final String roleName : getRoles()) {
+ for (final String roleName : this.roles) {
roles.add(new RoleMemento(roleName));
}
return new UserMemento(getUserName(), roles);
diff --git a/core/security/src/main/java/org/apache/isis/core/security/authentication/fixtures/AuthenticationRequestLogonFixture.java b/core/security/src/main/java/org/apache/isis/core/security/authentication/fixtures/AuthenticationRequestLogonFixture.java
index 276894b..a2bc959 100644
--- a/core/security/src/main/java/org/apache/isis/core/security/authentication/fixtures/AuthenticationRequestLogonFixture.java
+++ b/core/security/src/main/java/org/apache/isis/core/security/authentication/fixtures/AuthenticationRequestLogonFixture.java
@@ -19,8 +19,8 @@
package org.apache.isis.core.security.authentication.fixtures;
+import java.util.Collection;
import java.util.Collections;
-import java.util.List;
import org.apache.isis.commons.internal.collections._Lists;
import org.apache.isis.core.security.authentication.AuthenticationRequestAbstract;
@@ -41,9 +41,9 @@ public class AuthenticationRequestLogonFixture extends AuthenticationRequestAbst
: _Lists.of(roles));
}
- public AuthenticationRequestLogonFixture(final String name, final List<String> roles) {
+ public AuthenticationRequestLogonFixture(final String name, final Collection<String> roles) {
super(name);
- setRoles(roles);
+ addRoles(roles);
}
}
diff --git a/core/security/src/main/java/org/apache/isis/core/security/authentication/health/HealthAuthSession.java b/core/security/src/main/java/org/apache/isis/core/security/authentication/health/HealthAuthSession.java
index 6a4dc9b..d567594 100644
--- a/core/security/src/main/java/org/apache/isis/core/security/authentication/health/HealthAuthSession.java
+++ b/core/security/src/main/java/org/apache/isis/core/security/authentication/health/HealthAuthSession.java
@@ -20,7 +20,7 @@
package org.apache.isis.core.security.authentication.health;
import java.io.IOException;
-import java.util.Arrays;
+import java.util.stream.Stream;
import org.apache.isis.core.commons.encoding.DataInputExtended;
import org.apache.isis.core.security.authentication.AuthenticationSessionAbstract;
@@ -34,7 +34,7 @@ public class HealthAuthSession extends AuthenticationSessionAbstract {
private static final String CODE = "";
public HealthAuthSession() {
- super(USER_NAME, Arrays.asList(ROLE), CODE);
+ super(USER_NAME, Stream.of(ROLE), CODE);
}
public HealthAuthSession(final DataInputExtended input) throws IOException {
diff --git a/core/security/src/main/java/org/apache/isis/core/security/authentication/singleuser/AuthenticationRequestSingleUser.java b/core/security/src/main/java/org/apache/isis/core/security/authentication/singleuser/AuthenticationRequestSingleUser.java
index 38fac9b..e679dbf 100644
--- a/core/security/src/main/java/org/apache/isis/core/security/authentication/singleuser/AuthenticationRequestSingleUser.java
+++ b/core/security/src/main/java/org/apache/isis/core/security/authentication/singleuser/AuthenticationRequestSingleUser.java
@@ -19,10 +19,6 @@
package org.apache.isis.core.security.authentication.singleuser;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
import org.apache.isis.core.security.authentication.AuthenticationRequestAbstract;
/**
@@ -31,17 +27,11 @@ import org.apache.isis.core.security.authentication.AuthenticationRequestAbstrac
public class AuthenticationRequestSingleUser extends AuthenticationRequestAbstract {
private static final String SINGLE_USER_NAME = "self";
- private static final String SINGLE_USER_ROlE_NAME = "default_role";
- private final List<String> roles;
+ private static final String SINGLE_USER_ROLE_NAME = "default_role";
public AuthenticationRequestSingleUser() {
super(SINGLE_USER_NAME);
- roles = Collections.unmodifiableList(Arrays.asList(SINGLE_USER_ROlE_NAME));
- }
-
- @Override
- public List<String> getRoles() {
- return roles;
+ addRole(SINGLE_USER_ROLE_NAME);
}
}
diff --git a/core/security/src/main/java/org/apache/isis/core/security/authentication/standard/AuthenticatorAbstract.java b/core/security/src/main/java/org/apache/isis/core/security/authentication/standard/AuthenticatorAbstract.java
index 2b46972..e16bd77 100644
--- a/core/security/src/main/java/org/apache/isis/core/security/authentication/standard/AuthenticatorAbstract.java
+++ b/core/security/src/main/java/org/apache/isis/core/security/authentication/standard/AuthenticatorAbstract.java
@@ -47,7 +47,7 @@ public abstract class AuthenticatorAbstract implements Authenticator {
if (!isValid(request)) {
return null;
}
- return new SimpleSession(request.getName(), request.getRoles(), code);
+ return new SimpleSession(request.getName(), request.streamRoles(), code);
}
diff --git a/core/security/src/main/java/org/apache/isis/core/security/authentication/standard/SimpleSession.java b/core/security/src/main/java/org/apache/isis/core/security/authentication/standard/SimpleSession.java
index 22ee9e6..839abab 100644
--- a/core/security/src/main/java/org/apache/isis/core/security/authentication/standard/SimpleSession.java
+++ b/core/security/src/main/java/org/apache/isis/core/security/authentication/standard/SimpleSession.java
@@ -20,39 +20,48 @@
package org.apache.isis.core.security.authentication.standard;
import java.io.IOException;
-import java.util.Arrays;
-import java.util.List;
+import java.util.stream.Stream;
import org.apache.isis.core.commons.encoding.DataInputExtended;
import org.apache.isis.core.security.authentication.AuthenticationSessionAbstract;
+import static org.apache.isis.commons.internal.base._NullSafe.stream;
+
public class SimpleSession extends AuthenticationSessionAbstract {
private static final long serialVersionUID = 1L;
+ private static final String DEFAULT_VALIDATION_CODE = "";
// ///////////////////////////////////////////////////////////////
// Constructor, encode
// ///////////////////////////////////////////////////////////////
/**
- * as per {@link #SimpleSession(String, List)}.
+ * Defaults {@link #getValidationCode()} to empty string (<tt>""</tt>).
*/
public SimpleSession(final String name, final String[] roles) {
- this(name, Arrays.asList(roles));
+ this(name, stream(roles), DEFAULT_VALIDATION_CODE);
}
/**
* Defaults {@link #getValidationCode()} to empty string (<tt>""</tt>).
*/
- public SimpleSession(final String name, final List<String> roles) {
- this(name, roles, "");
+ public SimpleSession(final String name, final Iterable<String> roles) {
+ this(name, stream(roles), DEFAULT_VALIDATION_CODE);
+ }
+
+ /**
+ * Defaults {@link #getValidationCode()} to empty string (<tt>""</tt>).
+ */
+ public SimpleSession(final String name, final Stream<String> roles) {
+ this(name, roles, DEFAULT_VALIDATION_CODE);
}
public SimpleSession(final String name, final String[] roles, final String code) {
- this(name, Arrays.asList(roles), code);
+ this(name, stream(roles), code);
}
- public SimpleSession(final String name, final List<String> roles, final String code) {
+ public SimpleSession(final String name, final Stream<String> roles, final String code) {
super(name, roles, code);
}
diff --git a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/UserReprRenderer.java b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/UserReprRenderer.java
index 0a5d525..497701a 100644
--- a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/UserReprRenderer.java
+++ b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/UserReprRenderer.java
@@ -35,9 +35,10 @@ public class UserReprRenderer extends ReprRendererAbstract<UserReprRenderer, Aut
public UserReprRenderer with(final AuthenticationSession authenticationSession) {
representation.mapPut("userName", authenticationSession.getUserName());
final JsonRepresentation roles = JsonRepresentation.newArray();
- for (final String role : authenticationSession.getRoles()) {
- roles.arrayAdd(role);
- }
+
+ authenticationSession.streamRoles()
+ .forEach(roles::arrayAdd);
+
representation.mapPut("roles", roles);
return this;
}
diff --git a/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/integration/wicket/AuthenticatedWebSessionForIsis.java b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/integration/wicket/AuthenticatedWebSessionForIsis.java
index 8582b40..72c268f 100644
--- a/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/integration/wicket/AuthenticatedWebSessionForIsis.java
+++ b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/integration/wicket/AuthenticatedWebSessionForIsis.java
@@ -19,11 +19,14 @@
package org.apache.isis.viewer.wicket.viewer.integration.wicket;
-import java.util.Arrays;
-import java.util.List;
-
import javax.validation.constraints.NotNull;
+import org.apache.wicket.Session;
+import org.apache.wicket.authroles.authentication.AuthenticatedWebSession;
+import org.apache.wicket.authroles.authorization.strategies.role.Roles;
+import org.apache.wicket.request.Request;
+import org.apache.wicket.request.cycle.RequestCycle;
+
import org.apache.isis.applib.clock.Clock;
import org.apache.isis.applib.services.session.SessionLoggingService;
import org.apache.isis.core.runtime.system.context.IsisContext;
@@ -36,11 +39,6 @@ import org.apache.isis.viewer.wicket.model.models.BookmarkedPagesModel;
import org.apache.isis.viewer.wicket.ui.components.widgets.breadcrumbs.BreadcrumbModel;
import org.apache.isis.viewer.wicket.ui.components.widgets.breadcrumbs.BreadcrumbModelProvider;
import org.apache.isis.viewer.wicket.ui.pages.BookmarkedPagesModelProvider;
-import org.apache.wicket.Session;
-import org.apache.wicket.authroles.authentication.AuthenticatedWebSession;
-import org.apache.wicket.authroles.authorization.strategies.role.Roles;
-import org.apache.wicket.request.Request;
-import org.apache.wicket.request.cycle.RequestCycle;
/**
* Viewer-specific implementation of {@link AuthenticatedWebSession}, which
@@ -70,7 +68,7 @@ public class AuthenticatedWebSessionForIsis extends AuthenticatedWebSession impl
@Override
public synchronized boolean authenticate(final String username, final String password) {
AuthenticationRequest authenticationRequest = new AuthenticationRequestPassword(username, password);
- authenticationRequest.setRoles(Arrays.asList(USER_ROLE));
+ authenticationRequest.addRole(USER_ROLE);
authenticationSession = getAuthenticationManager().authenticate(authenticationRequest);
if (authenticationSession != null) {
log(SessionLoggingService.Type.LOGIN, username, null);
@@ -129,8 +127,11 @@ public class AuthenticatedWebSessionForIsis extends AuthenticatedWebSession impl
if (!isSignedIn()) {
return null;
}
- final List<String> roles = authenticationSession.getRoles();
- return new Roles(roles.toArray(new String[roles.size()]));
+
+ final Roles roles = new Roles();
+ authenticationSession.streamRoles()
+ .forEach(roles::add);
+ return roles;
}
@Override