remove GroupNames and ExternalGroupNames in favor of GroupCollector

This commit is contained in:
Eduard Heimbuch
2019-08-02 09:32:44 +02:00
parent 8550baaea9
commit 442aacbcdb
16 changed files with 100 additions and 566 deletions

View File

@@ -1,22 +0,0 @@
package sonia.scm.group;
import java.util.Collection;
/**
* This class represents all associated groups which are provided by external systems for a certain user.
*
* @author Sebastian Sdorra
* @since 2.0.0
*/
public class ExternalGroupNames extends GroupNames {
public ExternalGroupNames() {
}
public ExternalGroupNames(String groupName, String... groupNames) {
super(groupName, groupNames);
}
public ExternalGroupNames(Collection<String> collection) {
super(collection);
}
}

View File

@@ -1,187 +0,0 @@
/**
* Copyright (c) 2010, Sebastian Sdorra
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of SCM-Manager; nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.group;
//~--- non-JDK imports --------------------------------------------------------
import com.google.common.base.Joiner;
import com.google.common.base.Objects;
import com.google.common.collect.Lists;
import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
//~--- JDK imports ------------------------------------------------------------
/**
* This class represents all associated groups for a user.
*
* @author Sebastian Sdorra
* @since 1.21
*/
public class GroupNames implements Serializable, Iterable<String>
{
/**
* Group for all authenticated users
* @since 1.31
*/
public static final String AUTHENTICATED = "_authenticated";
/** Field description */
private static final long serialVersionUID = 8615685985213897947L;
//~--- constructors ---------------------------------------------------------
/**
* Constructs ...
*
*/
public GroupNames()
{
this(Collections.emptyList());
}
/**
* Constructs ...
*
*
* @param groupName
* @param groupNames
*/
public GroupNames(String groupName, String... groupNames)
{
this(Lists.asList(groupName, groupNames));
}
/**
* Constructs ...
*
*
* @param collection
*/
public GroupNames(Collection<String> collection)
{
this.collection = Collections.unmodifiableCollection(collection);
}
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @param groupName
*
* @return
*/
public boolean contains(String groupName)
{
return collection.contains(groupName);
}
/**
* {@inheritDoc}
*/
@Override
public boolean equals(Object obj)
{
if (obj == null)
{
return false;
}
if (getClass() != obj.getClass())
{
return false;
}
final GroupNames other = (GroupNames) obj;
return Objects.equal(collection, other.collection);
}
/**
* {@inheritDoc}
*/
@Override
public int hashCode()
{
return Objects.hashCode(collection);
}
/**
* Method description
*
*
* @return
*/
@Override
public Iterator<String> iterator()
{
return collection.iterator();
}
/**
* Method description
*
*
* @return
*/
@Override
public String toString()
{
return Joiner.on(", ").join(collection);
}
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*
* @return
*/
public Collection<String> getCollection()
{
return collection;
}
//~--- fields ---------------------------------------------------------------
/** Field description */
private final Collection<String> collection;
}

View File

@@ -99,15 +99,6 @@ public interface AccessTokenBuilder {
*/
AccessTokenBuilder scope(Scope scope);
/**
* Define the logged in user as member of the given groups.
*
* @param groups group names
*
* @return {@code this}
*/
AccessTokenBuilder groups(String... groups);
/**
* Creates a new {@link AccessToken} with the provided settings.
*

View File

@@ -31,7 +31,6 @@
package sonia.scm.security;
import sonia.scm.cache.CacheManager;
import sonia.scm.group.GroupDAO;
import sonia.scm.user.UserDAO;
import javax.inject.Inject;
@@ -47,21 +46,17 @@ public final class DAORealmHelperFactory {
private final LoginAttemptHandler loginAttemptHandler;
private final UserDAO userDAO;
private final CacheManager cacheManager;
private final GroupResolver groupResolver;
/**
* Constructs a new instance.
* @param loginAttemptHandler login attempt handler
* @param userDAO user dao
* @param groupDAO group dao
* @param cacheManager
* @param groupResolver
*/
@Inject
public DAORealmHelperFactory(LoginAttemptHandler loginAttemptHandler, UserDAO userDAO, GroupDAO groupDAO, CacheManager cacheManager, GroupResolver groupResolver) {
public DAORealmHelperFactory(LoginAttemptHandler loginAttemptHandler, UserDAO userDAO, CacheManager cacheManager) {
this.loginAttemptHandler = loginAttemptHandler;
this.userDAO = userDAO;
this.groupResolver = groupResolver;
this.cacheManager = cacheManager;
}

View File

@@ -32,25 +32,15 @@ import com.google.inject.Inject;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sonia.scm.AlreadyExistsException;
import sonia.scm.NotFoundException;
import sonia.scm.cache.CacheManager;
import sonia.scm.group.ExternalGroupNames;
import sonia.scm.group.Group;
import sonia.scm.group.GroupDAO;
import sonia.scm.group.GroupManager;
import sonia.scm.plugin.Extension;
import sonia.scm.user.User;
import sonia.scm.user.UserManager;
import sonia.scm.web.security.AdministrationContext;
import java.util.Collection;
import java.util.Collections;
import static java.util.Arrays.asList;
/**
* Helper class for syncing realms. The class should simplify the creation of realms, which are syncing authenticated
* users with the local database.
@@ -61,12 +51,9 @@ import static java.util.Arrays.asList;
@Extension
public final class SyncingRealmHelper {
private static final Logger LOG = LoggerFactory.getLogger(SyncingRealmHelper.class);
private final AdministrationContext ctx;
private final UserManager userManager;
private final GroupManager groupManager;
private final CacheManager cacheManager;
/**
* Constructs a new SyncingRealmHelper.
@@ -74,133 +61,28 @@ public final class SyncingRealmHelper {
* @param ctx administration context
* @param userManager user manager
* @param groupManager group manager
* @param groupDAO group dao
*/
@Inject
public SyncingRealmHelper(AdministrationContext ctx, UserManager userManager, GroupManager groupManager, GroupDAO groupDAO, CacheManager cacheManager) {
public SyncingRealmHelper(AdministrationContext ctx, UserManager userManager, GroupManager groupManager) {
this.ctx = ctx;
this.userManager = userManager;
this.groupManager = groupManager;
this.cacheManager = cacheManager;
}
/**
* Create {@link AuthenticationInfo} from user and groups.
*/
public AuthenticationInfoBuilder.ForRealm authenticationInfo() {
return new AuthenticationInfoBuilder().new ForRealm();
}
public class AuthenticationInfoBuilder {
private String realm;
private User user;
private Collection<String> groups = Collections.emptySet();
private Collection<String> externalGroups = Collections.emptySet();
private AuthenticationInfo build() {
return SyncingRealmHelper.this.createAuthenticationInfo(realm, user, groups, externalGroups);
}
public class ForRealm {
private ForRealm() {
}
/**
* Sets the realm.
* @param realm name of the realm
*/
public ForUser forRealm(String realm) {
AuthenticationInfoBuilder.this.realm = realm;
return AuthenticationInfoBuilder.this.new ForUser();
}
}
public class ForUser {
private ForUser() {
}
/**
* Sets the user.
* @param user authenticated user
*/
public AuthenticationInfoBuilder.WithGroups andUser(User user) {
AuthenticationInfoBuilder.this.user = user;
return AuthenticationInfoBuilder.this.new WithGroups();
}
}
public class WithGroups {
private WithGroups() {
}
/**
* Set the internal groups for the user.
* @param groups groups of the authenticated user
* @return builder step for groups
*/
public WithGroups withGroups(String... groups) {
return withGroups(asList(groups));
}
/**
* Set the internal groups for the user.
* @param groups groups of the authenticated user
* @return builder step for groups
*/
public WithGroups withGroups(Collection<String> groups) {
AuthenticationInfoBuilder.this.groups = groups;
return this;
}
/**
* Set the external groups for the user.
* @param externalGroups external groups of the authenticated user
* @return builder step for groups
*/
public WithGroups withExternalGroups(String... externalGroups) {
return withExternalGroups(asList(externalGroups));
}
/**
* Set the external groups for the user.
* @param externalGroups external groups of the authenticated user
* @return builder step for groups
*/
public WithGroups withExternalGroups(Collection<String> externalGroups) {
AuthenticationInfoBuilder.this.externalGroups = externalGroups;
return this;
}
/**
* Builds the {@link AuthenticationInfo} from the given options.
*
* @return complete autentication info
*/
public AuthenticationInfo build() {
return AuthenticationInfoBuilder.this.build();
}
}
}
//~--- methods --------------------------------------------------------------
/**
* Create {@link AuthenticationInfo} from user and groups.
*
*
* @param realm name of the realm
* @param user authenticated user
* @param groups groups of the authenticated user
*
* @return authentication info
*/
private AuthenticationInfo createAuthenticationInfo(String realm, User user,
Collection<String> groups, Collection<String> externalGroups) {
public AuthenticationInfo createAuthenticationInfo(String realm, User user) {
SimplePrincipalCollection collection = new SimplePrincipalCollection();
collection.add(user.getId(), realm);
collection.add(user, realm);
collection.add(new ExternalGroupNames(externalGroups), realm);
return new SimpleAuthenticationInfo(collection, user.getPassword());
}

View File

@@ -37,17 +37,13 @@ package sonia.scm.security;
import com.google.common.base.Throwables;
import org.apache.shiro.authc.AuthenticationInfo;
import org.assertj.core.api.Assertions;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import sonia.scm.AlreadyExistsException;
import sonia.scm.cache.CacheManager;
import sonia.scm.group.ExternalGroupNames;
import sonia.scm.group.Group;
import sonia.scm.group.GroupDAO;
import sonia.scm.group.GroupManager;
import sonia.scm.user.User;
import sonia.scm.user.UserManager;
@@ -81,12 +77,6 @@ public class SyncingRealmHelperTest {
@Mock
private UserManager userManager;
@Mock
private GroupDAO groupDAO;
@Mock
CacheManager cacheManager;
private SyncingRealmHelper helper;
/**
@@ -112,7 +102,7 @@ public class SyncingRealmHelperTest {
}
};
helper = new SyncingRealmHelper(ctx, userManager, groupManager, groupDAO, cacheManager);
helper = new SyncingRealmHelper(ctx, userManager, groupManager);
}
/**
@@ -189,27 +179,11 @@ public class SyncingRealmHelperTest {
verify(userManager, times(1)).modify(user);
}
@Test
public void builderShouldSetExternalGroups() {
AuthenticationInfo authenticationInfo = helper
.authenticationInfo()
.forRealm("unit-test")
.andUser(new User("ziltoid"))
.withExternalGroups("external")
.build();
ExternalGroupNames groupNames = authenticationInfo.getPrincipals().oneByType(ExternalGroupNames.class);
Assertions.assertThat(groupNames.getCollection()).containsOnly("external");
}
@Test
public void builderShouldSetValues() {
User user = new User("ziltoid");
AuthenticationInfo authInfo = helper
.authenticationInfo()
.forRealm("unit-test")
.andUser(user)
.build();
AuthenticationInfo authInfo = helper.createAuthenticationInfo("unit-test", user);
assertNotNull(authInfo);
assertEquals("ziltoid", authInfo.getPrincipals().getPrimaryPrincipal());