summaryrefslogtreecommitdiffstats
path: root/src/main/java/com/gitblit/wicket/GitBlitWebSession.java
blob: b26a1118f97bd2fb081c990a25eb940007e9822f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/*
 * Copyright 2011 gitblit.com.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.gitblit.wicket;

import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;
import java.util.concurrent.atomic.AtomicBoolean;

import org.apache.wicket.Page;
import org.apache.wicket.PageParameters;
import org.apache.wicket.RedirectToUrlException;
import org.apache.wicket.Request;
import org.apache.wicket.Session;
import org.apache.wicket.protocol.http.RequestUtils;
import org.apache.wicket.protocol.http.WebRequestCycle;
import org.apache.wicket.protocol.http.WebSession;
import org.apache.wicket.protocol.http.request.WebClientInfo;

import com.gitblit.Constants.AuthenticationType;
import com.gitblit.models.UserModel;

public final class GitBlitWebSession extends WebSession {

	private static final long serialVersionUID = 1L;

	protected TimeZone timezone;

	private UserModel user;

	private String errorMessage;

	private String requestUrl;

	private AtomicBoolean isForking;

	public AuthenticationType authenticationType;

	public GitBlitWebSession(Request request) {
		super(request);
		isForking = new AtomicBoolean();
		authenticationType = AuthenticationType.CREDENTIALS;
	}

	@Override
	public void invalidate() {
		super.invalidate();
		user = null;
	}

	/**
	 * Cache the requested protected resource pending successful authentication.
	 *
	 * @param pageClass
	 */
	public void cacheRequest(Class<? extends Page> pageClass) {
		// build absolute url with correctly encoded parameters?!
		Request req = WebRequestCycle.get().getRequest();
		Map<String, ?> params = req.getRequestParameters().getParameters();
		PageParameters pageParams = new PageParameters(params);
		String relativeUrl = WebRequestCycle.get().urlFor(pageClass, pageParams).toString();
		requestUrl = RequestUtils.toAbsolutePath(relativeUrl);
		if (isTemporary())
		{
			// we must bind the temporary session into the session store
			// so that we can re-use this session for reporting an error message
			// on the redirected page and continuing the request after
			// authentication.
			bind();
		}
	}

	/**
	 * Continue any cached request.  This is used when a request for a protected
	 * resource is aborted/redirected pending proper authentication.  Gitblit
	 * no longer uses Wicket's built-in mechanism for this because of Wicket's
	 * failure to properly handle parameters with forward-slashes.  This is a
	 * constant source of headaches with Wicket.
	 *
	 * @return false if there is no cached request to process
	 */
	public boolean continueRequest() {
		if (requestUrl != null) {
			String url = requestUrl;
			requestUrl = null;
			throw new RedirectToUrlException(url);
		}
		return false;
	}

	public boolean isLoggedIn() {
		return user != null;
	}

	public boolean canAdmin() {
		if (user == null) {
			return false;
		}
		return user.canAdmin();
	}

	public String getUsername() {
		return user == null ? "anonymous" : user.username;
	}

	public UserModel getUser() {
		return user;
	}

	public void setUser(UserModel user) {
		this.user = user;
		if (user != null) {
			Locale preferredLocale = user.getPreferences().getLocale();
			if (preferredLocale != null) {
				// set the user's preferred locale
				setLocale(preferredLocale);
			}
		}
	}

	public TimeZone getTimezone() {
		if (timezone == null) {
			timezone = ((WebClientInfo) getClientInfo()).getProperties().getTimeZone();
		}
		// use server timezone if we can't determine the client timezone
		if (timezone == null) {
			timezone = TimeZone.getDefault();
		}
		return timezone;
	}

	public void cacheErrorMessage(String message) {
		this.errorMessage = message;
	}

	public String clearErrorMessage() {
		String msg = errorMessage;
		errorMessage = null;
		return msg;
	}

	public boolean isForking() {
		return isForking.get();
	}

	public void isForking(boolean val) {
		isForking.set(val);
	}

	public static GitBlitWebSession get() {
		return (GitBlitWebSession) Session.get();
	}
}
com.gitblit.wicket.pages.UsersPage; import com.google.inject.Inject; import com.google.inject.Provider; import com.google.inject.Singleton; @Singleton public class GitBlitWebApp extends WebApplication implements GitblitWicketApp { private final Class<? extends WebPage> homePageClass = MyDashboardPage.class; private final Class<? extends WebPage> newRepositoryPageClass = NewRepositoryPage.class; private final Map<String, CacheControl> cacheablePages = new HashMap<String, CacheControl>(); private final Provider<IPublicKeyManager> publicKeyManagerProvider; private final Provider<ITicketService> ticketServiceProvider; private final IStoredSettings settings; private final XssFilter xssFilter; private final IRuntimeManager runtimeManager; private final IPluginManager pluginManager; private final INotificationManager notificationManager; private final IUserManager userManager; private final IAuthenticationManager authenticationManager; private final IRepositoryManager repositoryManager; private final IProjectManager projectManager; private final IFederationManager federationManager; private final IGitblit gitblit; private final IServicesManager services; private final IFilestoreManager filestoreManager; @Inject public GitBlitWebApp( Provider<IPublicKeyManager> publicKeyManagerProvider, Provider<ITicketService> ticketServiceProvider, IRuntimeManager runtimeManager, IPluginManager pluginManager, INotificationManager notificationManager, IUserManager userManager, IAuthenticationManager authenticationManager, IRepositoryManager repositoryManager, IProjectManager projectManager, IFederationManager federationManager, IGitblit gitblit, IServicesManager services, IFilestoreManager filestoreManager) { super(); this.publicKeyManagerProvider = publicKeyManagerProvider; this.ticketServiceProvider = ticketServiceProvider; this.settings = runtimeManager.getSettings(); this.xssFilter = runtimeManager.getXssFilter(); this.runtimeManager = runtimeManager; this.pluginManager = pluginManager; this.notificationManager = notificationManager; this.userManager = userManager; this.authenticationManager = authenticationManager; this.repositoryManager = repositoryManager; this.projectManager = projectManager; this.federationManager = federationManager; this.gitblit = gitblit; this.services = services; this.filestoreManager = filestoreManager; } @Override public void init() { super.init(); // Setup page authorization mechanism boolean useAuthentication = settings.getBoolean(Keys.web.authenticateViewPages, false) || settings.getBoolean(Keys.web.authenticateAdminPages, false); if (useAuthentication) { AuthorizationStrategy authStrategy = new AuthorizationStrategy(settings, homePageClass); getSecuritySettings().setAuthorizationStrategy(authStrategy); getSecuritySettings().setUnauthorizedComponentInstantiationListener(authStrategy); } // Grab Browser info (like timezone, etc) if (settings.getBoolean(Keys.web.useClientTimezone, false)) { getRequestCycleSettings().setGatherExtendedBrowserInfo(true); } // configure the resource cache duration to 90 days for deployment if (!isDebugMode()) { getResourceSettings().setDefaultCacheDuration(90 * 86400); } // setup the standard gitweb-ish urls mount("/repositories", RepositoriesPage.class); mount("/overview", OverviewPage.class, "r"); mount("/summary", SummaryPage.class, "r"); mount("/reflog", ReflogPage.class, "r"); mount("/commits", LogPage.class, "r", "h"); mount("/log", LogPage.class, "r", "h"); mount("/tags", TagsPage.class, "r"); mount("/branches", BranchesPage.class, "r"); mount("/commit", CommitPage.class, "r", "h"); mount("/tag", TagPage.class, "r", "h"); mount("/tree", TreePage.class, "r", "h", "f"); mount("/blob", BlobPage.class, "r", "h", "f"); mount("/blobdiff", BlobDiffPage.class, "r", "h", "f"); mount("/commitdiff", CommitDiffPage.class, "r", "h"); mount("/compare", ComparePage.class, "r", "h"); mount("/patch", PatchPage.class, "r", "h", "f"); mount("/history", HistoryPage.class, "r", "h", "f"); mount("/search", GitSearchPage.class); mount("/metrics", MetricsPage.class, "r"); mount("/blame", BlamePage.class, "r", "h", "f"); mount("/users", UsersPage.class); mount("/teams", TeamsPage.class); mount("/logout", LogoutPage.class); // setup ticket urls mount("/tickets", TicketsPage.class, "r", "h"); mount("/tickets/new", NewTicketPage.class, "r"); mount("/tickets/edit", EditTicketPage.class, "r", "h"); mount("/tickets/export", ExportTicketPage.class, "r", "h"); mount("/milestones/new", NewMilestonePage.class, "r"); mount("/milestones/edit", EditMilestonePage.class, "r", "h"); mount("/mytickets", MyTicketsPage.class, "r", "h"); // setup the markup document urls mount("/docs", DocsPage.class, "r", "h"); mount("/doc", DocPage.class, "r", "h", "f"); mount("/editfile", EditFilePage.class, "r", "h", "f"); // federation urls mount("/proposal", ReviewProposalPage.class, "t"); mount("/registration", FederationRegistrationPage.class, "u", "n"); mount("/new", NewRepositoryPage.class); mount("/edit", EditRepositoryPage.class, "r"); mount("/activity", ActivityPage.class, "r", "h"); mount("/lucene", LuceneSearchPage.class); mount("/project", ProjectPage.class, "p"); mount("/projects", ProjectsPage.class); mount("/user", UserPage.class, "user"); mount("/forks", ForksPage.class, "r"); mount("/fork", ForkPage.class, "r"); // filestore URL mount("/filestore", FilestorePage.class); // allow started Wicket plugins to initialize for (PluginWrapper pluginWrapper : pluginManager.getPlugins()) { if (PluginState.STARTED != pluginWrapper.getPluginState()) { continue; } if (pluginWrapper.getPlugin() instanceof GitblitWicketPlugin) { GitblitWicketPlugin wicketPlugin = (GitblitWicketPlugin) pluginWrapper.getPlugin(); wicketPlugin.init(this); } } // customize the Wicket class resolver to load from plugins IClassResolver coreResolver = getApplicationSettings().getClassResolver(); PluginClassResolver classResolver = new PluginClassResolver(coreResolver, pluginManager); getApplicationSettings().setClassResolver(classResolver); getMarkupSettings().setDefaultMarkupEncoding("UTF-8"); } /* (non-Javadoc) * @see com.gitblit.wicket.Webapp#mount(java.lang.String, java.lang.Class, java.lang.String) */ @Override public void mount(String location, Class<? extends WebPage> clazz, String... parameters) { if (parameters == null) { parameters = new String[] {}; } if (!settings.getBoolean(Keys.web.mountParameters, true)) { parameters = new String[] {}; } mount(new GitblitParamUrlCodingStrategy(settings, xssFilter, location, clazz, parameters)); // map the mount point to the cache control definition if (clazz.isAnnotationPresent(CacheControl.class)) { CacheControl cacheControl = clazz.getAnnotation(CacheControl.class); cacheablePages.put(location.substring(1), cacheControl); } } /* (non-Javadoc) * @see com.gitblit.wicket.Webapp#getHomePage() */ @Override public Class<? extends WebPage> getHomePage() { return homePageClass; } public Class<? extends WebPage> getNewRepositoryPage() { return newRepositoryPageClass; } /* (non-Javadoc) * @see com.gitblit.wicket.Webapp#isCacheablePage(java.lang.String) */ @Override public boolean isCacheablePage(String mountPoint) { return cacheablePages.containsKey(mountPoint); } /* (non-Javadoc) * @see com.gitblit.wicket.Webapp#getCacheControl(java.lang.String) */ @Override public CacheControl getCacheControl(String mountPoint) { return cacheablePages.get(mountPoint); } @Override public final Session newSession(Request request, Response response) { GitBlitWebSession gitBlitWebSession = new GitBlitWebSession(request); Locale forcedLocale = runtime().getLocale(); if (forcedLocale != null) { gitBlitWebSession.setLocale(forcedLocale); } return gitBlitWebSession; } /* (non-Javadoc) * @see com.gitblit.wicket.Webapp#settings() */ @Override public IStoredSettings settings() { return settings; } /* (non-Javadoc) * @see com.gitblit.wicket.Webapp#xssFilter() */ @Override public XssFilter xssFilter() { return xssFilter; } /* (non-Javadoc) * @see com.gitblit.wicket.Webapp#isDebugMode() */ @Override public boolean isDebugMode() { return runtimeManager.isDebugMode(); } /* * These methods look strange... and they are... but they are the first * step towards modularization across multiple commits. */ /* (non-Javadoc) * @see com.gitblit.wicket.Webapp#getBootDate() */ @Override public Date getBootDate() { return runtimeManager.getBootDate(); } /* (non-Javadoc) * @see com.gitblit.wicket.Webapp#getLastActivityDate() */ @Override public Date getLastActivityDate() { return repositoryManager.getLastActivityDate(); } /* (non-Javadoc) * @see com.gitblit.wicket.Webapp#runtime() */ @Override public IRuntimeManager runtime() { return runtimeManager; } /* (non-Javadoc) * @see com.gitblit.wicket.Webapp#plugins() */ @Override public IPluginManager plugins() { return pluginManager; } /* (non-Javadoc) * @see com.gitblit.wicket.Webapp#notifier() */ @Override public INotificationManager notifier() { return notificationManager; } /* (non-Javadoc) * @see com.gitblit.wicket.Webapp#users() */ @Override public IUserManager users() { return userManager; } /* (non-Javadoc) * @see com.gitblit.wicket.Webapp#authentication() */ @Override public IAuthenticationManager authentication() { return authenticationManager; } /* (non-Javadoc) * @see com.gitblit.wicket.Webapp#keys() */ @Override public IPublicKeyManager keys() { return publicKeyManagerProvider.get(); } /* (non-Javadoc) * @see com.gitblit.wicket.Webapp#repositories() */ @Override public IRepositoryManager repositories() { return repositoryManager; } /* (non-Javadoc) * @see com.gitblit.wicket.Webapp#projects() */ @Override public IProjectManager projects() { return projectManager; } /* (non-Javadoc) * @see com.gitblit.wicket.Webapp#federation() */ @Override public IFederationManager federation() { return federationManager; } /* (non-Javadoc) * @see com.gitblit.wicket.Webapp#gitblit() */ @Override public IGitblit gitblit() { return gitblit; } /* (non-Javadoc) * @see com.gitblit.wicket.Webapp#services() */ @Override public IServicesManager services() { return services; } /* (non-Javadoc) * @see com.gitblit.wicket.Webapp#tickets() */ @Override public ITicketService tickets() { return ticketServiceProvider.get(); } /* (non-Javadoc) * @see com.gitblit.wicket.Webapp#getTimezone() */ @Override public TimeZone getTimezone() { return runtimeManager.getTimezone(); } @Override public final String getConfigurationType() { if (runtimeManager.isDebugMode()) { return Application.DEVELOPMENT; } return Application.DEPLOYMENT; } public static GitBlitWebApp get() { return (GitBlitWebApp) WebApplication.get(); } @Override public IFilestoreManager filestore() { return filestoreManager; } }