mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-17 10:41:06 +01:00
Merge with 2.0.0-m3
This commit is contained in:
@@ -101,11 +101,11 @@ public class BearerRealm extends AuthenticatingRealm
|
||||
BearerToken bt = (BearerToken) token;
|
||||
AccessToken accessToken = tokenResolver.resolve(bt);
|
||||
|
||||
return helper.getAuthenticationInfo(
|
||||
accessToken.getSubject(),
|
||||
bt.getCredentials(),
|
||||
Scopes.fromClaims(accessToken.getClaims())
|
||||
);
|
||||
return helper.authenticationInfoBuilder(accessToken.getSubject())
|
||||
.withCredentials(bt.getCredentials())
|
||||
.withScope(Scopes.fromClaims(accessToken.getClaims()))
|
||||
.withGroups(accessToken.getGroups())
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import sonia.scm.cache.Cache;
|
||||
import sonia.scm.cache.CacheManager;
|
||||
import sonia.scm.config.ScmConfiguration;
|
||||
import sonia.scm.group.GroupNames;
|
||||
import sonia.scm.group.GroupPermissions;
|
||||
import sonia.scm.plugin.Extension;
|
||||
@@ -75,9 +76,6 @@ import java.util.Set;
|
||||
public class DefaultAuthorizationCollector implements AuthorizationCollector
|
||||
{
|
||||
|
||||
// TODO move to util class
|
||||
private static final String SEPARATOR = System.getProperty("line.separator", "\n");
|
||||
|
||||
/** Field description */
|
||||
private static final String ADMIN_PERMISSION = "*";
|
||||
|
||||
@@ -97,14 +95,16 @@ public class DefaultAuthorizationCollector implements AuthorizationCollector
|
||||
*
|
||||
*
|
||||
*
|
||||
* @param configuration
|
||||
* @param cacheManager
|
||||
* @param repositoryDAO
|
||||
* @param securitySystem
|
||||
*/
|
||||
@Inject
|
||||
public DefaultAuthorizationCollector(CacheManager cacheManager,
|
||||
RepositoryDAO repositoryDAO, SecuritySystem securitySystem)
|
||||
public DefaultAuthorizationCollector(ScmConfiguration configuration, CacheManager cacheManager,
|
||||
RepositoryDAO repositoryDAO, SecuritySystem securitySystem)
|
||||
{
|
||||
this.configuration = configuration;
|
||||
this.cache = cacheManager.getCache(CACHE_NAME);
|
||||
this.repositoryDAO = repositoryDAO;
|
||||
this.securitySystem = securitySystem;
|
||||
@@ -238,7 +238,7 @@ public class DefaultAuthorizationCollector implements AuthorizationCollector
|
||||
Set<String> roles;
|
||||
Set<String> permissions;
|
||||
|
||||
if (user.isAdmin())
|
||||
if (isAdmin(user, groups))
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
@@ -269,6 +269,37 @@ public class DefaultAuthorizationCollector implements AuthorizationCollector
|
||||
return info;
|
||||
}
|
||||
|
||||
private boolean isAdmin(User user, GroupNames groups) {
|
||||
boolean admin = user.isAdmin();
|
||||
if (admin) {
|
||||
logger.debug("user {} is marked as admin, because of the user flag", user.getName());
|
||||
return true;
|
||||
}
|
||||
if (isUserAdminInConfiguration(user)) {
|
||||
logger.debug("user {} is marked as admin, because of the admin user configuration", user.getName());
|
||||
return true;
|
||||
}
|
||||
return isUserAdminInGroupConfiguration(user, groups);
|
||||
}
|
||||
|
||||
private boolean isUserAdminInGroupConfiguration(User user, GroupNames groups) {
|
||||
Set<String> adminGroups = configuration.getAdminGroups();
|
||||
if (adminGroups != null && groups != null) {
|
||||
for (String group : groups) {
|
||||
if (adminGroups.contains(group)) {
|
||||
logger.debug("user {} is marked as admin, because of the admin group configuration for group {}", user.getName(), group);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isUserAdminInConfiguration(User user) {
|
||||
Set<String> adminUsers = configuration.getAdminUsers();
|
||||
return adminUsers != null && adminUsers.contains(user.getName());
|
||||
}
|
||||
|
||||
private String getGroupAutocompletePermission() {
|
||||
return GroupPermissions.autocomplete().asShiroString();
|
||||
}
|
||||
@@ -372,6 +403,8 @@ public class DefaultAuthorizationCollector implements AuthorizationCollector
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
private final ScmConfiguration configuration;
|
||||
|
||||
/** authorization cache */
|
||||
private final Cache<CacheKey, AuthorizationInfo> cache;
|
||||
|
||||
|
||||
@@ -30,12 +30,15 @@
|
||||
*/
|
||||
package sonia.scm.security;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import io.jsonwebtoken.Claims;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
import static java.util.Optional.ofNullable;
|
||||
|
||||
@@ -49,6 +52,8 @@ public final class JwtAccessToken implements AccessToken {
|
||||
|
||||
public static final String REFRESHABLE_UNTIL_CLAIM_KEY = "scm-manager.refreshExpiration";
|
||||
public static final String PARENT_TOKEN_ID_CLAIM_KEY = "scm-manager.parentTokenId";
|
||||
public static final String GROUPS_CLAIM_KEY = "scm-manager.groups";
|
||||
|
||||
private final Claims claims;
|
||||
private final String compact;
|
||||
|
||||
@@ -103,6 +108,16 @@ public final class JwtAccessToken implements AccessToken {
|
||||
return Optional.ofNullable(claims.get(key));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Set<String> getGroups() {
|
||||
Iterable<String> groups = claims.get(GROUPS_CLAIM_KEY, Iterable.class);
|
||||
if (groups != null) {
|
||||
return ImmutableSet.copyOf(groups);
|
||||
}
|
||||
return ImmutableSet.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String compact() {
|
||||
return compact;
|
||||
|
||||
@@ -39,9 +39,12 @@ import io.jsonwebtoken.SignatureAlgorithm;
|
||||
|
||||
import java.time.Clock;
|
||||
import java.time.Instant;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.subject.Subject;
|
||||
@@ -74,6 +77,7 @@ public final class JwtAccessTokenBuilder implements AccessTokenBuilder {
|
||||
private Instant refreshExpiration;
|
||||
private String parentKeyId;
|
||||
private Scope scope = Scope.empty();
|
||||
private Set<String> groups = new HashSet<>();
|
||||
|
||||
private final Map<String,Object> custom = Maps.newHashMap();
|
||||
|
||||
@@ -134,6 +138,12 @@ public final class JwtAccessTokenBuilder implements AccessTokenBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtAccessTokenBuilder groups(String... groups) {
|
||||
Collections.addAll(this.groups, groups);
|
||||
return this;
|
||||
}
|
||||
|
||||
JwtAccessTokenBuilder refreshExpiration(Instant refreshExpiration) {
|
||||
this.refreshExpiration = refreshExpiration;
|
||||
this.refreshableFor = 0;
|
||||
@@ -195,6 +205,10 @@ public final class JwtAccessTokenBuilder implements AccessTokenBuilder {
|
||||
claims.setIssuer(issuer);
|
||||
}
|
||||
|
||||
if (!groups.isEmpty()) {
|
||||
claims.put(JwtAccessToken.GROUPS_CLAIM_KEY, groups);
|
||||
}
|
||||
|
||||
// sign token and create compact version
|
||||
String compact = Jwts.builder()
|
||||
.setClaims(claims)
|
||||
|
||||
Reference in New Issue
Block a user