mirror of
https://github.com/theonedev/onedev.git
synced 2025-12-08 18:26:30 +00:00
Merge branch 'master' of https://git.pmease.com/p/robin/commons
* 'master' of https://git.pmease.com/p/robin/commons: Sub page should override onPageInitialize() instead of onInitialize() Reject git operation when server is not ready. Send git error messages to git client. Disable session creation for git operation. Make BasePage.onInitialize() final. Add security check for GitFilter Conflicts: gitop.web/src/main/java/com/pmease/gitop/web/page/BasePage.java gitop.web/src/main/java/com/pmease/gitop/web/page/account/setting/profile/AccountProfilePage.java gitop.web/src/main/java/com/pmease/gitop/web/page/home/HomePage.java gitop.web/src/main/java/com/pmease/gitop/web/page/project/ProjectHomePage.java
This commit is contained in:
commit
3b33ad2def
@ -4,6 +4,7 @@ import java.io.IOException;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.inject.Provider;
|
||||
import javax.servlet.DispatcherType;
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.FilterChain;
|
||||
@ -29,16 +30,19 @@ public class JettyPlugin extends AbstractPlugin {
|
||||
|
||||
private ServletContextHandler contextHandler;
|
||||
|
||||
private final Set<ServerConfigurator> serverConfigurators;
|
||||
private final Provider<Set<ServerConfigurator>> serverConfiguratorsProvider;
|
||||
|
||||
private final Set<ServletConfigurator> servletContextConfigurators;
|
||||
private final Provider<Set<ServletConfigurator>> servletConfiguratorsProvider;
|
||||
|
||||
/*
|
||||
* Inject providers here to avoid circurlar dependencies when dependency graph gets complicated
|
||||
*/
|
||||
@Inject
|
||||
public JettyPlugin(
|
||||
Set<ServerConfigurator> serverConfigurators,
|
||||
Set<ServletConfigurator> servletContextConfigurators) {
|
||||
this.serverConfigurators = serverConfigurators;
|
||||
this.servletContextConfigurators = servletContextConfigurators;
|
||||
Provider<Set<ServerConfigurator>> serverConfiguratorsProvider,
|
||||
Provider<Set<ServletConfigurator>> servletConfiguratorsProvider) {
|
||||
this.serverConfiguratorsProvider = serverConfiguratorsProvider;
|
||||
this.servletConfiguratorsProvider = servletConfiguratorsProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -80,7 +84,7 @@ public class JettyPlugin extends AbstractPlugin {
|
||||
|
||||
contextHandler.addFilter(DisableTraceFilter.class, "/*", EnumSet.of(DispatcherType.REQUEST));
|
||||
|
||||
for (ServletConfigurator configurator: servletContextConfigurators)
|
||||
for (ServletConfigurator configurator: servletConfiguratorsProvider.get())
|
||||
configurator.configure(contextHandler);
|
||||
|
||||
/*
|
||||
@ -92,7 +96,7 @@ public class JettyPlugin extends AbstractPlugin {
|
||||
|
||||
server.setHandler(contextHandler);
|
||||
|
||||
for (ServerConfigurator configurator: serverConfigurators)
|
||||
for (ServerConfigurator configurator: serverConfiguratorsProvider.get())
|
||||
configurator.configure(server);
|
||||
|
||||
return server;
|
||||
|
||||
@ -12,6 +12,8 @@ import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.authc.IncorrectCredentialsException;
|
||||
import org.apache.shiro.authc.UnknownAccountException;
|
||||
import org.apache.shiro.authc.UsernamePasswordToken;
|
||||
import org.apache.shiro.authz.UnauthenticatedException;
|
||||
import org.apache.shiro.authz.UnauthorizedException;
|
||||
@ -73,31 +75,30 @@ public class BasicAuthenticationFilter extends PathMatchingFilter {
|
||||
protected void cleanup(ServletRequest request, ServletResponse response, Exception existing)
|
||||
throws ServletException, IOException {
|
||||
|
||||
boolean sendChallenge = false;
|
||||
HttpServletResponse httpResponse = WebUtils.toHttp(response);
|
||||
if (existing != null) {
|
||||
if (ExceptionUtils.find(existing, UnauthenticatedException.class) != null) {
|
||||
sendChallenge = true;
|
||||
httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
|
||||
String authcHeader = HttpServletRequest.BASIC_AUTH + " realm=\"" + appName + "\"";
|
||||
httpResponse.setHeader(AUTHENTICATE_HEADER, authcHeader);
|
||||
existing = null;
|
||||
} else if (ExceptionUtils.find(existing, UnauthorizedException.class) != null) {
|
||||
if (!SecurityUtils.getSubject().isAuthenticated()) {
|
||||
sendChallenge = true;
|
||||
httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
|
||||
String authcHeader = HttpServletRequest.BASIC_AUTH + " realm=\"" + appName + "\"";
|
||||
httpResponse.setHeader(AUTHENTICATE_HEADER, authcHeader);
|
||||
existing = null;
|
||||
}
|
||||
} else if (ExceptionUtils.find(existing, IncorrectCredentialsException.class) != null) {
|
||||
httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Incorrect credentials.");
|
||||
existing = null;
|
||||
} else if (ExceptionUtils.find(existing, UnknownAccountException.class) != null) {
|
||||
httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unknown user name.");
|
||||
existing = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (sendChallenge) {
|
||||
existing = null;
|
||||
sendChallenge(request, response);
|
||||
}
|
||||
|
||||
super.cleanup(request, response, existing);
|
||||
}
|
||||
|
||||
protected boolean sendChallenge(ServletRequest request, ServletResponse response) {
|
||||
HttpServletResponse httpResponse = WebUtils.toHttp(response);
|
||||
httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
|
||||
String authcHeader = HttpServletRequest.BASIC_AUTH + " realm=\"" + appName + "\"";
|
||||
httpResponse.setHeader(AUTHENTICATE_HEADER, authcHeader);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@ import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.shiro.web.filter.mgt.FilterChainManager;
|
||||
import org.hibernate.cfg.NamingStrategy;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
@ -14,6 +15,7 @@ import com.pmease.commons.jetty.ServletConfigurator;
|
||||
import com.pmease.commons.loader.AbstractPlugin;
|
||||
import com.pmease.commons.loader.AbstractPluginModule;
|
||||
import com.pmease.commons.shiro.AbstractRealm;
|
||||
import com.pmease.commons.shiro.FilterChainConfigurator;
|
||||
import com.pmease.commons.util.ClassUtils;
|
||||
import com.pmease.gitop.core.model.ModelLocator;
|
||||
import com.pmease.gitop.core.permission.UserRealm;
|
||||
@ -69,6 +71,18 @@ public class CoreModule extends AbstractPluginModule {
|
||||
return Sets.newHashSet();
|
||||
}
|
||||
});
|
||||
|
||||
contribute(FilterChainConfigurator.class, new FilterChainConfigurator() {
|
||||
|
||||
@Override
|
||||
public void configure(FilterChainManager filterChainManager) {
|
||||
filterChainManager.createChain("/**/info/refs", "noSessionCreation, authcBasic");
|
||||
filterChainManager.createChain("/**/git-upload-pack", "noSessionCreation, authcBasic");
|
||||
filterChainManager.createChain("/**/git-receive-pack", "noSessionCreation, authcBasic");
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -48,6 +48,13 @@ public class CoreServletConfigurator implements ServletConfigurator {
|
||||
|
||||
filterHolder = new FilterHolder(gitFilter);
|
||||
context.addFilter(filterHolder, "/*", EnumSet.allOf(DispatcherType.class));
|
||||
|
||||
/*
|
||||
ServletHolder servletHolder = new ServletHolder(new GitServlet());
|
||||
servletHolder.setInitParameter("export-all", "1");
|
||||
servletHolder.setInitParameter("base-path", "w:\\temp\\storage\\1");
|
||||
context.addServlet(servletHolder, "/git/*");
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -14,14 +14,19 @@ import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.authz.UnauthorizedException;
|
||||
import org.eclipse.jgit.http.server.GitSmartHttpTools;
|
||||
import org.eclipse.jgit.http.server.ServletUtils;
|
||||
import org.eclipse.jgit.transport.PacketLineOut;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.pmease.commons.git.Git;
|
||||
import com.pmease.commons.util.GeneralException;
|
||||
import com.pmease.gitop.core.manager.ProjectManager;
|
||||
import com.pmease.gitop.core.model.Project;
|
||||
import com.pmease.gitop.core.permission.ObjectPermission;
|
||||
|
||||
@Singleton
|
||||
public class GitFilter implements Filter {
|
||||
@ -30,16 +35,23 @@ public class GitFilter implements Filter {
|
||||
|
||||
private static final String INFO_REFS = "info/refs";
|
||||
|
||||
private final Gitop gitop;
|
||||
|
||||
private final ProjectManager projectManager;
|
||||
|
||||
@Inject
|
||||
public GitFilter(ProjectManager projectManager) {
|
||||
public GitFilter(Gitop gitop, ProjectManager projectManager) {
|
||||
this.gitop = gitop;
|
||||
this.projectManager = projectManager;
|
||||
}
|
||||
|
||||
private String getPathInfo(HttpServletRequest request) {
|
||||
String pathInfo = request.getRequestURI().substring(request.getContextPath().length());
|
||||
return StringUtils.stripStart(pathInfo, "/");
|
||||
}
|
||||
|
||||
private Project getProject(HttpServletRequest request, HttpServletResponse response, String repoInfo)
|
||||
throws IOException {
|
||||
|
||||
repoInfo = StringUtils.stripStart(StringUtils.stripEnd(repoInfo, "/"), "/");
|
||||
|
||||
String ownerName = StringUtils.substringBefore(repoInfo, "/");
|
||||
@ -47,11 +59,8 @@ public class GitFilter implements Filter {
|
||||
|
||||
if (StringUtils.isBlank(ownerName) || StringUtils.isBlank(projectName)) {
|
||||
String url = request.getRequestURL().toString();
|
||||
String urlRoot = url.substring(0, url.length()-request.getPathInfo().length());
|
||||
String message = "Expecting url of format " + urlRoot + "/<owner name>/<project name>";
|
||||
logger.error("Error serving git request: " + message);
|
||||
response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
|
||||
return null;
|
||||
String urlRoot = url.substring(0, url.length()-getPathInfo(request).length());
|
||||
throw new GeneralException("Expecting url of format %s<owner name>/<project name>", urlRoot);
|
||||
}
|
||||
|
||||
if (projectName.endsWith(".git"))
|
||||
@ -59,10 +68,7 @@ public class GitFilter implements Filter {
|
||||
|
||||
Project project = projectManager.find(ownerName, projectName);
|
||||
if (project == null) {
|
||||
String message = "Unable to find project '" + projectName + "' owned by '" + ownerName + "'.";
|
||||
logger.error("Error serving git request: " + message);
|
||||
response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
|
||||
return null;
|
||||
throw new GeneralException("Unable to find project %s owned by %s.", projectName, ownerName);
|
||||
}
|
||||
|
||||
return project;
|
||||
@ -74,71 +80,64 @@ public class GitFilter implements Filter {
|
||||
response.setHeader("Cache-Control", "no-cache, max-age=0, must-revalidate");
|
||||
}
|
||||
|
||||
protected void processPacks(HttpServletRequest req, HttpServletResponse resp, String pathInfo) throws ServletException, IOException {
|
||||
protected void processPacks(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
||||
String pathInfo = getPathInfo(request);
|
||||
|
||||
String service = StringUtils.substringAfterLast(pathInfo, "/");
|
||||
|
||||
String repoInfo = StringUtils.substringBeforeLast(pathInfo, "/");
|
||||
Project project = getProject(req, resp, repoInfo);
|
||||
Project project = getProject(request, response, repoInfo);
|
||||
|
||||
if (project != null) {
|
||||
doNotCache(resp);
|
||||
resp.setHeader("Content-Type", "application/x-" + service + "-result");
|
||||
doNotCache(response);
|
||||
response.setHeader("Content-Type", "application/x-" + service + "-result");
|
||||
|
||||
Git git = new Git(projectManager.locateStorage(project).ofCode());
|
||||
Git git = new Git(projectManager.locateStorage(project).ofCode());
|
||||
|
||||
try {
|
||||
if (service.contains("upload")) {
|
||||
git.upload().input(ServletUtils.getInputStream(req)).output(resp.getOutputStream()).call();
|
||||
} else if (service.contains("receive")) {
|
||||
git.receive().input(ServletUtils.getInputStream(req)).output(resp.getOutputStream()).call();
|
||||
} else {
|
||||
String message = "Invalid service name '" + service + "'.";
|
||||
logger.error("Error serving git request: " + message);
|
||||
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("Error serving git request.", e);
|
||||
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
|
||||
if (GitSmartHttpTools.isUploadPack(request)) {
|
||||
if (!SecurityUtils.getSubject().isPermitted(ObjectPermission.ofProjectRead(project))) {
|
||||
throw new UnauthorizedException("You do not have permission to pull from this project.");
|
||||
}
|
||||
git.upload().input(ServletUtils.getInputStream(request)).output(response.getOutputStream()).call();
|
||||
} else {
|
||||
if (!SecurityUtils.getSubject().isPermitted(ObjectPermission.ofProjectWrite(project))) {
|
||||
throw new UnauthorizedException("You do not have permission to push to this project.");
|
||||
}
|
||||
git.receive().input(ServletUtils.getInputStream(request)).output(response.getOutputStream()).call();
|
||||
}
|
||||
}
|
||||
|
||||
protected void processRefs(HttpServletRequest req, HttpServletResponse resp, String pathInfo) throws ServletException, IOException {
|
||||
if (!pathInfo.endsWith(INFO_REFS)) {
|
||||
String message = "Invalid refs request url: " + req.getRequestURL();
|
||||
logger.error("Error serving git request: " + message);
|
||||
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
|
||||
return;
|
||||
}
|
||||
|
||||
private void writeInitial(HttpServletResponse response, String service) throws IOException {
|
||||
doNotCache(response);
|
||||
response.setHeader("Content-Type", "application/x-" + service + "-advertisement");
|
||||
|
||||
String repoInfo = pathInfo.substring(0, pathInfo.length() - INFO_REFS.length());
|
||||
Project project = getProject(req, resp, repoInfo);
|
||||
if (project != null) {
|
||||
doNotCache(resp);
|
||||
String service = req.getParameter("service");
|
||||
resp.setHeader("Content-Type", "application/x-" + service + "-advertisement");
|
||||
|
||||
PacketLineOut pack = new PacketLineOut(resp.getOutputStream());
|
||||
pack.setFlushOnEnd(false);
|
||||
pack.writeString("# service=" + service + "\n");
|
||||
pack.end();
|
||||
|
||||
Git git = new Git(projectManager.locateStorage(project).ofCode());
|
||||
PacketLineOut pack = new PacketLineOut(response.getOutputStream());
|
||||
pack.setFlushOnEnd(false);
|
||||
pack.writeString("# service=" + service + "\n");
|
||||
pack.end();
|
||||
}
|
||||
|
||||
protected void processRefs(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
||||
String pathInfo = request.getRequestURI().substring(request.getContextPath().length());
|
||||
pathInfo = StringUtils.stripStart(pathInfo, "/");
|
||||
|
||||
try {
|
||||
if (service.contains("upload")) {
|
||||
git.advertiseUploadRefs().output(resp.getOutputStream()).call();
|
||||
} else if (service.contains("receive")) {
|
||||
git.advertiseReceiveRefs().output(resp.getOutputStream()).call();
|
||||
} else {
|
||||
String message = "Invalid service name '" + service + "'.";
|
||||
logger.error("Error serving git request: " + message);
|
||||
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("Error serving git request.", e);
|
||||
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
|
||||
String repoInfo = pathInfo.substring(0, pathInfo.length() - INFO_REFS.length());
|
||||
Project project = getProject(request, response, repoInfo);
|
||||
String service = request.getParameter("service");
|
||||
|
||||
Git git = new Git(projectManager.locateStorage(project).ofCode());
|
||||
|
||||
if (service.contains("upload")) {
|
||||
if (!SecurityUtils.getSubject().isPermitted(ObjectPermission.ofProjectRead(project))) {
|
||||
throw new UnauthorizedException("You do not have permission to pull from this project.");
|
||||
}
|
||||
writeInitial(response, service);
|
||||
git.advertiseUploadRefs().output(response.getOutputStream()).call();
|
||||
} else {
|
||||
if (!SecurityUtils.getSubject().isPermitted(ObjectPermission.ofProjectWrite(project))) {
|
||||
throw new UnauthorizedException("You do not have permission to push to this project.");
|
||||
}
|
||||
writeInitial(response, service);
|
||||
git.advertiseReceiveRefs().output(response.getOutputStream()).call();
|
||||
}
|
||||
}
|
||||
|
||||
@ -151,16 +150,24 @@ public class GitFilter implements Filter {
|
||||
FilterChain chain) throws IOException, ServletException {
|
||||
HttpServletRequest httpRequest = (HttpServletRequest) request;
|
||||
HttpServletResponse httpResponse = (HttpServletResponse) response;
|
||||
|
||||
String pathInfo = httpRequest.getRequestURI().substring(httpRequest.getContextPath().length());
|
||||
pathInfo = StringUtils.stripStart(pathInfo, "/");
|
||||
|
||||
if (pathInfo.endsWith(INFO_REFS)) {
|
||||
processRefs(httpRequest, httpResponse, pathInfo);
|
||||
} else if (pathInfo.endsWith("git-receive-pack") || pathInfo.endsWith("git-upload-pack")) {
|
||||
processPacks(httpRequest, httpResponse, pathInfo);
|
||||
} else {
|
||||
chain.doFilter(request, response);
|
||||
|
||||
try {
|
||||
if (GitSmartHttpTools.isInfoRefs(httpRequest)) {
|
||||
if (gitop.isReady())
|
||||
processRefs(httpRequest, httpResponse);
|
||||
else
|
||||
throw new GeneralException("Server is not ready");
|
||||
} else if (GitSmartHttpTools.isReceivePack(httpRequest) || GitSmartHttpTools.isUploadPack(httpRequest)) {
|
||||
if (gitop.isReady())
|
||||
processPacks(httpRequest, httpResponse);
|
||||
else
|
||||
throw new GeneralException("Server is not ready");
|
||||
} else {
|
||||
chain.doFilter(request, response);
|
||||
}
|
||||
} catch (GeneralException e) {
|
||||
logger.error("Error serving git request", e);
|
||||
GitSmartHttpTools.sendError(httpRequest, httpResponse, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -12,11 +12,9 @@ import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.wicket.Application;
|
||||
import org.apache.wicket.Page;
|
||||
import org.apache.wicket.RuntimeConfigurationType;
|
||||
import org.apache.wicket.Session;
|
||||
import org.apache.wicket.bean.validation.BeanValidationConfiguration;
|
||||
import org.apache.wicket.core.request.mapper.MountedMapper;
|
||||
import org.apache.wicket.devutils.stateless.StatelessChecker;
|
||||
import org.apache.wicket.markup.html.IPackageResourceGuard;
|
||||
import org.apache.wicket.markup.html.SecurePackageResourceGuard;
|
||||
import org.apache.wicket.request.IRequestMapper;
|
||||
@ -109,9 +107,9 @@ public class GitopWebApp extends AbstractWicketConfig {
|
||||
mountPages();
|
||||
configureResources();
|
||||
|
||||
if (getConfigurationType() == RuntimeConfigurationType.DEVELOPMENT) {
|
||||
getComponentPreOnBeforeRenderListeners().add(new StatelessChecker());
|
||||
}
|
||||
// if (getConfigurationType() == RuntimeConfigurationType.DEVELOPMENT) {
|
||||
// getComponentPreOnBeforeRenderListeners().add(new StatelessChecker());
|
||||
// }
|
||||
}
|
||||
|
||||
public byte[] getDefaultUserAvatar() {
|
||||
|
||||
@ -1,17 +1,13 @@
|
||||
package com.pmease.gitop.web;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import com.codahale.dropwizard.jackson.Jackson;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.Provides;
|
||||
import com.pmease.commons.jetty.ServletConfigurator;
|
||||
import com.pmease.commons.loader.AbstractPluginModule;
|
||||
import com.pmease.commons.wicket.AbstractWicketConfig;
|
||||
import com.pmease.gitop.core.validation.ProjectNameReservation;
|
||||
import com.pmease.gitop.core.validation.UserNameReservation;
|
||||
import com.pmease.gitop.web.resource.RestResourceModule;
|
||||
|
||||
@ -33,31 +29,8 @@ public class WebModule extends AbstractPluginModule {
|
||||
contribute(UserNameReservation.class, WebUserNameReservation.class);
|
||||
|
||||
install(new RestResourceModule());
|
||||
|
||||
contribute(ProjectNameReservation.class, DefaultProjectNameReservation.class);
|
||||
contribute(UserNameReservation.class, DefaultUserNameReservation.class);
|
||||
}
|
||||
|
||||
public static class DefaultProjectNameReservation implements ProjectNameReservation {
|
||||
|
||||
@Override
|
||||
public Set<String> getReserved() {
|
||||
return ImmutableSet.<String>of(
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public static class DefaultUserNameReservation implements UserNameReservation {
|
||||
|
||||
@Override
|
||||
public Set<String> getReserved() {
|
||||
return ImmutableSet.<String>of(
|
||||
"rest",
|
||||
"assets"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
|
||||
@ -42,6 +42,7 @@ public class WebUserNameReservation implements UserNameReservation {
|
||||
}
|
||||
|
||||
reserved.add("wicket");
|
||||
reserved.add("rest");
|
||||
|
||||
for (IRequestMapper mapper: webApp.getRequestMappers()) {
|
||||
if (mapper instanceof MountedMapper || mapper instanceof ResourceMapper) {
|
||||
|
||||
@ -9,15 +9,11 @@ import com.pmease.gitop.core.model.User;
|
||||
public abstract class AbstractLayoutPage extends BasePage {
|
||||
|
||||
@Override
|
||||
protected void onInitialize() {
|
||||
super.onInitialize();
|
||||
protected void onPageInitialize() {
|
||||
super.onPageInitialize();
|
||||
add(new GlobalHeaderPanel("header"));
|
||||
}
|
||||
|
||||
protected boolean isSignedIn() {
|
||||
return SecurityUtils.getSubject().isAuthenticated();
|
||||
}
|
||||
|
||||
protected Optional<User> currentUser() {
|
||||
User user = User.getCurrent();
|
||||
if (user.isAnonymous()) {
|
||||
@ -26,4 +22,16 @@ public abstract class AbstractLayoutPage extends BasePage {
|
||||
return Optional.of(user);
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean isLoggedIn() {
|
||||
return currentUser().isPresent();
|
||||
}
|
||||
|
||||
protected boolean isRemembered() {
|
||||
return SecurityUtils.getSubject().isRemembered();
|
||||
}
|
||||
|
||||
protected boolean isAuthenticated() {
|
||||
return SecurityUtils.getSubject().isAuthenticated();
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,7 +22,5 @@
|
||||
<p class="chromeframe">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> or <a href="http://www.google.com/chromeframe/?redirect=true">activate Google Chrome Frame</a> to improve your experience.</p>
|
||||
<![endif]-->
|
||||
<wicket:child></wicket:child>
|
||||
|
||||
<wicket:container wicket:id="modal"></wicket:container>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -26,7 +26,6 @@ import com.pmease.gitop.core.Gitop;
|
||||
import com.pmease.gitop.web.assets.BaseResourcesBehavior;
|
||||
import com.pmease.gitop.web.assets.PageResourcesBehavior;
|
||||
import com.pmease.gitop.web.common.component.messenger.MessengerResourcesBehavior;
|
||||
import com.pmease.gitop.web.common.component.modal.Modal;
|
||||
import com.pmease.gitop.web.exception.AccessDeniedException;
|
||||
import com.pmease.gitop.web.page.init.ServerInitPage;
|
||||
|
||||
@ -34,8 +33,10 @@ import com.pmease.gitop.web.page.init.ServerInitPage;
|
||||
public abstract class BasePage extends WebPage {
|
||||
|
||||
private WebMarkupContainer body;
|
||||
|
||||
private boolean shouldInitialize = true;
|
||||
|
||||
private Modal modal;
|
||||
// private Modal modal;
|
||||
|
||||
public BasePage() {
|
||||
commonInit();
|
||||
@ -64,14 +65,15 @@ public abstract class BasePage extends WebPage {
|
||||
}
|
||||
}));
|
||||
|
||||
modal = new Modal("modal");
|
||||
add(modal);
|
||||
// modal = new Modal("modal");
|
||||
// add(modal);
|
||||
|
||||
if (!Gitop.getInstance().isReady()
|
||||
&& getClass() != ServerInitPage.class) {
|
||||
throw new RestartResponseAtInterceptPageException(
|
||||
ServerInitPage.class);
|
||||
redirect(ServerInitPage.class);
|
||||
}
|
||||
|
||||
shouldInitialize = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -127,23 +129,47 @@ public abstract class BasePage extends WebPage {
|
||||
}
|
||||
}
|
||||
|
||||
public final void redirectWithIntercept(final Class<? extends Page> clazz) {
|
||||
shouldInitialize = true;
|
||||
throw new RestartResponseAtInterceptPageException(clazz);
|
||||
}
|
||||
|
||||
public final void redirectWithIntercept(final Class<? extends Page> clazz, final PageParameters pageParams) {
|
||||
shouldInitialize = true;
|
||||
throw new RestartResponseAtInterceptPageException(clazz, pageParams);
|
||||
}
|
||||
|
||||
public final void redirectWithIntercept(final Page page) {
|
||||
shouldInitialize = true;
|
||||
throw new RestartResponseAtInterceptPageException(page);
|
||||
}
|
||||
|
||||
public final void redirect(final Class<? extends Page> clazz) {
|
||||
shouldInitialize = false;
|
||||
throw new RestartResponseException(clazz);
|
||||
}
|
||||
|
||||
public final void redirect(final Class<? extends Page> clazz,
|
||||
PageParameters parameters) {
|
||||
shouldInitialize = false;
|
||||
throw new RestartResponseException(clazz, parameters);
|
||||
}
|
||||
|
||||
public final void redirect(final Page page) {
|
||||
shouldInitialize = false;
|
||||
throw new RestartResponseException(page);
|
||||
}
|
||||
|
||||
public final void redirect(String url) {
|
||||
shouldInitialize = false;
|
||||
throw new RedirectToUrlException(url);
|
||||
}
|
||||
|
||||
|
||||
public final void redirectToOriginal() {
|
||||
shouldInitialize = false;
|
||||
continueToOriginalDestination();
|
||||
}
|
||||
|
||||
protected String getPageCssClass() {
|
||||
String name = getClass().getSimpleName();
|
||||
return StringUtils.camelCaseToLowerCaseWithHyphen(name);
|
||||
@ -152,11 +178,8 @@ public abstract class BasePage extends WebPage {
|
||||
protected boolean isPermitted() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onInitialize() {
|
||||
super.onInitialize();
|
||||
|
||||
|
||||
protected void onPageInitialize() {
|
||||
if (!isPermitted()) {
|
||||
throw new AccessDeniedException();
|
||||
}
|
||||
@ -187,11 +210,20 @@ public abstract class BasePage extends WebPage {
|
||||
* cause components with resources using global resources not working
|
||||
* properly.
|
||||
*/
|
||||
add(new BaseResourcesBehavior());
|
||||
add(new WebMarkupContainer("globalResourceBinder"));
|
||||
// .add(new BaseResourcesBehavior())
|
||||
add(MessengerResourcesBehavior.get());
|
||||
add(PageResourcesBehavior.get());
|
||||
add(new WebMarkupContainer("globalResourceBinder")
|
||||
.add(new BaseResourcesBehavior())
|
||||
.add(MessengerResourcesBehavior.get())
|
||||
.add(PageResourcesBehavior.get()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final void onInitialize() {
|
||||
super.onInitialize();
|
||||
|
||||
System.out.println("Still invoke onInitialize " + getClass());
|
||||
// if (shouldInitialize) {
|
||||
onPageInitialize();
|
||||
// }
|
||||
}
|
||||
|
||||
protected abstract String getPageTitle();
|
||||
@ -200,7 +232,7 @@ public abstract class BasePage extends WebPage {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public Modal getModal() {
|
||||
return modal;
|
||||
}
|
||||
// public Modal getModal() {
|
||||
// return modal;
|
||||
// }
|
||||
}
|
||||
|
||||
@ -37,9 +37,9 @@ public class AccountHomePage extends AbstractLayoutPage {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onInitialize() {
|
||||
super.onInitialize();
|
||||
|
||||
protected void onPageInitialize() {
|
||||
super.onPageInitialize();
|
||||
|
||||
add(new Label("accountName", getAccount().getName()));
|
||||
|
||||
add(new Link<Void>("link") {
|
||||
@ -51,7 +51,7 @@ public class AccountHomePage extends AbstractLayoutPage {
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected String getPageTitle() {
|
||||
return "Gitop";
|
||||
@ -63,7 +63,8 @@ public class AccountHomePage extends AbstractLayoutPage {
|
||||
|
||||
@Override
|
||||
public void detachModels() {
|
||||
accountModel.detach();
|
||||
if (accountModel != null)
|
||||
accountModel.detach();
|
||||
|
||||
super.detachModels();
|
||||
}
|
||||
|
||||
@ -40,13 +40,21 @@ public class RegisterPage extends AbstractLayoutPage {
|
||||
protected String getPageTitle() {
|
||||
return "Gitop - Sign Up";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onInitialize() {
|
||||
super.onInitialize();
|
||||
|
||||
protected void onPageInitialize() {
|
||||
super.onPageInitialize();
|
||||
|
||||
final IModel<User> model = Model.<User>of(new User());
|
||||
Form<User> form = new Form<User>("form", model);
|
||||
Form<User> form = new Form<User>("form", model) {
|
||||
|
||||
@Override
|
||||
protected void onInitialize() {
|
||||
super.onInitialize();
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
add(form);
|
||||
|
||||
form.add(new FeedbackPanel("feedback", form));
|
||||
|
||||
@ -47,9 +47,9 @@ public abstract class AccountSettingPage extends AbstractLayoutPage {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onInitialize() {
|
||||
super.onInitialize();
|
||||
|
||||
protected void onPageInitialize() {
|
||||
super.onPageInitialize();
|
||||
|
||||
add(new UserAvatarLink("userlink", new UserModel(getAccount())));
|
||||
|
||||
add(new ListView<Category>("setting", ImmutableList.<Category>copyOf(Category.values())) {
|
||||
|
||||
@ -36,9 +36,9 @@ public class AccountPasswordPage extends AccountSettingPage {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onInitialize() {
|
||||
super.onInitialize();
|
||||
|
||||
protected void onPageInitialize() {
|
||||
super.onPageInitialize();
|
||||
|
||||
Form<User> form = new Form<User>("form", new UserModel(getAccount()));
|
||||
add(form);
|
||||
form.add(new PasswordFieldElement("oldPass", "Current Password",
|
||||
|
||||
@ -45,8 +45,8 @@ public class AccountProfilePage extends AccountSettingPage {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onInitialize() {
|
||||
super.onInitialize();
|
||||
protected void onPageInitialize() {
|
||||
super.onPageInitialize();
|
||||
|
||||
IModel<User> userModel = new UserModel(getAccount());
|
||||
add(new ProfileForm("form", userModel));
|
||||
|
||||
@ -1,12 +1,19 @@
|
||||
package com.pmease.gitop.web.page.home;
|
||||
|
||||
import org.apache.wicket.devutils.stateless.StatelessComponent;
|
||||
|
||||
import com.pmease.gitop.web.common.component.dropzone.DropZoneBehavior;
|
||||
import com.pmease.gitop.web.common.component.vex.VexLinkBehavior.VexIcon;
|
||||
import com.pmease.gitop.web.page.AbstractLayoutPage;
|
||||
|
||||
@StatelessComponent
|
||||
public class HomePage extends AbstractLayoutPage {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public HomePage() {
|
||||
this.setStatelessHint(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getPageTitle() {
|
||||
@ -14,8 +21,8 @@ public class HomePage extends AbstractLayoutPage {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onInitialize() {
|
||||
super.onInitialize();
|
||||
protected void onPageInitialize() {
|
||||
super.onPageInitialize();
|
||||
|
||||
add(new DropZoneBehavior());
|
||||
}
|
||||
|
||||
@ -1,18 +0,0 @@
|
||||
<html xmlns:wicket>
|
||||
<wicket:panel>
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h4 class="modal-title">Modal title</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>One fine body…</p>
|
||||
<p wicket:id="sen"></p>
|
||||
<a class="btn btn-primary" wicket:id="submit">Submit</a>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||||
<button type="button" class="btn btn-primary">Save changes</button>
|
||||
</div>
|
||||
</wicket:panel>
|
||||
</html>
|
||||
@ -1,32 +0,0 @@
|
||||
package com.pmease.gitop.web.page.home;
|
||||
|
||||
import org.apache.wicket.ajax.AjaxRequestTarget;
|
||||
import org.apache.wicket.ajax.markup.html.AjaxLink;
|
||||
import org.apache.wicket.markup.html.basic.Label;
|
||||
import org.apache.wicket.markup.html.panel.Panel;
|
||||
|
||||
import com.pmease.gitop.web.common.component.modal.Modal;
|
||||
import com.pmease.gitop.web.page.BasePage;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class TestPanel extends Panel {
|
||||
|
||||
public TestPanel(String id) {
|
||||
super(id);
|
||||
|
||||
add(new Label("sen", "I love this game"));
|
||||
add(new AjaxLink<Void>("submit") {
|
||||
|
||||
@Override
|
||||
public void onClick(AjaxRequestTarget target) {
|
||||
Modal modal = ((BasePage) getPage()).getModal();
|
||||
modal.hide(target);
|
||||
|
||||
// modal.setContent(new Label(Modal.CONTENT_ID, "I like it"));
|
||||
// modal.show(target);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@ -3,7 +3,6 @@ package com.pmease.gitop.web.page.init;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.wicket.RestartResponseException;
|
||||
import org.apache.wicket.markup.html.WebMarkupContainer;
|
||||
import org.apache.wicket.markup.html.basic.Label;
|
||||
|
||||
@ -22,36 +21,35 @@ public class ServerInitPage extends BasePage {
|
||||
public ServerInitPage() {
|
||||
initStage = Gitop.getInstance().getInitStage();
|
||||
if (initStage == null) {
|
||||
continueToOriginalDestination();
|
||||
throw new RestartResponseException(getApplication().getHomePage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onInitialize() {
|
||||
super.onInitialize();
|
||||
|
||||
if (initStage != null) {
|
||||
add(new Label("message", initStage.getMessage()));
|
||||
redirectToOriginal();
|
||||
|
||||
if (!initStage.getManualConfigs().isEmpty()) {
|
||||
List<ManualConfigStep> configSteps = new ArrayList<ManualConfigStep>();
|
||||
for (ManualConfig each: initStage.getManualConfigs())
|
||||
configSteps.add(new ManualConfigStep(each));
|
||||
add(new Wizard("wizard", configSteps) {
|
||||
|
||||
@Override
|
||||
protected void finished() {
|
||||
setResponsePage(ServerInitPage.class);
|
||||
}
|
||||
|
||||
});
|
||||
} else {
|
||||
add(new WebMarkupContainer("wizard").setVisible(false));
|
||||
}
|
||||
redirect(getApplication().getHomePage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPageInitialize() {
|
||||
super.onPageInitialize();
|
||||
|
||||
add(new Label("message", initStage.getMessage()));
|
||||
|
||||
if (!initStage.getManualConfigs().isEmpty()) {
|
||||
List<ManualConfigStep> configSteps = new ArrayList<ManualConfigStep>();
|
||||
for (ManualConfig each: initStage.getManualConfigs())
|
||||
configSteps.add(new ManualConfigStep(each));
|
||||
add(new Wizard("wizard", configSteps) {
|
||||
|
||||
@Override
|
||||
protected void finished() {
|
||||
setResponsePage(ServerInitPage.class);
|
||||
}
|
||||
|
||||
});
|
||||
} else {
|
||||
add(new WebMarkupContainer("wizard").setVisible(false));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getPageTitle() {
|
||||
return "Server Initialization";
|
||||
|
||||
@ -3,7 +3,5 @@
|
||||
<h1>Welcome, Project Home</h1>
|
||||
<div wicket:id="accountName"></div>
|
||||
<div wicket:id="projectName"></div>
|
||||
|
||||
<a wicket:id="link">link</a>
|
||||
</wicket:extend>
|
||||
</html>
|
||||
@ -1,7 +1,7 @@
|
||||
package com.pmease.gitop.web.page.project;
|
||||
|
||||
import org.apache.shiro.authz.annotation.RequiresAuthentication;
|
||||
import org.apache.wicket.markup.html.basic.Label;
|
||||
import org.apache.wicket.markup.html.link.Link;
|
||||
import org.apache.wicket.model.IModel;
|
||||
import org.apache.wicket.model.LoadableDetachableModel;
|
||||
import org.apache.wicket.request.mapper.parameter.PageParameters;
|
||||
@ -13,6 +13,7 @@ import com.pmease.gitop.core.model.Project;
|
||||
import com.pmease.gitop.web.page.AbstractLayoutPage;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
@RequiresAuthentication
|
||||
public class ProjectHomePage extends AbstractLayoutPage {
|
||||
|
||||
private final IModel<Project> projectModel;
|
||||
@ -44,25 +45,16 @@ public class ProjectHomePage extends AbstractLayoutPage {
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
add(new Link<Void>("link") {
|
||||
|
||||
@Override
|
||||
public void onClick() {
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onInitialize() {
|
||||
super.onInitialize();
|
||||
protected void onPageInitialize() {
|
||||
super.onPageInitialize();
|
||||
|
||||
add(new Label("accountName", getProject().getOwner().getName()));
|
||||
add(new Label("projectName", getProject().getName()));
|
||||
}
|
||||
|
||||
|
||||
public Project getProject() {
|
||||
return projectModel.getObject();
|
||||
}
|
||||
@ -71,7 +63,6 @@ public class ProjectHomePage extends AbstractLayoutPage {
|
||||
public void detachModels() {
|
||||
if (projectModel != null)
|
||||
projectModel.detach();
|
||||
|
||||
super.detachModels();
|
||||
}
|
||||
|
||||
|
||||
@ -15,8 +15,8 @@ import com.pmease.gitop.web.page.BasePage;
|
||||
public class TestPage extends BasePage {
|
||||
|
||||
@Override
|
||||
protected void onInitialize() {
|
||||
super.onInitialize();
|
||||
protected void onPageInitialize() {
|
||||
super.onPageInitialize();
|
||||
|
||||
final EditContext editContext = EditableUtils.getContext(new Project());
|
||||
|
||||
@ -39,7 +39,7 @@ public class TestPage extends BasePage {
|
||||
|
||||
add(form);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected String getPageTitle() {
|
||||
return "Test page used by Robin";
|
||||
|
||||
@ -28,11 +28,6 @@ public class LoginPage extends AbstractLayoutPage {
|
||||
if (SecurityUtils.getSubject().isAuthenticated()) {
|
||||
throw new RestartResponseException(getApplication().getHomePage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onInitialize() {
|
||||
super.onInitialize();
|
||||
add(new LoginForm("login"));
|
||||
FeedbackPanel feedback = new FeedbackPanel("feedback");
|
||||
add(feedback);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user