Merge branch 'develop' into feature/user_converter

This commit is contained in:
Eduard Heimbuch
2020-10-14 15:45:07 +02:00
14 changed files with 228 additions and 89 deletions

View File

@@ -30,6 +30,8 @@ import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.AllowAllCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.realm.AuthenticatingRealm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sonia.scm.plugin.Extension;
import sonia.scm.repository.RepositoryRole;
import sonia.scm.repository.RepositoryRoleManager;
@@ -43,6 +45,8 @@ import static com.google.common.base.Preconditions.checkArgument;
@Extension
public class ApiKeyRealm extends AuthenticatingRealm {
private static final Logger LOG = LoggerFactory.getLogger(ApiKeyRealm.class);
private final ApiKeyService apiKeyService;
private final DAORealmHelper helper;
private final RepositoryRoleManager repositoryRoleManager;
@@ -58,7 +62,14 @@ public class ApiKeyRealm extends AuthenticatingRealm {
@Override
public boolean supports(AuthenticationToken token) {
return token instanceof UsernamePasswordToken || token instanceof BearerToken;
if (token instanceof UsernamePasswordToken || token instanceof BearerToken) {
boolean containsDot = getPassword(token).contains(".");
if (containsDot) {
LOG.debug("Ignoring token with at least one dot ('.'); this is probably a JWT token");
}
return !containsDot;
}
return false;
}
@Override
@@ -74,6 +85,7 @@ public class ApiKeyRealm extends AuthenticatingRealm {
private AuthenticationInfo buildAuthenticationInfo(AuthenticationToken token, ApiKeyService.CheckResult check) {
RepositoryRole repositoryRole = determineRole(check);
Scope scope = createScope(repositoryRole);
LOG.debug("login for user {} with api key limited to role {}", check.getUser(), check.getPermissionRole());
return helper
.authenticationInfoBuilder(check.getUser())
.withSessionId(getPrincipal(token))

View File

@@ -21,7 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package sonia.scm.security;
import com.google.common.annotations.VisibleForTesting;
@@ -29,6 +29,8 @@ import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.credential.AllowAllCredentialsMatcher;
import org.apache.shiro.realm.AuthenticatingRealm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sonia.scm.group.GroupDAO;
import sonia.scm.plugin.Extension;
import sonia.scm.user.UserDAO;
@@ -54,6 +56,7 @@ public class BearerRealm extends AuthenticatingRealm
@VisibleForTesting
static final String REALM = "BearerRealm";
private static final Logger LOG = LoggerFactory.getLogger(BearerRealm.class);
/** dao realm helper */
private final DAORealmHelper helper;
@@ -76,7 +79,17 @@ public class BearerRealm extends AuthenticatingRealm
setAuthenticationTokenClass(BearerToken.class);
}
//~--- methods --------------------------------------------------------------
@Override
public boolean supports(AuthenticationToken token) {
if (token instanceof BearerToken) {
boolean containsDot = ((BearerToken) token).getCredentials().contains(".");
if (!containsDot) {
LOG.debug("Ignoring token without a dot ('.'); this probably is an API key");
}
return containsDot;
}
return false;
}
/**
* Validates the given bearer token and retrieves authentication data from

View File

@@ -21,7 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package sonia.scm.update.repository;
import org.slf4j.Logger;
@@ -89,9 +89,13 @@ public class PublicFlagUpdateStep implements UpdateStep {
.filter(V1Repository::isPublic)
.forEach(v1Repository -> {
Repository v2Repository = repositoryDAO.get(v1Repository.getId());
LOG.info(String.format("Add RepositoryRole 'READ' to _anonymous user for repository: %s - %s/%s", v2Repository.getId(), v2Repository.getNamespace(), v2Repository.getName()));
v2Repository.addPermission(new RepositoryPermission(v2AnonymousUser.getId(), "READ", false));
repositoryDAO.modify(v2Repository);
if (v2Repository != null) {
LOG.info("Add RepositoryRole 'READ' to _anonymous user for repository: {} - {}/{}", v2Repository.getId(), v2Repository.getNamespace(), v2Repository.getName());
v2Repository.addPermission(new RepositoryPermission(v2AnonymousUser.getId(), "READ", false));
repositoryDAO.modify(v2Repository);
} else {
LOG.info("Repository no longer found for id {}; could not set permission for former anonymous mode", v1Repository.getId());
}
});
}

View File

@@ -21,7 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package sonia.scm.web.security;
import org.apache.shiro.authc.AuthenticationException;
@@ -90,6 +90,10 @@ public class TokenRefreshFilter extends HttpFilter {
private void examineToken(HttpServletRequest request, HttpServletResponse response, BearerToken token) {
AccessToken accessToken;
if (!token.getCredentials().contains(".")) {
LOG.trace("Ignoring token without dot. This probably is an API key, no JWT");
return;
}
try {
accessToken = resolver.resolve(token);
} catch (AuthenticationException e) {