mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-13 17:05:43 +01:00
Get verbs from repository roles
This commit is contained in:
@@ -52,7 +52,6 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import sonia.scm.cache.Cache;
|
import sonia.scm.cache.Cache;
|
||||||
import sonia.scm.cache.CacheManager;
|
import sonia.scm.cache.CacheManager;
|
||||||
import sonia.scm.config.ScmConfiguration;
|
|
||||||
import sonia.scm.group.GroupNames;
|
import sonia.scm.group.GroupNames;
|
||||||
import sonia.scm.group.GroupPermissions;
|
import sonia.scm.group.GroupPermissions;
|
||||||
import sonia.scm.plugin.Extension;
|
import sonia.scm.plugin.Extension;
|
||||||
@@ -64,7 +63,6 @@ import sonia.scm.user.UserPermissions;
|
|||||||
import sonia.scm.util.Util;
|
import sonia.scm.util.Util;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
//~--- JDK imports ------------------------------------------------------------
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
@@ -90,18 +88,19 @@ public class DefaultAuthorizationCollector implements AuthorizationCollector
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs ...
|
* Constructs ...
|
||||||
*
|
|
||||||
* @param cacheManager
|
* @param cacheManager
|
||||||
* @param repositoryDAO
|
* @param repositoryDAO
|
||||||
* @param securitySystem
|
* @param securitySystem
|
||||||
|
* @param repositoryPermissionProvider
|
||||||
*/
|
*/
|
||||||
@Inject
|
@Inject
|
||||||
public DefaultAuthorizationCollector(CacheManager cacheManager,
|
public DefaultAuthorizationCollector(CacheManager cacheManager,
|
||||||
RepositoryDAO repositoryDAO, SecuritySystem securitySystem)
|
RepositoryDAO repositoryDAO, SecuritySystem securitySystem, RepositoryPermissionProvider repositoryPermissionProvider)
|
||||||
{
|
{
|
||||||
this.cache = cacheManager.getCache(CACHE_NAME);
|
this.cache = cacheManager.getCache(CACHE_NAME);
|
||||||
this.repositoryDAO = repositoryDAO;
|
this.repositoryDAO = repositoryDAO;
|
||||||
this.securitySystem = securitySystem;
|
this.securitySystem = securitySystem;
|
||||||
|
this.repositoryPermissionProvider = repositoryPermissionProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
//~--- methods --------------------------------------------------------------
|
//~--- methods --------------------------------------------------------------
|
||||||
@@ -201,16 +200,8 @@ public class DefaultAuthorizationCollector implements AuthorizationCollector
|
|||||||
for (RepositoryPermission permission : repositoryPermissions)
|
for (RepositoryPermission permission : repositoryPermissions)
|
||||||
{
|
{
|
||||||
hasPermission = isUserPermitted(user, groups, permission);
|
hasPermission = isUserPermitted(user, groups, permission);
|
||||||
if (hasPermission && !permission.getVerbs().isEmpty())
|
if (hasPermission) {
|
||||||
{
|
addRepositoryPermission(builder, repository, user, hasPermission, permission);
|
||||||
String perm = "repository:" + String.join(",", permission.getVerbs()) + ":" + repository.getId();
|
|
||||||
if (logger.isTraceEnabled())
|
|
||||||
{
|
|
||||||
logger.trace("add repository permission {} for user {} at repository {}",
|
|
||||||
perm, user.getName(), repository.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.add(perm);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,6 +217,29 @@ public class DefaultAuthorizationCollector implements AuthorizationCollector
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addRepositoryPermission(Builder<String> builder, Repository repository, User user, boolean hasPermission, RepositoryPermission permission) {
|
||||||
|
Collection<String> verbs = getVerbs(permission);
|
||||||
|
if (!verbs.isEmpty())
|
||||||
|
{
|
||||||
|
String perm = "repository:" + String.join(",", verbs) + ":" + repository.getId();
|
||||||
|
if (logger.isTraceEnabled())
|
||||||
|
{
|
||||||
|
logger.trace("add repository permission {} for user {} at repository {}",
|
||||||
|
perm, user.getName(), repository.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.add(perm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Collection<String> getVerbs(RepositoryPermission permission) {
|
||||||
|
return permission.getRole() == null? permission.getVerbs(): getVerbsForRole(permission.getRole());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Collection<String> getVerbsForRole(String roleName) {
|
||||||
|
return repositoryPermissionProvider.availableRoles().stream().filter(role -> roleName.equals(role.getName())).findFirst().orElseThrow(() -> new RuntimeException()).getVerbs();
|
||||||
|
}
|
||||||
|
|
||||||
private AuthorizationInfo createAuthorizationInfo(User user, GroupNames groups) {
|
private AuthorizationInfo createAuthorizationInfo(User user, GroupNames groups) {
|
||||||
Builder<String> builder = ImmutableSet.builder();
|
Builder<String> builder = ImmutableSet.builder();
|
||||||
|
|
||||||
@@ -353,4 +367,6 @@ public class DefaultAuthorizationCollector implements AuthorizationCollector
|
|||||||
|
|
||||||
/** security system */
|
/** security system */
|
||||||
private final SecuritySystem securitySystem;
|
private final SecuritySystem securitySystem;
|
||||||
|
|
||||||
|
private final RepositoryPermissionProvider repositoryPermissionProvider;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,10 +33,10 @@ package sonia.scm.security;
|
|||||||
|
|
||||||
import com.github.sdorra.shiro.ShiroRule;
|
import com.github.sdorra.shiro.ShiroRule;
|
||||||
import com.github.sdorra.shiro.SubjectAware;
|
import com.github.sdorra.shiro.SubjectAware;
|
||||||
import com.google.common.collect.ImmutableSet;
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import org.apache.shiro.authz.AuthorizationInfo;
|
import org.apache.shiro.authz.AuthorizationInfo;
|
||||||
import org.apache.shiro.authz.SimpleAuthorizationInfo;
|
import org.apache.shiro.authz.SimpleAuthorizationInfo;
|
||||||
|
import org.apache.shiro.subject.PrincipalCollection;
|
||||||
import org.apache.shiro.subject.SimplePrincipalCollection;
|
import org.apache.shiro.subject.SimplePrincipalCollection;
|
||||||
import org.apache.shiro.subject.Subject;
|
import org.apache.shiro.subject.Subject;
|
||||||
import org.hamcrest.Matchers;
|
import org.hamcrest.Matchers;
|
||||||
@@ -49,11 +49,11 @@ import org.mockito.Mockito;
|
|||||||
import org.mockito.junit.MockitoJUnitRunner;
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
import sonia.scm.cache.Cache;
|
import sonia.scm.cache.Cache;
|
||||||
import sonia.scm.cache.CacheManager;
|
import sonia.scm.cache.CacheManager;
|
||||||
import sonia.scm.config.ScmConfiguration;
|
|
||||||
import sonia.scm.group.GroupNames;
|
import sonia.scm.group.GroupNames;
|
||||||
import sonia.scm.repository.Repository;
|
import sonia.scm.repository.Repository;
|
||||||
import sonia.scm.repository.RepositoryDAO;
|
import sonia.scm.repository.RepositoryDAO;
|
||||||
import sonia.scm.repository.RepositoryPermission;
|
import sonia.scm.repository.RepositoryPermission;
|
||||||
|
import sonia.scm.repository.RepositoryRole;
|
||||||
import sonia.scm.repository.RepositoryTestData;
|
import sonia.scm.repository.RepositoryTestData;
|
||||||
import sonia.scm.user.User;
|
import sonia.scm.user.User;
|
||||||
import sonia.scm.user.UserTestData;
|
import sonia.scm.user.UserTestData;
|
||||||
@@ -90,6 +90,9 @@ public class DefaultAuthorizationCollectorTest {
|
|||||||
@Mock
|
@Mock
|
||||||
private SecuritySystem securitySystem;
|
private SecuritySystem securitySystem;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private RepositoryPermissionProvider repositoryPermissionProvider;
|
||||||
|
|
||||||
private DefaultAuthorizationCollector collector;
|
private DefaultAuthorizationCollector collector;
|
||||||
|
|
||||||
@Rule
|
@Rule
|
||||||
@@ -101,11 +104,11 @@ public class DefaultAuthorizationCollectorTest {
|
|||||||
@Before
|
@Before
|
||||||
public void setUp(){
|
public void setUp(){
|
||||||
when(cacheManager.getCache(Mockito.any(String.class))).thenReturn(cache);
|
when(cacheManager.getCache(Mockito.any(String.class))).thenReturn(cache);
|
||||||
collector = new DefaultAuthorizationCollector(cacheManager, repositoryDAO, securitySystem);
|
collector = new DefaultAuthorizationCollector(cacheManager, repositoryDAO, securitySystem, repositoryPermissionProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests {@link AuthorizationCollector#collect()} without user role.
|
* Tests {@link AuthorizationCollector#collect(PrincipalCollection)} ()} without user role.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@SubjectAware
|
@SubjectAware
|
||||||
@@ -118,7 +121,7 @@ public class DefaultAuthorizationCollectorTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests {@link AuthorizationCollector#collect()} from cache.
|
* Tests {@link AuthorizationCollector#collect(PrincipalCollection)} from cache.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@SubjectAware(
|
@SubjectAware(
|
||||||
@@ -134,7 +137,7 @@ public class DefaultAuthorizationCollectorTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests {@link AuthorizationCollector#collect()} with cache.
|
* Tests {@link AuthorizationCollector#collect(PrincipalCollection)} ()} with cache.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@SubjectAware(
|
@SubjectAware(
|
||||||
@@ -148,7 +151,7 @@ public class DefaultAuthorizationCollectorTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests {@link AuthorizationCollector#collect()} without permissions.
|
* Tests {@link AuthorizationCollector#collect(PrincipalCollection)} ()} without permissions.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@SubjectAware(
|
@SubjectAware(
|
||||||
@@ -165,7 +168,7 @@ public class DefaultAuthorizationCollectorTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests {@link AuthorizationCollector#collect()} with repository permissions.
|
* Tests {@link AuthorizationCollector#collect(PrincipalCollection)} ()} with repository permissions.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@SubjectAware(
|
@SubjectAware(
|
||||||
@@ -191,7 +194,50 @@ public class DefaultAuthorizationCollectorTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests {@link AuthorizationCollector#collect()} with global permissions.
|
* Tests {@link AuthorizationCollector#collect(PrincipalCollection)} with repository roles.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
@SubjectAware(
|
||||||
|
configuration = "classpath:sonia/scm/shiro-001.ini"
|
||||||
|
)
|
||||||
|
public void testCollectWithRepositoryRolePermissions() {
|
||||||
|
when(repositoryPermissionProvider.availableRoles()).thenReturn(
|
||||||
|
asList(
|
||||||
|
new RepositoryRole("user role", asList("user"), "xml"),
|
||||||
|
new RepositoryRole("group role", asList("group"), "xml"),
|
||||||
|
new RepositoryRole("system role", asList("system"), "system")
|
||||||
|
));
|
||||||
|
|
||||||
|
String group = "heart-of-gold-crew";
|
||||||
|
authenticate(UserTestData.createTrillian(), group);
|
||||||
|
Repository heartOfGold = RepositoryTestData.createHeartOfGold();
|
||||||
|
heartOfGold.setId("one");
|
||||||
|
heartOfGold.setPermissions(Lists.newArrayList(
|
||||||
|
new RepositoryPermission("trillian", "user role", false),
|
||||||
|
new RepositoryPermission("trillian", "system role", false)
|
||||||
|
));
|
||||||
|
Repository puzzle42 = RepositoryTestData.create42Puzzle();
|
||||||
|
puzzle42.setId("two");
|
||||||
|
RepositoryPermission permission = new RepositoryPermission(group, "group role", true);
|
||||||
|
puzzle42.setPermissions(Lists.newArrayList(permission));
|
||||||
|
when(repositoryDAO.getAll()).thenReturn(Lists.newArrayList(heartOfGold, puzzle42));
|
||||||
|
|
||||||
|
// execute and assert
|
||||||
|
AuthorizationInfo authInfo = collector.collect();
|
||||||
|
assertThat(authInfo.getRoles(), Matchers.containsInAnyOrder(Role.USER));
|
||||||
|
assertThat(authInfo.getObjectPermissions(), nullValue());
|
||||||
|
assertThat(authInfo.getStringPermissions(), containsInAnyOrder(
|
||||||
|
"user:autocomplete",
|
||||||
|
"group:autocomplete",
|
||||||
|
"user:changePassword:trillian",
|
||||||
|
"repository:user:one",
|
||||||
|
"repository:system:one",
|
||||||
|
"repository:group:two",
|
||||||
|
"user:read:trillian"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests {@link AuthorizationCollector#collect(PrincipalCollection)} ()} with global permissions.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@SubjectAware(
|
@SubjectAware(
|
||||||
|
|||||||
Reference in New Issue
Block a user