From 9effe1630d97039b3e01cd9b58ed07e75be1d63c Mon Sep 17 00:00:00 2001 From: James Moger <james.moger@gitblit.com> Date: Mon, 25 Feb 2013 08:40:30 -0500 Subject: [PATCH] Merge pull request #75 from thefake/master --- src/com/gitblit/wicket/pages/BasePage.java | 257 ++++++++++++++++++++++++++++++++++++++++++++------ 1 files changed, 224 insertions(+), 33 deletions(-) diff --git a/src/com/gitblit/wicket/pages/BasePage.java b/src/com/gitblit/wicket/pages/BasePage.java index 515e9ce..c733c99 100644 --- a/src/com/gitblit/wicket/pages/BasePage.java +++ b/src/com/gitblit/wicket/pages/BasePage.java @@ -15,24 +15,36 @@ */ package com.gitblit.wicket.pages; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collections; +import java.util.Date; +import java.util.HashSet; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; +import java.util.ResourceBundle; +import java.util.Set; import java.util.TimeZone; +import java.util.regex.Pattern; -import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import org.apache.wicket.Application; import org.apache.wicket.MarkupContainer; import org.apache.wicket.PageParameters; -import org.apache.wicket.RestartResponseAtInterceptPageException; +import org.apache.wicket.RedirectToUrlException; +import org.apache.wicket.RequestCycle; import org.apache.wicket.RestartResponseException; +import org.apache.wicket.markup.html.CSSPackageResource; import org.apache.wicket.markup.html.WebPage; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.link.BookmarkablePageLink; import org.apache.wicket.markup.html.link.ExternalLink; import org.apache.wicket.markup.html.panel.FeedbackPanel; import org.apache.wicket.markup.html.panel.Fragment; +import org.apache.wicket.protocol.http.RequestUtils; import org.apache.wicket.protocol.http.WebRequest; import org.apache.wicket.protocol.http.WebResponse; import org.apache.wicket.protocol.http.servlet.ServletWebRequest; @@ -40,12 +52,18 @@ import org.slf4j.LoggerFactory; import com.gitblit.Constants; +import com.gitblit.Constants.AccessPermission; import com.gitblit.Constants.AccessRestrictionType; +import com.gitblit.Constants.AuthorizationControl; import com.gitblit.Constants.FederationStrategy; import com.gitblit.GitBlit; import com.gitblit.Keys; +import com.gitblit.models.ProjectModel; import com.gitblit.models.RepositoryModel; +import com.gitblit.models.TeamModel; import com.gitblit.models.UserModel; +import com.gitblit.utils.StringUtils; +import com.gitblit.utils.TimeUtils; import com.gitblit.wicket.GitBlitWebSession; import com.gitblit.wicket.WicketUtils; import com.gitblit.wicket.panels.LinkPanel; @@ -53,17 +71,48 @@ public abstract class BasePage extends WebPage { private final Logger logger; + + private transient TimeUtils timeUtils; public BasePage() { super(); logger = LoggerFactory.getLogger(getClass()); - loginByCookie(); + customizeHeader(); + login(); } public BasePage(PageParameters params) { super(params); logger = LoggerFactory.getLogger(getClass()); - loginByCookie(); + customizeHeader(); + login(); + } + + private void customizeHeader() { + if (GitBlit.getBoolean(Keys.web.useResponsiveLayout, true)) { + add(CSSPackageResource.getHeaderContribution("bootstrap/css/bootstrap-responsive.css")); + } + } + + protected String getLanguageCode() { + return GitBlitWebSession.get().getLocale().getLanguage(); + } + + protected String getCountryCode() { + return GitBlitWebSession.get().getLocale().getCountry().toLowerCase(); + } + + protected TimeUtils getTimeUtils() { + if (timeUtils == null) { + ResourceBundle bundle; + try { + bundle = ResourceBundle.getBundle("com.gitblit.wicket.GitBlitWebApp", GitBlitWebSession.get().getLocale()); + } catch (Throwable t) { + bundle = ResourceBundle.getBundle("com.gitblit.wicket.GitBlitWebApp"); + } + timeUtils = new TimeUtils(bundle); + } + return timeUtils; } @Override @@ -84,22 +133,22 @@ super.onAfterRender(); } - private void loginByCookie() { - if (!GitBlit.getBoolean(Keys.web.allowCookieAuthentication, false)) { + private void login() { + GitBlitWebSession session = GitBlitWebSession.get(); + if (session.isLoggedIn() && !session.isSessionInvalidated()) { + // already have a session, refresh usermodel to pick up + // any changes to permissions or roles (issue-186) + UserModel user = GitBlit.self().getUserModel(session.getUser().username); + session.setUser(user); return; } - UserModel user = null; - - // Grab cookie from Browser Session - Cookie[] cookies = ((WebRequest) getRequestCycle().getRequest()).getCookies(); - if (cookies != null && cookies.length > 0) { - user = GitBlit.self().authenticate(cookies); - } + + // try to authenticate by servlet request + HttpServletRequest httpRequest = ((WebRequest) getRequestCycle().getRequest()).getHttpServletRequest(); + UserModel user = GitBlit.self().authenticate(httpRequest); // Login the user if (user != null) { - // Set the user into the session - GitBlitWebSession session = GitBlitWebSession.get(); // issue 62: fix session fixation vulnerability session.replaceSession(); session.setUser(user); @@ -107,7 +156,8 @@ // Set Cookie WebResponse response = (WebResponse) getRequestCycle().getResponse(); GitBlit.self().setCookie(response, user); - continueToOriginalDestination(); + + session.continueRequest(); } } @@ -161,6 +211,39 @@ return map; } + protected Map<AccessPermission, String> getAccessPermissions() { + Map<AccessPermission, String> map = new LinkedHashMap<AccessPermission, String>(); + for (AccessPermission type : AccessPermission.values()) { + switch (type) { + case NONE: + map.put(type, MessageFormat.format(getString("gb.noPermission"), type.code)); + break; + case EXCLUDE: + map.put(type, MessageFormat.format(getString("gb.excludePermission"), type.code)); + break; + case VIEW: + map.put(type, MessageFormat.format(getString("gb.viewPermission"), type.code)); + break; + case CLONE: + map.put(type, MessageFormat.format(getString("gb.clonePermission"), type.code)); + break; + case PUSH: + map.put(type, MessageFormat.format(getString("gb.pushPermission"), type.code)); + break; + case CREATE: + map.put(type, MessageFormat.format(getString("gb.createPermission"), type.code)); + break; + case DELETE: + map.put(type, MessageFormat.format(getString("gb.deletePermission"), type.code)); + break; + case REWIND: + map.put(type, MessageFormat.format(getString("gb.rewindPermission"), type.code)); + break; + } + } + return map; + } + protected Map<FederationStrategy, String> getFederationTypes() { Map<FederationStrategy, String> map = new LinkedHashMap<FederationStrategy, String>(); for (FederationStrategy type : FederationStrategy.values()) { @@ -178,10 +261,25 @@ } return map; } + + protected Map<AuthorizationControl, String> getAuthorizationControls() { + Map<AuthorizationControl, String> map = new LinkedHashMap<AuthorizationControl, String>(); + for (AuthorizationControl type : AuthorizationControl.values()) { + switch (type) { + case AUTHENTICATED: + map.put(type, getString("gb.allowAuthenticatedDescription")); + break; + case NAMED: + map.put(type, getString("gb.allowNamedDescription")); + break; + } + } + return map; + } protected TimeZone getTimeZone() { return GitBlit.getBoolean(Keys.web.useClientTimezone, false) ? GitBlitWebSession.get() - .getTimezone() : TimeZone.getDefault(); + .getTimezone() : GitBlit.getTimezone(); } protected String getServerName() { @@ -190,30 +288,115 @@ return req.getServerName(); } - protected String getRepositoryUrl(RepositoryModel repository) { + public static String getRepositoryUrl(RepositoryModel repository) { StringBuilder sb = new StringBuilder(); - sb.append(WicketUtils.getGitblitURL(getRequestCycle().getRequest())); + sb.append(WicketUtils.getGitblitURL(RequestCycle.get().getRequest())); sb.append(Constants.GIT_PATH); sb.append(repository.name); // inject username into repository url if authentication is required if (repository.accessRestriction.exceeds(AccessRestrictionType.NONE) && GitBlitWebSession.get().isLoggedIn()) { - String username = GitBlitWebSession.get().getUser().username; + String username = GitBlitWebSession.get().getUsername(); sb.insert(sb.indexOf("://") + 3, username + "@"); } return sb.toString(); + } + + protected List<ProjectModel> getProjectModels() { + final UserModel user = GitBlitWebSession.get().getUser(); + List<ProjectModel> projects = GitBlit.self().getProjectModels(user, true); + return projects; + } + + protected List<ProjectModel> getProjects(PageParameters params) { + if (params == null) { + return getProjectModels(); + } + + boolean hasParameter = false; + String regex = WicketUtils.getRegEx(params); + String team = WicketUtils.getTeam(params); + int daysBack = params.getInt("db", 0); + + List<ProjectModel> availableModels = getProjectModels(); + Set<ProjectModel> models = new HashSet<ProjectModel>(); + + if (!StringUtils.isEmpty(regex)) { + // filter the projects by the regex + hasParameter = true; + Pattern pattern = Pattern.compile(regex); + for (ProjectModel model : availableModels) { + if (pattern.matcher(model.name).find()) { + models.add(model); + } + } + } + + if (!StringUtils.isEmpty(team)) { + // filter the projects by the specified teams + hasParameter = true; + List<String> teams = StringUtils.getStringsFromValue(team, ","); + + // need TeamModels first + List<TeamModel> teamModels = new ArrayList<TeamModel>(); + for (String name : teams) { + TeamModel teamModel = GitBlit.self().getTeamModel(name); + if (teamModel != null) { + teamModels.add(teamModel); + } + } + + // brute-force our way through finding the matching models + for (ProjectModel projectModel : availableModels) { + for (String repositoryName : projectModel.repositories) { + for (TeamModel teamModel : teamModels) { + if (teamModel.hasRepositoryPermission(repositoryName)) { + models.add(projectModel); + } + } + } + } + } + + if (!hasParameter) { + models.addAll(availableModels); + } + + // time-filter the list + if (daysBack > 0) { + Calendar cal = Calendar.getInstance(); + cal.set(Calendar.HOUR_OF_DAY, 0); + cal.set(Calendar.MINUTE, 0); + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MILLISECOND, 0); + cal.add(Calendar.DATE, -1 * daysBack); + Date threshold = cal.getTime(); + Set<ProjectModel> timeFiltered = new HashSet<ProjectModel>(); + for (ProjectModel model : models) { + if (model.lastChange.after(threshold)) { + timeFiltered.add(model); + } + } + models = timeFiltered; + } + + List<ProjectModel> list = new ArrayList<ProjectModel>(models); + Collections.sort(list); + return list; } public void warn(String message, Throwable t) { logger.warn(message, t); } - + public void error(String message, boolean redirect) { - logger.error(message); + logger.error(message + " for " + GitBlitWebSession.get().getUsername()); if (redirect) { GitBlitWebSession.get().cacheErrorMessage(message); - throw new RestartResponseException(getApplication().getHomePage()); + String relativeUrl = urlFor(RepositoriesPage.class, null).toString(); + String absoluteUrl = RequestUtils.toAbsolutePath(relativeUrl); + throw new RedirectToUrlException(absoluteUrl); } else { super.error(message); } @@ -230,12 +413,13 @@ } public void authenticationError(String message) { - logger.error(message); - if (GitBlitWebSession.get().isLoggedIn()) { - error(message, true); - } else { - throw new RestartResponseAtInterceptPageException(RepositoriesPage.class); + logger.error(getRequest().getURL() + " for " + GitBlitWebSession.get().getUsername()); + if (!GitBlitWebSession.get().isLoggedIn()) { + // cache the request if we have not authenticated. + // the request will continue after authentication. + GitBlitWebSession.get().cacheRequest(getClass()); } + error(message, true); } /** @@ -249,14 +433,21 @@ public UserFragment(String id, String markupId, MarkupContainer markupProvider) { super(id, markupId, markupProvider); - if (GitBlitWebSession.get().isLoggedIn()) { + GitBlitWebSession session = GitBlitWebSession.get(); + if (session.isLoggedIn()) { + UserModel user = session.getUser(); + boolean editCredentials = GitBlit.self().supportsCredentialChanges(user); + boolean standardLogin = session.authenticationType.isStandard(); + // username, logout, and change password - add(new Label("username", GitBlitWebSession.get().getUser().toString() + ":")); + add(new Label("username", user.getDisplayName() + ":")); add(new LinkPanel("loginLink", null, markupProvider.getString("gb.logout"), - LogoutPage.class)); + LogoutPage.class).setVisible(standardLogin)); + // quick and dirty hack for showing a separator - add(new Label("separator", "|")); - add(new BookmarkablePageLink<Void>("changePasswordLink", ChangePasswordPage.class)); + add(new Label("separator", "|").setVisible(standardLogin && editCredentials)); + add(new BookmarkablePageLink<Void>("changePasswordLink", + ChangePasswordPage.class).setVisible(editCredentials)); } else { // login add(new Label("username").setVisible(false)); -- Gitblit v1.9.1