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