Use existing permission filters in http servlet protocol

Just as a POC, fix logging and public access.
This commit is contained in:
René Pfeuffer
2018-09-10 16:35:50 +02:00
parent d9d3167bbb
commit eb378de87f
9 changed files with 55 additions and 14 deletions

View File

@@ -32,4 +32,8 @@ public abstract class HttpScmProtocol implements ScmProtocol {
} }
public abstract void serve(HttpServletRequest request, HttpServletResponse response, ServletConfig config) throws ServletException, IOException; public abstract void serve(HttpServletRequest request, HttpServletResponse response, ServletConfig config) throws ServletException, IOException;
Repository getRepository() {
return repository;
}
} }

View File

@@ -1,7 +1,13 @@
package sonia.scm.repository.spi; package sonia.scm.repository.spi;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sonia.scm.api.v2.resources.UriInfoStore; import sonia.scm.api.v2.resources.UriInfoStore;
import sonia.scm.repository.Repository; import sonia.scm.repository.Repository;
import sonia.scm.web.filter.PermissionFilter;
import sonia.scm.web.filter.ProviderPermissionFilter;
import javax.inject.Provider; import javax.inject.Provider;
import javax.servlet.ServletConfig; import javax.servlet.ServletConfig;
@@ -13,14 +19,19 @@ import java.io.IOException;
public abstract class InitializingHttpScmProtocolWrapper { public abstract class InitializingHttpScmProtocolWrapper {
private static final Logger logger =
LoggerFactory.getLogger(InitializingHttpScmProtocolWrapper.class);
private final Provider<? extends HttpServlet> delegateProvider; private final Provider<? extends HttpServlet> delegateProvider;
private final Provider<? extends ProviderPermissionFilter> permissionFilterProvider;
private final Provider<UriInfoStore> uriInfoStore; private final Provider<UriInfoStore> uriInfoStore;
private volatile boolean isInitialized = false; private volatile boolean isInitialized = false;
protected InitializingHttpScmProtocolWrapper(Provider<? extends HttpServlet> delegateProvider, Provider<UriInfoStore> uriInfoStore) { protected InitializingHttpScmProtocolWrapper(Provider<? extends HttpServlet> delegateProvider, Provider<? extends ProviderPermissionFilter> permissionFilterProvider, Provider<UriInfoStore> uriInfoStore) {
this.delegateProvider = delegateProvider; this.delegateProvider = delegateProvider;
this.permissionFilterProvider = permissionFilterProvider;
this.uriInfoStore = uriInfoStore; this.uriInfoStore = uriInfoStore;
} }
@@ -49,7 +60,33 @@ public abstract class InitializingHttpScmProtocolWrapper {
} }
} }
} }
delegateProvider.get().service(request, response);
if (getRepository() != null)
{
Subject subject = SecurityUtils.getSubject();
PermissionFilter permissionFilter = permissionFilterProvider.get();
boolean writeRequest = permissionFilter.isWriteRequest(request);
if (permissionFilter.hasPermission(getRepository(), writeRequest))
{
// logger.trace("{} access to repository {} for user {} granted",
// getActionAsString(writeRequest), repository.getName(),
// getUserName(subject));
delegateProvider.get().service(request, response);
}
else
{
// logger.info("{} access to repository {} for user {} denied",
// getActionAsString(writeRequest), repository.getName(),
// getUserName(subject));
permissionFilter.sendAccessDenied(request, response, subject);
}
}
} }
} }
} }

View File

@@ -106,7 +106,7 @@ public abstract class PermissionFilter extends HttpFilter
* *
* @return returns true if the current request is a write request * @return returns true if the current request is a write request
*/ */
protected abstract boolean isWriteRequest(HttpServletRequest request); public abstract boolean isWriteRequest(HttpServletRequest request);
//~--- methods -------------------------------------------------------------- //~--- methods --------------------------------------------------------------
@@ -249,7 +249,7 @@ public abstract class PermissionFilter extends HttpFilter
* *
* @throws IOException * @throws IOException
*/ */
private void sendAccessDenied(HttpServletRequest request, public void sendAccessDenied(HttpServletRequest request,
HttpServletResponse response, Subject subject) HttpServletResponse response, Subject subject)
throws IOException throws IOException
{ {
@@ -328,7 +328,7 @@ public abstract class PermissionFilter extends HttpFilter
* *
* @return true if the current user has the required permissions * @return true if the current user has the required permissions
*/ */
private boolean hasPermission(Repository repository, boolean writeRequest) public boolean hasPermission(Repository repository, boolean writeRequest)
{ {
boolean permitted; boolean permitted;

View File

@@ -98,7 +98,7 @@ public class GitPermissionFilter extends ProviderPermissionFilter
} }
@Override @Override
protected boolean isWriteRequest(HttpServletRequest request) { public boolean isWriteRequest(HttpServletRequest request) {
return isReceivePackRequest(request) || return isReceivePackRequest(request) ||
isReceiveServiceRequest(request) || isReceiveServiceRequest(request) ||
isLfsFileUpload(request); isLfsFileUpload(request);

View File

@@ -10,7 +10,7 @@ import javax.inject.Singleton;
@Singleton @Singleton
public class GitScmProtocolProviderWrapper extends InitializingHttpScmProtocolWrapper { public class GitScmProtocolProviderWrapper extends InitializingHttpScmProtocolWrapper {
@Inject @Inject
public GitScmProtocolProviderWrapper(Provider<ScmGitServlet> servletProvider, Provider<UriInfoStore> uriInfoStore) { public GitScmProtocolProviderWrapper(Provider<ScmGitServlet> servletProvider, Provider<GitPermissionFilter> permissionFilter, Provider<UriInfoStore> uriInfoStore) {
super(servletProvider, uriInfoStore); super(servletProvider, permissionFilter, uriInfoStore);
} }
} }

View File

@@ -74,7 +74,7 @@ public class HgPermissionFilter extends ProviderPermissionFilter
//~--- get methods ---------------------------------------------------------- //~--- get methods ----------------------------------------------------------
@Override @Override
protected boolean isWriteRequest(HttpServletRequest request) public boolean isWriteRequest(HttpServletRequest request)
{ {
return !READ_METHODS.contains(request.getMethod()); return !READ_METHODS.contains(request.getMethod());
} }

View File

@@ -10,7 +10,7 @@ import javax.inject.Singleton;
@Singleton @Singleton
public class HgScmProtocolProviderWrapper extends InitializingHttpScmProtocolWrapper { public class HgScmProtocolProviderWrapper extends InitializingHttpScmProtocolWrapper {
@Inject @Inject
public HgScmProtocolProviderWrapper(Provider<HgCGIServlet> servletProvider, Provider<UriInfoStore> uriInfoStore) { public HgScmProtocolProviderWrapper(Provider<HgCGIServlet> servletProvider, Provider<HgPermissionFilter> permissionFilter, Provider<UriInfoStore> uriInfoStore) {
super(servletProvider, uriInfoStore); super(servletProvider, permissionFilter, uriInfoStore);
} }
} }

View File

@@ -126,7 +126,7 @@ public class SvnPermissionFilter extends ProviderPermissionFilter
* @return * @return
*/ */
@Override @Override
protected boolean isWriteRequest(HttpServletRequest request) public boolean isWriteRequest(HttpServletRequest request)
{ {
return WRITEMETHOD_SET.contains(request.getMethod().toUpperCase()); return WRITEMETHOD_SET.contains(request.getMethod().toUpperCase());
} }

View File

@@ -17,8 +17,8 @@ import static sonia.scm.web.SvnServletModule.PARAMETER_SVN_PARENTPATH;
@Singleton @Singleton
public class SvnScmProtocolProviderWrapper extends InitializingHttpScmProtocolWrapper { public class SvnScmProtocolProviderWrapper extends InitializingHttpScmProtocolWrapper {
@Inject @Inject
public SvnScmProtocolProviderWrapper(Provider<SvnDAVServlet> servletProvider, Provider<UriInfoStore> uriInfoStore) { public SvnScmProtocolProviderWrapper(Provider<SvnDAVServlet> servletProvider, Provider<SvnPermissionFilter> permissionFilter, Provider<UriInfoStore> uriInfoStore) {
super(servletProvider, uriInfoStore); super(servletProvider, permissionFilter, uriInfoStore);
} }
@Override @Override