# Require authentication for http/https push/pull access of git repositories\r
authenticatePushPull = true\r
\r
+# Require authentication to see the web ui\r
+authenticateWebUI = true\r
+\r
# Simple user realm file to authenticate users for push/pull\r
realmFile = users.properties\r
\r
* the byte array\r
* @return the SHA1 checksum\r
*/\r
- private static String getSHA1(byte[] data) {\r
+ public static String getSHA1(byte[] data) {\r
MessageDigest md;\r
try {\r
md = MessageDigest.getInstance("SHA-1");\r
--- /dev/null
+package com.gitblit.wicket;\r
+\r
+import java.lang.annotation.ElementType;\r
+import java.lang.annotation.Retention;\r
+import java.lang.annotation.RetentionPolicy;\r
+import java.lang.annotation.Target;\r
+\r
+@Retention(RetentionPolicy.RUNTIME)\r
+@Target(ElementType.TYPE)\r
+public @interface AdminPage {\r
+}\r
--- /dev/null
+package com.gitblit.wicket;\r
+\r
+import org.apache.wicket.Component;\r
+import org.apache.wicket.RestartResponseAtInterceptPageException;\r
+import org.apache.wicket.authorization.IUnauthorizedComponentInstantiationListener;\r
+import org.apache.wicket.authorization.strategies.page.AbstractPageAuthorizationStrategy;\r
+\r
+import com.gitblit.wicket.pages.RepositoriesPage;\r
+\r
+public class AuthorizationStrategy extends AbstractPageAuthorizationStrategy implements IUnauthorizedComponentInstantiationListener {\r
+\r
+ public AuthorizationStrategy() {\r
+ }\r
+\r
+ @SuppressWarnings({ "unchecked", "rawtypes" })\r
+ @Override\r
+ protected boolean isPageAuthorized(Class pageClass) {\r
+ if (BasePage.class.isAssignableFrom(pageClass))\r
+ return isAuthorized(pageClass);\r
+ // Return contruction by default\r
+ return true;\r
+ }\r
+\r
+ @Override\r
+ public void onUnauthorizedInstantiation(Component component) {\r
+ if (component instanceof BasePage) { \r
+ GitBlitWebSession session = GitBlitWebSession.get(); \r
+ if (!session.isLoggedIn())\r
+ throw new RestartResponseAtInterceptPageException(LoginPage.class);\r
+ else\r
+ throw new RestartResponseAtInterceptPageException(RepositoriesPage.class);\r
+ }\r
+ }\r
+\r
+ protected boolean isAuthorized(Class<? extends BasePage> pageClass) {\r
+ GitBlitWebSession session = GitBlitWebSession.get();\r
+ if (!session.isLoggedIn())\r
+ return false;\r
+ User user = session.getUser();\r
+ if (pageClass.isAnnotationPresent(AdminPage.class)) {\r
+ \r
+ }\r
+ return true;\r
+ }\r
+}\r
<div style="float:right">\r
<a href="http://gitblit.com"><span wicket:id="gbVersion"></span></a> \r
</div>\r
- <div wicket:id="footerText">[footer text]</div>\r
+ <div wicket:id="userText">[user text]</div>\r
</div>\r
</body>\r
</html>
\ No newline at end of file
public BasePage(PageParameters params) {\r
super(params);\r
}\r
- \r
+ \r
protected void setupPage(String repositoryName, String pageName) {\r
if (repositoryName != null && repositoryName.trim().length() > 0) {\r
add(new Label("title", getServerName() + " - " + repositoryName));\r
add(new Label("pageName", pageName));\r
\r
// footer\r
- add(new Label("footerText", ""));\r
+ User user = null;\r
+ if (StoredSettings.getBoolean("authenticateWebUI", true)) {\r
+ user = GitBlitWebSession.get().getUser();\r
+ add(new Label("userText", "Logout " + user.toString()));\r
+ } else {\r
+ add(new Label("userText", ""));\r
+ }\r
add(new Label("gbVersion", "v" + Constants.VERSION));\r
if (StoredSettings.getBoolean("aggressiveHeapManagement", false)) {\r
System.gc();\r
import java.util.Date;\r
import java.util.List;\r
\r
+import javax.servlet.http.Cookie;\r
import javax.servlet.http.HttpServletRequest;\r
\r
import org.apache.wicket.Application;\r
import org.apache.wicket.Response;\r
import org.apache.wicket.Session;\r
import org.apache.wicket.protocol.http.WebApplication;\r
+import org.apache.wicket.protocol.http.WebResponse;\r
import org.apache.wicket.protocol.http.request.urlcompressing.UrlCompressingWebRequestProcessor;\r
import org.apache.wicket.protocol.http.servlet.ServletWebRequest;\r
import org.apache.wicket.request.IRequestCycleProcessor;\r
import org.slf4j.Logger;\r
import org.slf4j.LoggerFactory;\r
\r
+import com.gitblit.Constants;\r
import com.gitblit.GitBlitServer;\r
import com.gitblit.StoredSettings;\r
import com.gitblit.utils.JGitUtils;\r
import com.gitblit.wicket.pages.BlobDiffPage;\r
import com.gitblit.wicket.pages.BlobPage;\r
import com.gitblit.wicket.pages.BranchesPage;\r
-import com.gitblit.wicket.pages.CommitPage;\r
import com.gitblit.wicket.pages.CommitDiffPage;\r
+import com.gitblit.wicket.pages.CommitPage;\r
import com.gitblit.wicket.pages.LogPage;\r
import com.gitblit.wicket.pages.PatchPage;\r
import com.gitblit.wicket.pages.RawPage;\r
import com.gitblit.wicket.pages.TicGitTicketPage;\r
import com.gitblit.wicket.pages.TreePage;\r
\r
-\r
public class GitBlitWebApp extends WebApplication {\r
\r
- public static int PAGING_ITEM_COUNT = 50;\r
-\r
Logger logger = LoggerFactory.getLogger(GitBlitWebApp.class);\r
\r
FileResolver repositoryResolver;\r
public void init() {\r
super.init();\r
\r
+ // Setup page authorization mechanism\r
+ if (StoredSettings.getBoolean("authenticateWebUI", false)) {\r
+ AuthorizationStrategy authStrategy = new AuthorizationStrategy();\r
+ getSecuritySettings().setAuthorizationStrategy(authStrategy);\r
+ getSecuritySettings().setUnauthorizedComponentInstantiationListener(authStrategy);\r
+ }\r
+\r
// Grab Browser info (like timezone, etc)\r
- getRequestCycleSettings().setGatherExtendedBrowserInfo(true);\r
+ if (StoredSettings.getBoolean("useClientTimezone", false)) {\r
+ getRequestCycleSettings().setGatherExtendedBrowserInfo(true);\r
+ }\r
\r
// setup the standard gitweb-ish urls\r
mount(new MixedParamUrlCodingStrategy("/summary", SummaryPage.class, new String[] { "r" }));\r
mount(new MixedParamUrlCodingStrategy("/blobdiff", BlobDiffPage.class, new String[] { "r", "h", "f" }));\r
mount(new MixedParamUrlCodingStrategy("/commitdiff", CommitDiffPage.class, new String[] { "r", "h" }));\r
mount(new MixedParamUrlCodingStrategy("/patch", PatchPage.class, new String[] { "r", "h", "f" }));\r
- \r
+\r
// setup extended urls\r
mount(new MixedParamUrlCodingStrategy("/ticgit", TicGitPage.class, new String[] { "r" }));\r
mount(new MixedParamUrlCodingStrategy("/ticgittkt", TicGitTicketPage.class, new String[] { "r", "h", "f" }));\r
- \r
+\r
+ mount(new MixedParamUrlCodingStrategy("/login", LoginPage.class, new String[] {}));\r
+\r
repositories = new File(StoredSettings.getString("repositoriesFolder", "repos"));\r
exportAll = StoredSettings.getBoolean("exportAll", true);\r
repositoryResolver = new FileResolver(repositories, exportAll);\r
return Application.DEPLOYMENT;\r
}\r
\r
+ public User authenticate(String username, char [] password) {\r
+ return new User(username, password);\r
+ }\r
+\r
+ public User authenticate(Cookie[] cookies) {\r
+ if (cookies != null && cookies.length > 0) {\r
+ for (Cookie cookie:cookies) {\r
+ if (cookie.getName().equals(Constants.NAME)) {\r
+ String value = cookie.getValue();\r
+ }\r
+ }\r
+ }\r
+ return null;\r
+ }\r
+ \r
+ public void setCookie(WebResponse response, User user) {\r
+ Cookie userCookie = new Cookie(Constants.NAME, user.getCookie());\r
+ userCookie.setMaxAge(Integer.MAX_VALUE);\r
+ userCookie.setPath("/");\r
+ response.addCookie(userCookie);\r
+ }\r
+\r
public List<String> getRepositoryList() {\r
return JGitUtils.getRepositoryList(repositories, exportAll, StoredSettings.getBoolean("nestedRepositories", true));\r
}\r
private static final long serialVersionUID = 1L;\r
\r
protected TimeZone timezone = null;\r
+ \r
+ private User user = null;\r
\r
public GitBlitWebSession(Request request) {\r
super(request);\r
\r
public void invalidate() {\r
super.invalidate();\r
+ user = null;\r
+ }\r
+ \r
+ public boolean isLoggedIn() {\r
+ return user != null;\r
+ }\r
+ \r
+ public User getUser() {\r
+ return user;\r
+ }\r
+ \r
+ public void setUser(User user) {\r
+ this.user = user;\r
}\r
\r
public TimeZone getTimezone() {\r
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\r
+<html xmlns="http://www.w3.org/1999/xhtml" \r
+ xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.3-strict.dtd" \r
+ xml:lang="en" \r
+ lang="en"> \r
+ \r
+ <!-- Head with Wicket-controlled resources in this package -->\r
+ <wicket:head>\r
+ <title wicket:id="title">[page title]</title>\r
+ <wicket:link>\r
+ <link rel="stylesheet" type="text/css" href="resources/gitblit.css"/>\r
+ <link rel="shortcut icon" href="resources/gitblt-favicon.png" type="image/png" />\r
+ </wicket:link>\r
+ </wicket:head>\r
+ \r
+\r
+ <body onload="document.getElementById('username').focus();">\r
+ <div>\r
+ <center>\r
+ <img wicket:id="logo" /><br/>\r
+ <span style="font-weight:bold;" wicket:id="name">[name]</span><br/>\r
+\r
+ <div>\r
+ <form style="text-align:center;" wicket:id="loginForm">\r
+ <p/>\r
+ Username <input type="text" id="username" wicket:id="username" value=""/>\r
+ <p/>\r
+ Password <input type="password" wicket:id="password" value=""/>\r
+ <p/>\r
+ <input type="submit" value="Login" />\r
+ <div style="background-color:#c7c7c7" wicket:id="feedback"></div>\r
+ </form>\r
+ </div>\r
+ </center>\r
+ </div>\r
+ </body>\r
+</html>
\ No newline at end of file
--- /dev/null
+package com.gitblit.wicket;\r
+\r
+import javax.servlet.http.Cookie;\r
+import javax.servlet.http.HttpServletRequest;\r
+\r
+import org.apache.wicket.PageParameters;\r
+import org.apache.wicket.markup.html.WebPage;\r
+import org.apache.wicket.markup.html.basic.Label;\r
+import org.apache.wicket.markup.html.form.Form;\r
+import org.apache.wicket.markup.html.form.PasswordTextField;\r
+import org.apache.wicket.markup.html.form.TextField;\r
+import org.apache.wicket.markup.html.image.ContextImage;\r
+import org.apache.wicket.markup.html.panel.FeedbackPanel;\r
+import org.apache.wicket.model.IModel;\r
+import org.apache.wicket.model.Model;\r
+import org.apache.wicket.protocol.http.WebRequest;\r
+import org.apache.wicket.protocol.http.WebResponse;\r
+import org.apache.wicket.protocol.http.servlet.ServletWebRequest;\r
+\r
+import com.gitblit.Constants;\r
+\r
+public class LoginPage extends WebPage {\r
+\r
+ IModel<String> username = new Model<String>("");\r
+ IModel<String> password = new Model<String>("");\r
+\r
+ public LoginPage(PageParameters params) {\r
+ super(params);\r
+\r
+ tryAutomaticLogin();\r
+\r
+ add(new Label("title", getServerName()));\r
+ add(new ContextImage("logo", "gitblt2.png"));\r
+ add(new Label("name", Constants.NAME));\r
+\r
+ Form<Void> loginForm = new LoginForm("loginForm");\r
+ loginForm.add(new TextField<String>("username", username));\r
+ loginForm.add(new PasswordTextField("password", password));\r
+ loginForm.add(new FeedbackPanel("feedback"));\r
+ add(loginForm);\r
+ }\r
+ \r
+ protected String getServerName() {\r
+ ServletWebRequest servletWebRequest = (ServletWebRequest) getRequest();\r
+ HttpServletRequest req = servletWebRequest.getHttpServletRequest();\r
+ return req.getServerName();\r
+ }\r
+\r
+ class LoginForm extends Form<Void> {\r
+ private static final long serialVersionUID = 1L;\r
+\r
+ public LoginForm(String id) {\r
+ super(id);\r
+ }\r
+\r
+ @Override\r
+ public void onSubmit() {\r
+ String username = LoginPage.this.username.getObject();\r
+ char [] password = LoginPage.this.password.getObject().toCharArray();\r
+\r
+ User user = GitBlitWebApp.get().authenticate(username, password);\r
+ if (user == null)\r
+ error("Invalid username or password!");\r
+ else\r
+ loginUser(user);\r
+ }\r
+ }\r
+\r
+ private void tryAutomaticLogin() {\r
+ User user = null;\r
+\r
+ // Grab cookie from Browser Session\r
+ Cookie[] cookies = ((WebRequest) getRequestCycle().getRequest()).getCookies();\r
+ if (cookies != null && cookies.length > 0) {\r
+ user = GitBlitWebApp.get().authenticate(cookies);\r
+ }\r
+\r
+ // Login the user\r
+ loginUser(user);\r
+ }\r
+\r
+ private void loginUser(User user) {\r
+ if (user != null) {\r
+ GitBlitWebSession session = GitBlitWebSession.get();\r
+\r
+ // Set Cookie\r
+ WebResponse response = (WebResponse) getRequestCycle().getResponse();\r
+ GitBlitWebApp.get().setCookie(response, user);\r
+ \r
+ // track user object so that we do not have to continue\r
+ // re-authenticating on each request.\r
+ session.setUser(user);\r
+\r
+ // Redirect to original page OR to first available tab\r
+ if (!continueToOriginalDestination()) {\r
+ // Redirect to home page\r
+ setResponsePage(session.getApplication().getHomePage());\r
+ }\r
+ }\r
+ }\r
+}\r
+++ /dev/null
-package com.gitblit.wicket;\r
-\r
-import java.lang.annotation.ElementType;\r
-import java.lang.annotation.Retention;\r
-import java.lang.annotation.RetentionPolicy;\r
-import java.lang.annotation.Target;\r
-\r
-@Retention(RetentionPolicy.RUNTIME)\r
-@Target(ElementType.TYPE)\r
-public @interface SecuredPage {\r
-}\r
--- /dev/null
+package com.gitblit.wicket;\r
+\r
+import com.gitblit.Build;\r
+import com.gitblit.Constants;\r
+\r
+public class User {\r
+ \r
+ private String username;\r
+ private char [] password;\r
+ \r
+ public User(String username, char [] password) {\r
+ this.username = username;\r
+ this.password = password;\r
+ }\r
+ \r
+ public String getCookie() {\r
+ return Build.getSHA1((Constants.NAME + username + new String(password)).getBytes());\r
+ }\r
+ \r
+ public String toString() {\r
+ return username;\r
+ }\r
+}\r