mirror of
https://github.com/scm-manager/scm-manager.git
synced 2026-02-05 06:09:12 +01:00
fix anonymous access
This commit is contained in:
@@ -113,7 +113,7 @@ public class PermissionUtil
|
||||
@Deprecated
|
||||
public static void assertPermission(Repository repository, PermissionType pt)
|
||||
{
|
||||
if (!hasPermission(repository, pt))
|
||||
if (!hasPermission(null, repository, pt))
|
||||
{
|
||||
throw new ScmSecurityException("action denied");
|
||||
}
|
||||
@@ -136,7 +136,7 @@ public class PermissionUtil
|
||||
public static boolean hasPermission(Repository repository,
|
||||
Provider<WebSecurityContext> securityContextProvider, PermissionType pt)
|
||||
{
|
||||
return hasPermission(repository, securityContextProvider.get(), pt);
|
||||
return hasPermission(null, repository, pt);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -154,24 +154,23 @@ public class PermissionUtil
|
||||
public static boolean hasPermission(Repository repository,
|
||||
WebSecurityContext securityContext, PermissionType pt)
|
||||
{
|
||||
return hasPermission(repository, pt);
|
||||
return hasPermission(null, repository, pt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param configuration
|
||||
* @param repository
|
||||
* @param securityContext
|
||||
* @param pt
|
||||
*
|
||||
* @return
|
||||
* @since 1.21
|
||||
*
|
||||
* @deprecated
|
||||
* @since 1.21
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean hasPermission(Repository repository, PermissionType pt)
|
||||
public static boolean hasPermission(ScmConfiguration configuration,
|
||||
Repository repository, PermissionType pt)
|
||||
{
|
||||
boolean result = false;
|
||||
|
||||
@@ -179,7 +178,6 @@ public class PermissionUtil
|
||||
|
||||
if (subject.isAuthenticated())
|
||||
{
|
||||
|
||||
String username = subject.getPrincipal().toString();
|
||||
|
||||
AssertUtil.assertIsNotEmpty(username);
|
||||
@@ -203,6 +201,14 @@ public class PermissionUtil
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// check anonymous access
|
||||
result = (configuration != null)
|
||||
&& configuration.isAnonymousAccessEnabled()
|
||||
&& repository.isPublicReadable() && (pt == PermissionType.READ);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -252,7 +258,7 @@ public class PermissionUtil
|
||||
}
|
||||
else
|
||||
{
|
||||
permitted = PermissionUtil.hasPermission(repository,
|
||||
permitted = PermissionUtil.hasPermission(configuration, repository,
|
||||
PermissionType.WRITE);
|
||||
}
|
||||
|
||||
|
||||
@@ -40,20 +40,19 @@ import com.google.common.base.Strings;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.subject.Subject;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import sonia.scm.HandlerEvent;
|
||||
import sonia.scm.cache.Cache;
|
||||
import sonia.scm.cache.CacheManager;
|
||||
import sonia.scm.config.ScmConfiguration;
|
||||
import sonia.scm.repository.BlameResult;
|
||||
import sonia.scm.repository.Branches;
|
||||
import sonia.scm.repository.BrowserResult;
|
||||
import sonia.scm.repository.ChangesetPagingResult;
|
||||
import sonia.scm.repository.PermissionType;
|
||||
import sonia.scm.repository.PermissionUtil;
|
||||
import sonia.scm.repository.PostReceiveRepositoryHook;
|
||||
import sonia.scm.repository.PreProcessorUtil;
|
||||
import sonia.scm.repository.Repository;
|
||||
@@ -65,7 +64,6 @@ import sonia.scm.repository.RepositoryNotFoundException;
|
||||
import sonia.scm.repository.Tags;
|
||||
import sonia.scm.repository.spi.RepositoryServiceProvider;
|
||||
import sonia.scm.repository.spi.RepositoryServiceResolver;
|
||||
import sonia.scm.security.RepositoryPermission;
|
||||
import sonia.scm.security.ScmSecurityException;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
@@ -135,12 +133,38 @@ public final class RepositoryServiceFactory
|
||||
* @param securityContextProvider provider for the current security context
|
||||
* @param resolvers a set of {@link RepositoryServiceResolver}
|
||||
* @param preProcessorUtil helper object for pre processor handling
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
@Inject
|
||||
@Deprecated
|
||||
public RepositoryServiceFactory(CacheManager cacheManager,
|
||||
RepositoryManager repositoryManager,
|
||||
Set<RepositoryServiceResolver> resolvers, PreProcessorUtil preProcessorUtil)
|
||||
{
|
||||
this(null, cacheManager, repositoryManager, resolvers, preProcessorUtil);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@link RepositoryServiceFactory}. This constructor
|
||||
* should not be called manually, it should only be used by the injection
|
||||
* container.
|
||||
*
|
||||
*
|
||||
* @param configuration configuration
|
||||
* @param cacheManager cache manager
|
||||
* @param repositoryManager manager for repositories
|
||||
* @param securityContextProvider provider for the current security context
|
||||
* @param resolvers a set of {@link RepositoryServiceResolver}
|
||||
* @param preProcessorUtil helper object for pre processor handling
|
||||
*
|
||||
* @since 1.21
|
||||
*/
|
||||
@Inject
|
||||
public RepositoryServiceFactory(ScmConfiguration configuration,
|
||||
CacheManager cacheManager, RepositoryManager repositoryManager,
|
||||
Set<RepositoryServiceResolver> resolvers, PreProcessorUtil preProcessorUtil)
|
||||
{
|
||||
this.configuration = configuration;
|
||||
this.cacheManager = cacheManager;
|
||||
this.repositoryManager = repositoryManager;
|
||||
this.resolvers = resolvers;
|
||||
@@ -249,10 +273,8 @@ public final class RepositoryServiceFactory
|
||||
Preconditions.checkNotNull(repository, "repository is required");
|
||||
|
||||
// check for read permissions of current user
|
||||
Subject subject = SecurityUtils.getSubject();
|
||||
|
||||
if (!subject.isPermitted(new RepositoryPermission(repository,
|
||||
PermissionType.READ)))
|
||||
if (!PermissionUtil.hasPermission(configuration, repository,
|
||||
PermissionType.READ))
|
||||
{
|
||||
throw new ScmSecurityException("read permission are required");
|
||||
}
|
||||
@@ -408,6 +430,9 @@ public final class RepositoryServiceFactory
|
||||
/** Field description */
|
||||
private CacheManager cacheManager;
|
||||
|
||||
/** scm-manager configuration */
|
||||
private ScmConfiguration configuration;
|
||||
|
||||
/** Field description */
|
||||
private PreProcessorUtil preProcessorUtil;
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ package sonia.scm.web.filter;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
import com.google.inject.Singleton;
|
||||
|
||||
@@ -45,6 +46,8 @@ import org.apache.shiro.subject.Subject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import sonia.scm.SCMContext;
|
||||
import sonia.scm.config.ScmConfiguration;
|
||||
import sonia.scm.security.ScmAuthenticationToken;
|
||||
import sonia.scm.user.User;
|
||||
import sonia.scm.util.HttpUtil;
|
||||
@@ -85,12 +88,6 @@ public class BasicAuthenticationFilter extends HttpFilter
|
||||
|
||||
//~--- constructors ---------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
* @since 1.21
|
||||
*/
|
||||
public BasicAuthenticationFilter() {}
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
@@ -102,6 +99,19 @@ public class BasicAuthenticationFilter extends HttpFilter
|
||||
public BasicAuthenticationFilter(
|
||||
Provider<WebSecurityContext> securityContextProvider) {}
|
||||
|
||||
/**
|
||||
* Constructs a new basic authenticaton filter
|
||||
*
|
||||
* @param configuration scm-manager global configuration
|
||||
*
|
||||
* @since 1.21
|
||||
*/
|
||||
@Inject
|
||||
public BasicAuthenticationFilter(ScmConfiguration configuration)
|
||||
{
|
||||
this.configuration = configuration;
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
@@ -155,6 +165,13 @@ public class BasicAuthenticationFilter extends HttpFilter
|
||||
|
||||
user = subject.getPrincipals().oneByType(User.class);
|
||||
}
|
||||
else if ((configuration != null)
|
||||
&& configuration.isAnonymousAccessEnabled())
|
||||
{
|
||||
user = new User(SCMContext.USER_ANONYMOUS, "SCM Anonymous",
|
||||
"scm-anonymous@scm-manager.com");
|
||||
|
||||
}
|
||||
|
||||
if (user == null)
|
||||
{
|
||||
@@ -258,4 +275,9 @@ public class BasicAuthenticationFilter extends HttpFilter
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
private ScmConfiguration configuration;
|
||||
}
|
||||
|
||||
@@ -45,7 +45,6 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import sonia.scm.ArgumentIsInvalidException;
|
||||
import sonia.scm.SCMContext;
|
||||
import sonia.scm.config.ScmConfiguration;
|
||||
import sonia.scm.repository.PermissionType;
|
||||
import sonia.scm.repository.PermissionUtil;
|
||||
@@ -80,12 +79,11 @@ public abstract class PermissionFilter extends HttpFilter
|
||||
//~--- constructors ---------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
*
|
||||
* @param configuration
|
||||
* @param securityContextProvider
|
||||
* Constructs a new permission filter
|
||||
*
|
||||
* @param configuration global scm-manager configuration
|
||||
*
|
||||
* @since 1.21
|
||||
*/
|
||||
public PermissionFilter(ScmConfiguration configuration)
|
||||
{
|
||||
@@ -150,87 +148,76 @@ public abstract class PermissionFilter extends HttpFilter
|
||||
{
|
||||
Subject subject = SecurityUtils.getSubject();
|
||||
|
||||
if (subject.isAuthenticated())
|
||||
try
|
||||
{
|
||||
try
|
||||
Repository repository = getRepository(request);
|
||||
|
||||
if (repository != null)
|
||||
{
|
||||
Repository repository = getRepository(request);
|
||||
boolean writeRequest = isWriteRequest(request);
|
||||
|
||||
if (repository != null)
|
||||
if (hasPermission(repository, writeRequest))
|
||||
{
|
||||
boolean writeRequest = isWriteRequest(request);
|
||||
|
||||
if (hasPermission(repository, writeRequest))
|
||||
if (logger.isTraceEnabled())
|
||||
{
|
||||
if (logger.isTraceEnabled())
|
||||
{
|
||||
logger.trace("{} access to repository {} for user {} granted",
|
||||
new Object[] { writeRequest
|
||||
? "write"
|
||||
: "read", repository.getName(), subject.getPrincipal() });
|
||||
}
|
||||
|
||||
chain.doFilter(request, response);
|
||||
logger.trace("{} access to repository {} for user {} granted",
|
||||
new Object[] { writeRequest
|
||||
? "write"
|
||||
: "read", repository.getName(), subject.getPrincipal() });
|
||||
}
|
||||
else
|
||||
{
|
||||
if (logger.isInfoEnabled())
|
||||
{
|
||||
logger.info("{} access to repository {} for user {} denied",
|
||||
new Object[] { writeRequest
|
||||
? "write"
|
||||
: "read", repository.getName(), subject.getPrincipal() });
|
||||
}
|
||||
|
||||
sendAccessDenied(response, subject);
|
||||
}
|
||||
chain.doFilter(request, response);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
if (logger.isInfoEnabled())
|
||||
{
|
||||
logger.debug("repository not found");
|
||||
logger.info("{} access to repository {} for user {} denied",
|
||||
new Object[] { writeRequest
|
||||
? "write"
|
||||
: "read", repository.getName(), subject.getPrincipal() });
|
||||
}
|
||||
|
||||
response.sendError(HttpServletResponse.SC_NOT_FOUND);
|
||||
sendAccessDenied(response, subject);
|
||||
}
|
||||
}
|
||||
catch (ArgumentIsInvalidException ex)
|
||||
else
|
||||
{
|
||||
if (logger.isTraceEnabled())
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.trace(
|
||||
"wrong request at ".concat(request.getRequestURI()).concat(
|
||||
" send redirect"), ex);
|
||||
}
|
||||
else if (logger.isWarnEnabled())
|
||||
{
|
||||
logger.warn("wrong request at {} send redirect",
|
||||
request.getRequestURI());
|
||||
logger.debug("repository not found");
|
||||
}
|
||||
|
||||
response.sendRedirect(getRepositoryRootHelpUrl(request));
|
||||
}
|
||||
catch (ScmSecurityException ex)
|
||||
{
|
||||
if (logger.isWarnEnabled())
|
||||
{
|
||||
logger.warn("user {} has not enough permissions",
|
||||
subject.getPrincipal());
|
||||
}
|
||||
|
||||
sendAccessDenied(response, subject);
|
||||
response.sendError(HttpServletResponse.SC_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
else
|
||||
catch (ArgumentIsInvalidException ex)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
if (logger.isTraceEnabled())
|
||||
{
|
||||
logger.debug("user in not authenticated");
|
||||
logger.trace(
|
||||
"wrong request at ".concat(request.getRequestURI()).concat(
|
||||
" send redirect"), ex);
|
||||
}
|
||||
else if (logger.isWarnEnabled())
|
||||
{
|
||||
logger.warn("wrong request at {} send redirect",
|
||||
request.getRequestURI());
|
||||
}
|
||||
|
||||
response.sendError(HttpServletResponse.SC_FORBIDDEN);
|
||||
response.sendRedirect(getRepositoryRootHelpUrl(request));
|
||||
}
|
||||
catch (ScmSecurityException ex)
|
||||
{
|
||||
if (logger.isWarnEnabled())
|
||||
{
|
||||
logger.warn("user {} has not enough permissions",
|
||||
subject.getPrincipal());
|
||||
}
|
||||
|
||||
sendAccessDenied(response, subject);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -269,15 +256,13 @@ public abstract class PermissionFilter extends HttpFilter
|
||||
private void sendAccessDenied(HttpServletResponse response, Subject subject)
|
||||
throws IOException
|
||||
{
|
||||
|
||||
// TODO check anonymous access
|
||||
if (SCMContext.USER_ANONYMOUS.equals(subject.getPrincipal()))
|
||||
if (subject.isAuthenticated())
|
||||
{
|
||||
HttpUtil.sendUnauthorized(response);
|
||||
response.sendError(HttpServletResponse.SC_FORBIDDEN);
|
||||
}
|
||||
else
|
||||
{
|
||||
response.sendError(HttpServletResponse.SC_FORBIDDEN);
|
||||
HttpUtil.sendUnauthorized(response);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -322,7 +307,8 @@ public abstract class PermissionFilter extends HttpFilter
|
||||
}
|
||||
else
|
||||
{
|
||||
permitted = PermissionUtil.hasPermission(repository, PermissionType.READ);
|
||||
permitted = PermissionUtil.hasPermission(configuration, repository,
|
||||
PermissionType.READ);
|
||||
}
|
||||
|
||||
return permitted;
|
||||
|
||||
Reference in New Issue
Block a user