From 87d72e9d7b175142f8de9856a0e2e497646eda2f Mon Sep 17 00:00:00 2001 From: James Moger Date: Thu, 29 Nov 2012 17:11:58 -0500 Subject: Tweak css of short commit id in log and history views --- src/com/gitblit/wicket/panels/HistoryPanel.html | 2 +- src/com/gitblit/wicket/panels/HistoryPanel.java | 2 +- src/com/gitblit/wicket/panels/LogPanel.html | 2 +- src/com/gitblit/wicket/panels/LogPanel.java | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/com/gitblit/wicket/panels/HistoryPanel.html b/src/com/gitblit/wicket/panels/HistoryPanel.html index fed08076..811eeed1 100644 --- a/src/com/gitblit/wicket/panels/HistoryPanel.html +++ b/src/com/gitblit/wicket/panels/HistoryPanel.html @@ -20,7 +20,7 @@ [commit author]
[commit short message]
[commit refs]
- [hash label][hash link] + [hash label][hash link] [history links] diff --git a/src/com/gitblit/wicket/panels/HistoryPanel.java b/src/com/gitblit/wicket/panels/HistoryPanel.java index 152bbae6..0f586031 100644 --- a/src/com/gitblit/wicket/panels/HistoryPanel.java +++ b/src/com/gitblit/wicket/panels/HistoryPanel.java @@ -171,7 +171,7 @@ public class HistoryPanel extends BasePanel { LinkPanel commitHash = new LinkPanel("hashLink", null, entry.getName().substring(0, hashLen), TreePage.class, WicketUtils.newObjectParameter( repositoryName, entry.getName())); - WicketUtils.setCssClass(commitHash, "sha1"); + WicketUtils.setCssClass(commitHash, "shortsha1"); WicketUtils.setHtmlTooltip(commitHash, entry.getName()); item.add(commitHash); diff --git a/src/com/gitblit/wicket/panels/LogPanel.html b/src/com/gitblit/wicket/panels/LogPanel.html index d0770a35..2b2605ac 100644 --- a/src/com/gitblit/wicket/panels/LogPanel.html +++ b/src/com/gitblit/wicket/panels/LogPanel.html @@ -16,7 +16,7 @@ [commit author]
[commit short message]
[commit refs]
- [hash link] + [hash link] | diff --git a/src/com/gitblit/wicket/panels/LogPanel.java b/src/com/gitblit/wicket/panels/LogPanel.java index 0686dee6..05397642 100644 --- a/src/com/gitblit/wicket/panels/LogPanel.java +++ b/src/com/gitblit/wicket/panels/LogPanel.java @@ -131,7 +131,7 @@ public class LogPanel extends BasePanel { LinkPanel commitHash = new LinkPanel("hashLink", null, entry.getName().substring(0, hashLen), CommitPage.class, WicketUtils.newObjectParameter( repositoryName, entry.getName())); - WicketUtils.setCssClass(commitHash, "sha1"); + WicketUtils.setCssClass(commitHash, "shortsha1"); WicketUtils.setHtmlTooltip(commitHash, entry.getName()); item.add(commitHash); -- cgit v1.2.3 From 86a9855288ef73380a5de613a45052bb7cda7a0a Mon Sep 17 00:00:00 2001 From: James Moger Date: Thu, 29 Nov 2012 17:24:37 -0500 Subject: Moved cookie and certificate authentication to http request authentication method --- src/com/gitblit/GitBlit.java | 21 ++++++++++++++++----- src/com/gitblit/wicket/pages/BasePage.java | 13 ++----------- 2 files changed, 18 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/com/gitblit/GitBlit.java b/src/com/gitblit/GitBlit.java index c05a9248..c8deee12 100644 --- a/src/com/gitblit/GitBlit.java +++ b/src/com/gitblit/GitBlit.java @@ -537,7 +537,7 @@ public class GitBlit implements ServletContextListener { * @param cookies * @return a user object or null */ - public UserModel authenticate(Cookie[] cookies) { + protected UserModel authenticate(Cookie[] cookies) { if (userService == null) { return null; } @@ -555,22 +555,33 @@ public class GitBlit implements ServletContextListener { } /** - * Authenticate a user based on HTTP request paramters. - * This method is inteded to be used as fallback when other - * means of authentication are failing (username / password or cookies). + * Authenticate a user based on HTTP request parameters. + * + * Authentication by X509Certificate is tried first and then by cookie. + * * @param httpRequest * @return a user object or null */ public UserModel authenticate(HttpServletRequest httpRequest) { + // try to authenticate by certificate boolean checkValidity = settings.getBoolean(Keys.git.enforceCertificateValidity, true); String [] oids = getStrings(Keys.git.certificateUsernameOIDs).toArray(new String[0]); UserModel model = HttpUtils.getUserModelFromCertificate(httpRequest, checkValidity, oids); if (model != null) { - UserModel user = GitBlit.self().getUserModel(model.username); + // grab real user model and preserve certificate serial number + UserModel user = getUserModel(model.username); logger.info(MessageFormat.format("{0} authenticated by client certificate from {1}", user.username, httpRequest.getRemoteAddr())); return user; } + + // try to authenticate by cookie + Cookie[] cookies = httpRequest.getCookies(); + if (allowCookieAuthentication() && cookies != null && cookies.length > 0) { + // Grab cookie from Browser Session + UserModel user = authenticate(cookies); + return user; + } return null; } diff --git a/src/com/gitblit/wicket/pages/BasePage.java b/src/com/gitblit/wicket/pages/BasePage.java index 05640ad0..d04271db 100644 --- a/src/com/gitblit/wicket/pages/BasePage.java +++ b/src/com/gitblit/wicket/pages/BasePage.java @@ -29,7 +29,6 @@ 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; @@ -132,16 +131,8 @@ public abstract class BasePage extends WebPage { private void login() { // try to authenticate by servlet request - UserModel user = GitBlit.self().authenticate(((WebRequest) getRequestCycle().getRequest()).getHttpServletRequest()); - - if (user == null) { - // try to authenticate by cookie - Cookie[] cookies = ((WebRequest) getRequestCycle().getRequest()).getCookies(); - if (GitBlit.self().allowCookieAuthentication() && cookies != null && cookies.length > 0) { - // Grab cookie from Browser Session - user = GitBlit.self().authenticate(cookies); - } - } + HttpServletRequest httpRequest = ((WebRequest) getRequestCycle().getRequest()).getHttpServletRequest(); + UserModel user = GitBlit.self().authenticate(httpRequest); // Login the user if (user != null) { -- cgit v1.2.3 From 6e991161d6d4db5aeda66c2d99d469d5069180bc Mon Sep 17 00:00:00 2001 From: James Moger Date: Thu, 29 Nov 2012 17:25:35 -0500 Subject: View Log button for GCA --- build.xml | 1 + resources/script_16x16.png | Bin 0 -> 626 bytes src/com/gitblit/authority/GitblitAuthority.java | 20 ++++++++++++++++++++ 3 files changed, 21 insertions(+) create mode 100644 resources/script_16x16.png (limited to 'src') diff --git a/build.xml b/build.xml index 59d79b5a..080c91b6 100644 --- a/build.xml +++ b/build.xml @@ -767,6 +767,7 @@ + diff --git a/resources/script_16x16.png b/resources/script_16x16.png new file mode 100644 index 00000000..ec93a22f Binary files /dev/null and b/resources/script_16x16.png differ diff --git a/src/com/gitblit/authority/GitblitAuthority.java b/src/com/gitblit/authority/GitblitAuthority.java index 5ee6af59..ed942e58 100644 --- a/src/com/gitblit/authority/GitblitAuthority.java +++ b/src/com/gitblit/authority/GitblitAuthority.java @@ -67,6 +67,7 @@ import javax.swing.JPasswordField; import javax.swing.JScrollPane; import javax.swing.JSplitPane; import javax.swing.JTable; +import javax.swing.JTextArea; import javax.swing.JTextField; import javax.swing.RowFilter; import javax.swing.SwingConstants; @@ -92,6 +93,7 @@ import com.gitblit.client.HeaderPanel; import com.gitblit.client.Translation; import com.gitblit.models.UserModel; import com.gitblit.utils.ArrayUtils; +import com.gitblit.utils.FileUtils; import com.gitblit.utils.StringUtils; import com.gitblit.utils.TimeUtils; import com.gitblit.utils.X509Utils; @@ -681,6 +683,23 @@ public class GitblitAuthority extends JFrame implements X509Log { } }); + JButton logButton = new JButton(new ImageIcon(getClass().getResource("/script_16x16.png"))); + logButton.setFocusable(false); + logButton.setToolTipText(Translation.get("gb.log")); + logButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + File log = new File(folder, X509Utils.CERTS + File.separator + "log.txt"); + if (log.exists()) { + String content = FileUtils.readContent(log, "\n"); + JTextArea textarea = new JTextArea(content); + JScrollPane scrollPane = new JScrollPane(textarea); + scrollPane.setPreferredSize(new Dimension(700, 400)); + JOptionPane.showMessageDialog(GitblitAuthority.this, scrollPane, log.getAbsolutePath(), JOptionPane.INFORMATION_MESSAGE); + } + } + }); + final JTextField filterTextfield = new JTextField(15); filterTextfield.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { @@ -697,6 +716,7 @@ public class GitblitAuthority extends JFrame implements X509Log { buttonControls.add(certificateDefaultsButton); buttonControls.add(newSSLCertificate); buttonControls.add(emailBundle); + buttonControls.add(logButton); JPanel userControls = new JPanel(new FlowLayout(FlowLayout.RIGHT, Utils.MARGIN, Utils.MARGIN)); userControls.add(new JLabel(Translation.get("gb.filter"))); -- cgit v1.2.3 From 8fef1f8128b35e7378b8af1d9d76a731a74851c5 Mon Sep 17 00:00:00 2001 From: James Moger Date: Thu, 29 Nov 2012 18:21:30 -0500 Subject: Track the authentication type in the session --- src/com/gitblit/Constants.java | 10 +++++++++- src/com/gitblit/GitBlit.java | 10 +++++++++- src/com/gitblit/wicket/GitBlitWebSession.java | 4 ++++ 3 files changed, 22 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/com/gitblit/Constants.java b/src/com/gitblit/Constants.java index cd6b0709..4669c4c9 100644 --- a/src/com/gitblit/Constants.java +++ b/src/com/gitblit/Constants.java @@ -397,7 +397,15 @@ public class Constants { return ordinal() > s.ordinal(); } } - + + public static enum AuthenticationType { + CREDENTIALS, COOKIE, CERTIFICATE; + + public boolean isStandard() { + return ordinal() <= COOKIE.ordinal(); + } + } + @Documented @Retention(RetentionPolicy.RUNTIME) public @interface Unused { diff --git a/src/com/gitblit/GitBlit.java b/src/com/gitblit/GitBlit.java index c8deee12..6a3f98b6 100644 --- a/src/com/gitblit/GitBlit.java +++ b/src/com/gitblit/GitBlit.java @@ -75,6 +75,7 @@ import org.slf4j.LoggerFactory; import com.gitblit.Constants.AccessPermission; import com.gitblit.Constants.AccessRestrictionType; +import com.gitblit.Constants.AuthenticationType; import com.gitblit.Constants.AuthorizationControl; import com.gitblit.Constants.FederationRequest; import com.gitblit.Constants.FederationStrategy; @@ -107,6 +108,7 @@ import com.gitblit.utils.MetricUtils; import com.gitblit.utils.ObjectCache; import com.gitblit.utils.StringUtils; import com.gitblit.utils.TimeUtils; +import com.gitblit.wicket.GitBlitWebSession; import com.gitblit.wicket.WicketUtils; /** @@ -569,6 +571,8 @@ public class GitBlit implements ServletContextListener { UserModel model = HttpUtils.getUserModelFromCertificate(httpRequest, checkValidity, oids); if (model != null) { // grab real user model and preserve certificate serial number + GitBlitWebSession session = GitBlitWebSession.get(); + session.authenticationType = AuthenticationType.CERTIFICATE; UserModel user = getUserModel(model.username); logger.info(MessageFormat.format("{0} authenticated by client certificate from {1}", user.username, httpRequest.getRemoteAddr())); @@ -580,7 +584,11 @@ public class GitBlit implements ServletContextListener { if (allowCookieAuthentication() && cookies != null && cookies.length > 0) { // Grab cookie from Browser Session UserModel user = authenticate(cookies); - return user; + if (user != null) { + GitBlitWebSession session = GitBlitWebSession.get(); + session.authenticationType = AuthenticationType.COOKIE; + return user; + } } return null; } diff --git a/src/com/gitblit/wicket/GitBlitWebSession.java b/src/com/gitblit/wicket/GitBlitWebSession.java index 015d97ad..5195a1fd 100644 --- a/src/com/gitblit/wicket/GitBlitWebSession.java +++ b/src/com/gitblit/wicket/GitBlitWebSession.java @@ -29,6 +29,7 @@ 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 { @@ -45,9 +46,12 @@ public final class GitBlitWebSession extends WebSession { private AtomicBoolean isForking; + public AuthenticationType authenticationType; + public GitBlitWebSession(Request request) { super(request); isForking = new AtomicBoolean(); + authenticationType = AuthenticationType.CREDENTIALS; } public void invalidate() { -- cgit v1.2.3 From 18edd81951a034a2bda9459ff1ef2dcd686eb39b Mon Sep 17 00:00:00 2001 From: James Moger Date: Thu, 29 Nov 2012 18:45:55 -0500 Subject: Hide some user links based on authentication type --- src/com/gitblit/wicket/pages/BasePage.java | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/com/gitblit/wicket/pages/BasePage.java b/src/com/gitblit/wicket/pages/BasePage.java index d04271db..5721adf7 100644 --- a/src/com/gitblit/wicket/pages/BasePage.java +++ b/src/com/gitblit/wicket/pages/BasePage.java @@ -422,14 +422,19 @@ public abstract class BasePage extends WebPage { 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(); + boolean standardLogin = session.authenticationType.isStandard(); + // username, logout, and change password - add(new Label("username", GitBlitWebSession.get().getUser().getDisplayName() + ":")); + add(new Label("username", user.getDisplayName() + ":")); add(new LinkPanel("loginLink", null, markupProvider.getString("gb.logout"), - LogoutPage.class)); - boolean editCredentials = GitBlit.self().supportsCredentialChanges(); + LogoutPage.class).setVisible(standardLogin)); + // quick and dirty hack for showing a separator - add(new Label("separator", "|").setVisible(editCredentials)); + add(new Label("separator", "|").setVisible(standardLogin && editCredentials)); add(new BookmarkablePageLink("changePasswordLink", ChangePasswordPage.class).setVisible(editCredentials)); } else { -- cgit v1.2.3 From 5f3966fed628b25ffb73cb8750ba636fa487037d Mon Sep 17 00:00:00 2001 From: James Moger Date: Thu, 29 Nov 2012 18:46:41 -0500 Subject: Improve logging of certificate authentication --- src/com/gitblit/GitBlit.java | 14 +++++++----- src/com/gitblit/utils/HttpUtils.java | 42 +++++++++++++----------------------- src/com/gitblit/utils/X509Utils.java | 39 +++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/com/gitblit/GitBlit.java b/src/com/gitblit/GitBlit.java index 6a3f98b6..319f4436 100644 --- a/src/com/gitblit/GitBlit.java +++ b/src/com/gitblit/GitBlit.java @@ -108,6 +108,7 @@ import com.gitblit.utils.MetricUtils; import com.gitblit.utils.ObjectCache; import com.gitblit.utils.StringUtils; import com.gitblit.utils.TimeUtils; +import com.gitblit.utils.X509Utils.X509Metadata; import com.gitblit.wicket.GitBlitWebSession; import com.gitblit.wicket.WicketUtils; @@ -571,12 +572,15 @@ public class GitBlit implements ServletContextListener { UserModel model = HttpUtils.getUserModelFromCertificate(httpRequest, checkValidity, oids); if (model != null) { // grab real user model and preserve certificate serial number - GitBlitWebSession session = GitBlitWebSession.get(); - session.authenticationType = AuthenticationType.CERTIFICATE; UserModel user = getUserModel(model.username); - logger.info(MessageFormat.format("{0} authenticated by client certificate from {1}", - user.username, httpRequest.getRemoteAddr())); - return user; + if (user != null) { + GitBlitWebSession session = GitBlitWebSession.get(); + session.authenticationType = AuthenticationType.CERTIFICATE; + X509Metadata metadata = HttpUtils.getCertificateMetadata(httpRequest); + logger.info(MessageFormat.format("{0} authenticated by client certificate {1} from {2}", + user.username, metadata.serialNumber, httpRequest.getRemoteAddr())); + return user; + } } // try to authenticate by cookie diff --git a/src/com/gitblit/utils/HttpUtils.java b/src/com/gitblit/utils/HttpUtils.java index 68a35066..b40088c8 100644 --- a/src/com/gitblit/utils/HttpUtils.java +++ b/src/com/gitblit/utils/HttpUtils.java @@ -20,14 +20,13 @@ import java.security.cert.CertificateNotYetValidException; import java.security.cert.X509Certificate; import java.text.MessageFormat; import java.util.Date; -import java.util.HashMap; -import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.slf4j.LoggerFactory; import com.gitblit.models.UserModel; +import com.gitblit.utils.X509Utils.X509Metadata; /** * Collection of utility methods for http requests. @@ -145,21 +144,11 @@ public class HttpUtils { * @return */ public static UserModel getUserModelFromCertificate(X509Certificate cert, String... usernameOIDs) { - UserModel user = new UserModel(null); - user.isAuthenticated = false; + X509Metadata metadata = X509Utils.getMetadata(cert); - // manually split DN into OID components - // this is instead of parsing with LdapName which: - // (1) I don't trust the order of values - // (2) it filters out values like EMAILADDRESS - String dn = cert.getSubjectDN().getName(); - Map oids = new HashMap(); - for (String kvp : dn.split(",")) { - String [] val = kvp.trim().split("="); - String oid = val[0].toUpperCase().trim(); - String data = val[1].trim(); - oids.put(oid, data); - } + UserModel user = new UserModel(metadata.commonName); + user.emailAddress = metadata.emailAddress; + user.isAuthenticated = false; if (usernameOIDs == null || usernameOIDs.length == 0) { // use default usename<->CN mapping @@ -169,24 +158,23 @@ public class HttpUtils { // determine username from OID fingerprint StringBuilder an = new StringBuilder(); for (String oid : usernameOIDs) { - String val = getOIDValue(oid.toUpperCase(), oids); + String val = metadata.getOID(oid.toUpperCase(), null); if (val != null) { an.append(val).append(' '); } } - user.username = an.toString().trim(); - - // extract email address, if available - user.emailAddress = getOIDValue("E", oids); - if (user.emailAddress == null) { - user.emailAddress = getOIDValue("EMAILADDRESS", oids); - } + user.username = an.toString().trim(); return user; } - private static String getOIDValue(String oid, Map oids) { - if (oids.containsKey(oid)) { - return oids.get(oid); + public static X509Metadata getCertificateMetadata(HttpServletRequest httpRequest) { + if (httpRequest.getAttribute("javax.servlet.request.X509Certificate") != null) { + X509Certificate[] certChain = (X509Certificate[]) httpRequest + .getAttribute("javax.servlet.request.X509Certificate"); + if (certChain != null) { + X509Certificate cert = certChain[0]; + return X509Utils.getMetadata(cert); + } } return null; } diff --git a/src/com/gitblit/utils/X509Utils.java b/src/com/gitblit/utils/X509Utils.java index 24afb8d9..1d144897 100644 --- a/src/com/gitblit/utils/X509Utils.java +++ b/src/com/gitblit/utils/X509Utils.java @@ -183,6 +183,9 @@ public class X509Utils { // displayname of user for README in bundle public String userDisplayname; + // serialnumber of generated or read certificate + public String serialNumber; + public X509Metadata(String cn, String pwd) { if (StringUtils.isEmpty(cn)) { throw new RuntimeException("Common name required!"); @@ -562,6 +565,10 @@ public class X509Utils { saveKeyStore(targetStoreFile, serverStore, sslMetadata.password); x509log.log(MessageFormat.format("New SSL certificate {0,number,0} [{1}]", cert.getSerialNumber(), cert.getSubjectDN().getName())); + + // update serial number in metadata object + sslMetadata.serialNumber = cert.getSerialNumber().toString(); + return cert; } catch (Throwable t) { throw new RuntimeException("Failed to generate SSL certificate!", t); @@ -623,6 +630,9 @@ public class X509Utils { x509log.log(MessageFormat.format("New CA certificate {0,number,0} [{1}]", cert.getSerialNumber(), cert.getIssuerDN().getName())); + // update serial number in metadata object + caMetadata.serialNumber = cert.getSerialNumber().toString(); + return cert; } catch (Throwable t) { throw new RuntimeException("Failed to generate Gitblit CA certificate!", t); @@ -852,6 +862,9 @@ public class X509Utils { // save certificate after successfully creating the key stores saveCertificate(userCert, certFile); + // update serial number in metadata object + clientMetadata.serialNumber = userCert.getSerialNumber().toString(); + return userCert; } catch (Throwable t) { throw new RuntimeException("Failed to generate client certificate!", t); @@ -1065,4 +1078,30 @@ public class X509Utils { } return false; } + + public static X509Metadata getMetadata(X509Certificate cert) { + // manually split DN into OID components + // this is instead of parsing with LdapName which: + // (1) I don't trust the order of values + // (2) it filters out values like EMAILADDRESS + String dn = cert.getSubjectDN().getName(); + Map oids = new HashMap(); + for (String kvp : dn.split(",")) { + String [] val = kvp.trim().split("="); + String oid = val[0].toUpperCase().trim(); + String data = val[1].trim(); + oids.put(oid, data); + } + + X509Metadata metadata = new X509Metadata(oids.get("CN"), "whocares"); + metadata.oids.putAll(oids); + metadata.serialNumber = cert.getSerialNumber().toString(); + metadata.notAfter = cert.getNotAfter(); + metadata.notBefore = cert.getNotBefore(); + metadata.emailAddress = metadata.getOID("E", null); + if (metadata.emailAddress == null) { + metadata.emailAddress = metadata.getOID("EMAILADDRESS", null); + } + return metadata; + } } -- cgit v1.2.3 From e5c7795dc9185272365ff340698c7d2f1e6f11ab Mon Sep 17 00:00:00 2001 From: James Moger Date: Thu, 29 Nov 2012 19:11:24 -0500 Subject: Skip re-authentication if we have a valid session --- src/com/gitblit/GitBlit.java | 2 ++ src/com/gitblit/wicket/pages/BasePage.java | 8 ++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/com/gitblit/GitBlit.java b/src/com/gitblit/GitBlit.java index 319f4436..870e22fb 100644 --- a/src/com/gitblit/GitBlit.java +++ b/src/com/gitblit/GitBlit.java @@ -591,6 +591,8 @@ public class GitBlit implements ServletContextListener { if (user != null) { GitBlitWebSession session = GitBlitWebSession.get(); session.authenticationType = AuthenticationType.COOKIE; + logger.info(MessageFormat.format("{0} authenticated by cookie from {1}", + user.username, httpRequest.getRemoteAddr())); return user; } } diff --git a/src/com/gitblit/wicket/pages/BasePage.java b/src/com/gitblit/wicket/pages/BasePage.java index 5721adf7..d1ee2710 100644 --- a/src/com/gitblit/wicket/pages/BasePage.java +++ b/src/com/gitblit/wicket/pages/BasePage.java @@ -130,14 +130,18 @@ public abstract class BasePage extends WebPage { } private void login() { + GitBlitWebSession session = GitBlitWebSession.get(); + if (session.isLoggedIn() && !session.isSessionInvalidated()) { + // already have a session + return; + } + // 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); -- cgit v1.2.3 From d7f4a1baf51f3cb869518d133a882c99dddf021b Mon Sep 17 00:00:00 2001 From: James Moger Date: Fri, 30 Nov 2012 16:15:14 -0500 Subject: Fixed regression on certificate authentication of servlets --- src/com/gitblit/GitBlit.java | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/com/gitblit/GitBlit.java b/src/com/gitblit/GitBlit.java index 870e22fb..69135c49 100644 --- a/src/com/gitblit/GitBlit.java +++ b/src/com/gitblit/GitBlit.java @@ -58,6 +58,7 @@ import javax.servlet.ServletContextListener; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; +import org.apache.wicket.RequestCycle; import org.apache.wicket.protocol.http.WebResponse; import org.apache.wicket.resource.ContextRelativeResource; import org.apache.wicket.util.resource.ResourceStreamNotFoundException; @@ -574,8 +575,12 @@ public class GitBlit implements ServletContextListener { // grab real user model and preserve certificate serial number UserModel user = getUserModel(model.username); if (user != null) { - GitBlitWebSession session = GitBlitWebSession.get(); - session.authenticationType = AuthenticationType.CERTIFICATE; + RequestCycle requestCycle = RequestCycle.get(); + if (requestCycle != null) { + // flag the Wicket session, if this is a Wicket request + GitBlitWebSession session = GitBlitWebSession.get(); + session.authenticationType = AuthenticationType.CERTIFICATE; + } X509Metadata metadata = HttpUtils.getCertificateMetadata(httpRequest); logger.info(MessageFormat.format("{0} authenticated by client certificate {1} from {2}", user.username, metadata.serialNumber, httpRequest.getRemoteAddr())); @@ -589,8 +594,12 @@ public class GitBlit implements ServletContextListener { // Grab cookie from Browser Session UserModel user = authenticate(cookies); if (user != null) { - GitBlitWebSession session = GitBlitWebSession.get(); - session.authenticationType = AuthenticationType.COOKIE; + RequestCycle requestCycle = RequestCycle.get(); + if (requestCycle != null) { + // flag the Wicket session, if this is a Wicket request + GitBlitWebSession session = GitBlitWebSession.get(); + session.authenticationType = AuthenticationType.COOKIE; + } logger.info(MessageFormat.format("{0} authenticated by cookie from {1}", user.username, httpRequest.getRemoteAddr())); return user; -- cgit v1.2.3 From 1687ae45c088789287b9d6ca77289e9b1ec4c68a Mon Sep 17 00:00:00 2001 From: James Moger Date: Fri, 30 Nov 2012 16:17:04 -0500 Subject: Cranked up signing algorithm from SHA1 to SHA512. This makes Opera P12 Import happy. --- src/com/gitblit/utils/X509Utils.java | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/com/gitblit/utils/X509Utils.java b/src/com/gitblit/utils/X509Utils.java index 1d144897..7a402dac 100644 --- a/src/com/gitblit/utils/X509Utils.java +++ b/src/com/gitblit/utils/X509Utils.java @@ -111,6 +111,12 @@ public class X509Utils { private static final String BC = org.bouncycastle.jce.provider.BouncyCastleProvider.PROVIDER_NAME; + private static final int KEY_LENGTH = 2048; + + private static final String KEY_ALGORITHM = "RSA"; + + private static final String SIGNING_ALGORITHM = "SHA512withRSA"; + public static final boolean unlimitedStrength; private static final Logger logger = LoggerFactory.getLogger(X509Utils.class); @@ -475,8 +481,8 @@ public class X509Utils { * @throws Exception */ private static KeyPair newKeyPair() throws Exception { - KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", BC); - kpGen.initialize(2048, new SecureRandom()); + KeyPairGenerator kpGen = KeyPairGenerator.getInstance(KEY_ALGORITHM, BC); + kpGen.initialize(KEY_LENGTH, new SecureRandom()); return kpGen.generateKeyPair(); } @@ -550,7 +556,7 @@ public class X509Utils { certBuilder.addExtension(X509Extension.basicConstraints, false, new BasicConstraints(false)); certBuilder.addExtension(X509Extension.authorityKeyIdentifier, false, extUtils.createAuthorityKeyIdentifier(caCert.getPublicKey())); - ContentSigner caSigner = new JcaContentSignerBuilder("SHA256WithRSAEncryption") + ContentSigner caSigner = new JcaContentSignerBuilder(SIGNING_ALGORITHM) .setProvider(BC).build(caPrivateKey); X509Certificate cert = new JcaX509CertificateConverter().setProvider(BC) .getCertificate(certBuilder.build(caSigner)); @@ -589,7 +595,7 @@ public class X509Utils { try { KeyPair caPair = newKeyPair(); - ContentSigner caSigner = new JcaContentSignerBuilder("SHA1WithRSA").setProvider(BC).build(caPair.getPrivate()); + ContentSigner caSigner = new JcaContentSignerBuilder(SIGNING_ALGORITHM).setProvider(BC).build(caPair.getPrivate()); // clone metadata X509Metadata caMetadata = metadata.clone(CA_CN, metadata.password); @@ -659,7 +665,7 @@ public class X509Utils { X509v2CRLBuilder crlBuilder = new X509v2CRLBuilder(issuerDN, new Date()); // build and sign CRL with CA private key - ContentSigner signer = new JcaContentSignerBuilder("SHA1WithRSA").setProvider(BC).build(caPrivateKey); + ContentSigner signer = new JcaContentSignerBuilder(SIGNING_ALGORITHM).setProvider(BC).build(caPrivateKey); X509CRLHolder crl = crlBuilder.build(signer); File tmpFile = new File(caRevocationList.getParentFile(), Long.toHexString(System.currentTimeMillis()) + ".tmp"); @@ -809,7 +815,7 @@ public class X509Utils { certBuilder.addExtension(X509Extension.subjectAlternativeName, false, subjectAltName); } - ContentSigner signer = new JcaContentSignerBuilder("SHA1WithRSA").setProvider(BC).build(caPrivateKey); + ContentSigner signer = new JcaContentSignerBuilder(SIGNING_ALGORITHM).setProvider(BC).build(caPrivateKey); X509Certificate userCert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certBuilder.build(signer)); PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)pair.getPrivate(); -- cgit v1.2.3 From 99d00579ec14079cba2dff7b48a3a4555be9017f Mon Sep 17 00:00:00 2001 From: James Moger Date: Fri, 30 Nov 2012 16:18:04 -0500 Subject: Include user's public cert and ca public cert, individually, in bundle --- src/com/gitblit/utils/X509Utils.java | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src') diff --git a/src/com/gitblit/utils/X509Utils.java b/src/com/gitblit/utils/X509Utils.java index 7a402dac..cfad9ec0 100644 --- a/src/com/gitblit/utils/X509Utils.java +++ b/src/com/gitblit/utils/X509Utils.java @@ -759,6 +759,17 @@ public class X509Utils { zos.write(FileUtils.readContent(pemFile)); zos.closeEntry(); } + + // include user's public certificate + zos.putNextEntry(new ZipEntry(clientMetadata.commonName + ".cer")); + zos.write(cert.getEncoded()); + zos.closeEntry(); + + // include CA public certificate + zos.putNextEntry(new ZipEntry("ca.cer")); + zos.write(caCert.getEncoded()); + zos.closeEntry(); + if (readme != null) { zos.putNextEntry(new ZipEntry("README.TXT")); zos.write(readme.getBytes("UTF-8")); -- cgit v1.2.3 From e377dce8818ecd55bb599a8532376cf55e56381a Mon Sep 17 00:00:00 2001 From: James Moger Date: Fri, 30 Nov 2012 16:20:24 -0500 Subject: Fixed regression on expiration date of CA and SSL certs --- src/com/gitblit/authority/GitblitAuthority.java | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/com/gitblit/authority/GitblitAuthority.java b/src/com/gitblit/authority/GitblitAuthority.java index ed942e58..d97a8e39 100644 --- a/src/com/gitblit/authority/GitblitAuthority.java +++ b/src/com/gitblit/authority/GitblitAuthority.java @@ -345,6 +345,7 @@ public class GitblitAuthority extends JFrame implements X509Log { X509Metadata metadata = new X509Metadata("localhost", caKeystorePassword); setMetadataDefaults(metadata); + metadata.notAfter = new Date(System.currentTimeMillis() + 10*TimeUtils.ONEYEAR); X509Utils.prepareX509Infrastructure(metadata, folder, this); return true; } -- cgit v1.2.3 From 9e1aa2eab5a72be52ebee633557a5aafc8132eb6 Mon Sep 17 00:00:00 2001 From: James Moger Date: Fri, 30 Nov 2012 16:26:38 -0500 Subject: Added Commons-Compress and XZ for Java (issue-174) --- .classpath | 2 ++ NOTICE | 18 +++++++++++++++++- docs/04_design.mkd | 2 ++ docs/04_releases.mkd | 3 ++- src/com/gitblit/build/Build.java | 20 ++++++++++++++++++-- 5 files changed, 41 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/.classpath b/.classpath index 772d0e62..55018bfb 100644 --- a/.classpath +++ b/.classpath @@ -34,6 +34,8 @@ + + diff --git a/NOTICE b/NOTICE index 6c2e2531..4daa1202 100644 --- a/NOTICE +++ b/NOTICE @@ -238,4 +238,20 @@ JCalendar GNU LESSER GENERAL PUBLIC LICENSE. (http://www.unboundid.com/products/ldap-sdk/docs/LICENSE-LGPLv2.1.txt) http://www.toedter.com/en/jcalendar - \ No newline at end of file + +--------------------------------------------------------------------------- +Commons-Compress +--------------------------------------------------------------------------- + Commons-Compress, released under the + Apache Software License, Version 2.0. + + http://commons.apache.org/compress + +--------------------------------------------------------------------------- +XZ for Java +--------------------------------------------------------------------------- + XZ for Java, released under the + Public Domain + + http://tukaani.org/xz/java.html + diff --git a/docs/04_design.mkd b/docs/04_design.mkd index c2a73592..622e4a23 100644 --- a/docs/04_design.mkd +++ b/docs/04_design.mkd @@ -43,6 +43,8 @@ The following dependencies are automatically downloaded by Gitblit GO (or alread - [UnboundID](http://www.unboundid.com) (LGPL 2.1) - [Ivy](http://ant.apache.org/ivy) (Apache 2.0) - [JCalendar](http://www.toedter.com/en/jcalendar) (LGPL 2.1) +- [Commons-Compress](http://commons.apache.org/compress) (Apache 2.0) +- [XZ for Java](http://tukaani.org/xz/java.html) (Public Domain) ### Other Build Dependencies - [Fancybox image viewer](http://fancybox.net) (MIT and GPL dual-licensed) diff --git a/docs/04_releases.mkd b/docs/04_releases.mkd index 9704de0f..70a853fc 100644 --- a/docs/04_releases.mkd +++ b/docs/04_releases.mkd @@ -90,7 +90,8 @@ If *realm.ldap.maintainTeams==true* **AND** *realm.ldap.admins* is not empty, th - updated to Lucene 3.6.1 - updated to BouncyCastle 1.47 - added JCalendar 1.3.2 - +- added Commons-Compress 1.4.1 +- added XZ for Java 1.0
### Older Releases diff --git a/src/com/gitblit/build/Build.java b/src/com/gitblit/build/Build.java index 4c5fa195..e8e6b45d 100644 --- a/src/com/gitblit/build/Build.java +++ b/src/com/gitblit/build/Build.java @@ -106,6 +106,8 @@ public class Build { downloadFromApache(MavenObject.UNBOUND_ID, BuildType.RUNTIME); downloadFromApache(MavenObject.IVY, BuildType.RUNTIME); downloadFromApache(MavenObject.JCALENDAR, BuildType.RUNTIME); + downloadFromApache(MavenObject.COMMONS_COMPRESS, BuildType.RUNTIME); + downloadFromApache(MavenObject.XZ, BuildType.RUNTIME); downloadFromEclipse(MavenObject.JGIT, BuildType.RUNTIME); downloadFromEclipse(MavenObject.JGIT_HTTP, BuildType.RUNTIME); @@ -143,7 +145,9 @@ public class Build { downloadFromApache(MavenObject.UNBOUND_ID, BuildType.COMPILETIME); downloadFromApache(MavenObject.IVY, BuildType.COMPILETIME); downloadFromApache(MavenObject.JCALENDAR, BuildType.COMPILETIME); - + downloadFromApache(MavenObject.COMMONS_COMPRESS, BuildType.COMPILETIME); + downloadFromApache(MavenObject.XZ, BuildType.COMPILETIME); + downloadFromEclipse(MavenObject.JGIT, BuildType.COMPILETIME); downloadFromEclipse(MavenObject.JGIT_HTTP, BuildType.COMPILETIME); @@ -779,7 +783,19 @@ public class Build { 127000, 0, 0, "323a672aeacb5f5f4461be3b7f7d9d3e4bda80d4", null, ""); - + + public static final MavenObject COMMONS_COMPRESS = new MavenObject( + "commons-compress", "org/apache/commons", "commons-compress", "1.4.1", + 242000, 265000, 0, + "b02e84a993d88568417536240e970c4b809126fd", + "277d39267403965a7a192474794a29bac6760a25", ""); + + public static final MavenObject XZ = new MavenObject( + "xz", "org/tukaani", "xz", "1.0", + 95000, 120000, 0, + "ecff5cb8b1189514c9d1d8d68eb77ac372e000c9", + "f95e32a5d2dd8da643c4419814415b9704312993", ""); + public final String name; public final String group; public final String artifact; -- cgit v1.2.3 From 59b817a55b04b4bd8c5950a2d97998d3af6d44e3 Mon Sep 17 00:00:00 2001 From: James Moger Date: Fri, 30 Nov 2012 18:05:35 -0500 Subject: Support alternate compressed download formats (issue-174) --- distrib/gitblit.properties | 13 + docs/04_releases.mkd | 3 + src/com/gitblit/DownloadZipServlet.java | 58 +++- src/com/gitblit/utils/CompressionUtils.java | 315 +++++++++++++++++++++ src/com/gitblit/utils/JGitUtils.java | 69 ----- src/com/gitblit/wicket/pages/CommitPage.html | 2 +- src/com/gitblit/wicket/pages/CommitPage.java | 10 +- src/com/gitblit/wicket/pages/TreePage.html | 6 +- src/com/gitblit/wicket/pages/TreePage.java | 23 +- .../wicket/panels/CompressedDownloadsPanel.html | 12 + .../wicket/panels/CompressedDownloadsPanel.java | 77 +++++ tests/com/gitblit/tests/JGitUtilsTest.java | 7 +- 12 files changed, 492 insertions(+), 103 deletions(-) create mode 100644 src/com/gitblit/utils/CompressionUtils.java create mode 100644 src/com/gitblit/wicket/panels/CompressedDownloadsPanel.html create mode 100644 src/com/gitblit/wicket/panels/CompressedDownloadsPanel.java (limited to 'src') diff --git a/distrib/gitblit.properties b/distrib/gitblit.properties index ee050a48..233fdfad 100644 --- a/distrib/gitblit.properties +++ b/distrib/gitblit.properties @@ -482,6 +482,19 @@ web.allowGravatar = true # SINCE 0.5.0 web.allowZipDownloads = true +# If *web.allowZipDownloads=true* the following formats will be displayed for +# download compressed archive links: +# +# zip = standard .zip +# tar = standard tar format (preserves *nix permissions and symlinks) +# gz = gz-compressed tar +# xz = xz-compressed tar +# bzip2 = bzip2-compressed tar +# +# SPACE-DELIMITED +# SINCE 1.2.0 +web.compressedDownloads = zip gz + # Allow optional Lucene integration. Lucene indexing is an opt-in feature. # A repository may specify branches to index with Lucene instead of using Git # commit traversal. There are scenarios where you may want to completely disable diff --git a/docs/04_releases.mkd b/docs/04_releases.mkd index 70a853fc..3f03160a 100644 --- a/docs/04_releases.mkd +++ b/docs/04_releases.mkd @@ -60,6 +60,8 @@ This is extreme and should be considered carefully since it affects every https - Added Gitblit Certificate Authority, an X509 certificate generation tool for Gitblit GO to encourage use of client certificate authentication. - Added setting to control length of shortened commit ids **New:** *web.shortCommitIdLength=8* +- Added alternate compressed download formats: tar.gz, tar.xz, tar.bzip2 (issue 174) + **New:** *web.compressedDownloads = zip gz* - Added simple project pages. A project is a subfolder off the *git.repositoriesFolder*. - Added support for X-Forwarded-Context for Apache subdomain proxy configurations (issue 135) - Delete branch feature (issue 121, Github/ajermakovics) @@ -70,6 +72,7 @@ This is extreme and should be considered carefully since it affects every https #### changes +- Access restricted servlets (e.g. DownloadZip, RSS, etc) will try to authenticate any Gitblit cookie found in the request before resorting to BASIC authentication. - Added *groovy* and *scala* to *web.prettyPrintExtensions* - Added short commit id column to log and history tables (issue 168) - Teams can now specify the *admin*, *create*, and *fork* roles to simplify user administration diff --git a/src/com/gitblit/DownloadZipServlet.java b/src/com/gitblit/DownloadZipServlet.java index 26559344..0feee879 100644 --- a/src/com/gitblit/DownloadZipServlet.java +++ b/src/com/gitblit/DownloadZipServlet.java @@ -29,6 +29,7 @@ import org.eclipse.jgit.revwalk.RevCommit; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.gitblit.utils.CompressionUtils; import com.gitblit.utils.JGitUtils; import com.gitblit.utils.MarkdownUtils; import com.gitblit.utils.StringUtils; @@ -45,6 +46,25 @@ public class DownloadZipServlet extends HttpServlet { private static final long serialVersionUID = 1L; private transient Logger logger = LoggerFactory.getLogger(DownloadZipServlet.class); + + public static enum Format { + zip(".zip"), tar(".tar"), gz(".tar.gz"), xz(".tar.xz"), bzip2(".tar.bzip2"); + + public final String extension; + + Format(String ext) { + this.extension = ext; + } + + public static Format fromName(String name) { + for (Format format : values()) { + if (format.name().equalsIgnoreCase(name)) { + return format; + } + } + return zip; + } + } public DownloadZipServlet() { super(); @@ -57,15 +77,17 @@ public class DownloadZipServlet extends HttpServlet { * @param repository * @param objectId * @param path + * @param format * @return an url */ - public static String asLink(String baseURL, String repository, String objectId, String path) { + public static String asLink(String baseURL, String repository, String objectId, String path, Format format) { if (baseURL.length() > 0 && baseURL.charAt(baseURL.length() - 1) == '/') { baseURL = baseURL.substring(0, baseURL.length() - 1); } return baseURL + Constants.ZIP_PATH + "?r=" + repository + (path == null ? "" : ("&p=" + path)) - + (objectId == null ? "" : ("&h=" + objectId)); + + (objectId == null ? "" : ("&h=" + objectId)) + + (format == null ? "" : ("&format=" + format.name())); } /** @@ -84,16 +106,22 @@ public class DownloadZipServlet extends HttpServlet { response.sendError(HttpServletResponse.SC_FORBIDDEN); return; } - + + Format format = Format.zip; String repository = request.getParameter("r"); String basePath = request.getParameter("p"); String objectId = request.getParameter("h"); - + String f = request.getParameter("format"); + if (!StringUtils.isEmpty(f)) { + format = Format.fromName(f); + } + try { String name = repository; if (name.indexOf('/') > -1) { name = name.substring(name.lastIndexOf('/') + 1); } + name = StringUtils.stripDotGit(name); if (!StringUtils.isEmpty(basePath)) { name += "-" + basePath.replace('/', '_'); @@ -122,15 +150,31 @@ public class DownloadZipServlet extends HttpServlet { String contentType = "application/octet-stream"; response.setContentType(contentType + "; charset=" + response.getCharacterEncoding()); - response.setHeader("Content-Disposition", "attachment; filename=\"" + name + ".zip" - + "\""); + response.setHeader("Content-Disposition", "attachment; filename=\"" + name + format.extension + "\""); response.setDateHeader("Last-Modified", date.getTime()); response.setHeader("Cache-Control", "no-cache"); response.setHeader("Pragma", "no-cache"); response.setDateHeader("Expires", 0); try { - JGitUtils.zip(r, basePath, objectId, response.getOutputStream()); + switch (format) { + case zip: + CompressionUtils.zip(r, basePath, objectId, response.getOutputStream()); + break; + case tar: + CompressionUtils.tar(r, basePath, objectId, response.getOutputStream()); + break; + case gz: + CompressionUtils.gz(r, basePath, objectId, response.getOutputStream()); + break; + case xz: + CompressionUtils.xz(r, basePath, objectId, response.getOutputStream()); + break; + case bzip2: + CompressionUtils.bzip2(r, basePath, objectId, response.getOutputStream()); + break; + } + response.flushBuffer(); } catch (Throwable t) { logger.error("Failed to write attachment to client", t); diff --git a/src/com/gitblit/utils/CompressionUtils.java b/src/com/gitblit/utils/CompressionUtils.java new file mode 100644 index 00000000..7b0d0471 --- /dev/null +++ b/src/com/gitblit/utils/CompressionUtils.java @@ -0,0 +1,315 @@ +/* + * Copyright 2012 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.utils; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +import org.apache.commons.compress.archivers.tar.TarArchiveEntry; +import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream; +import org.apache.commons.compress.compressors.CompressorException; +import org.apache.commons.compress.compressors.CompressorStreamFactory; +import org.apache.commons.compress.utils.IOUtils; +import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.lib.FileMode; +import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.lib.ObjectLoader; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.revwalk.RevBlob; +import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.jgit.revwalk.RevWalk; +import org.eclipse.jgit.treewalk.TreeWalk; +import org.eclipse.jgit.treewalk.filter.PathFilter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Collection of static methods for retrieving information from a repository. + * + * @author James Moger + * + */ +public class CompressionUtils { + + static final Logger LOGGER = LoggerFactory.getLogger(CompressionUtils.class); + + /** + * Log an error message and exception. + * + * @param t + * @param repository + * if repository is not null it MUST be the {0} parameter in the + * pattern. + * @param pattern + * @param objects + */ + private static void error(Throwable t, Repository repository, String pattern, Object... objects) { + List parameters = new ArrayList(); + if (objects != null && objects.length > 0) { + for (Object o : objects) { + parameters.add(o); + } + } + if (repository != null) { + parameters.add(0, repository.getDirectory().getAbsolutePath()); + } + LOGGER.error(MessageFormat.format(pattern, parameters.toArray()), t); + } + + /** + * Zips the contents of the tree at the (optionally) specified revision and + * the (optionally) specified basepath to the supplied outputstream. + * + * @param repository + * @param basePath + * if unspecified, entire repository is assumed. + * @param objectId + * if unspecified, HEAD is assumed. + * @param os + * @return true if repository was successfully zipped to supplied output + * stream + */ + public static boolean zip(Repository repository, String basePath, String objectId, + OutputStream os) { + RevCommit commit = JGitUtils.getCommit(repository, objectId); + if (commit == null) { + return false; + } + boolean success = false; + RevWalk rw = new RevWalk(repository); + TreeWalk tw = new TreeWalk(repository); + try { + tw.addTree(commit.getTree()); + ZipOutputStream zos = new ZipOutputStream(os); + zos.setComment("Generated by Gitblit"); + if (!StringUtils.isEmpty(basePath)) { + PathFilter f = PathFilter.create(basePath); + tw.setFilter(f); + } + tw.setRecursive(true); + while (tw.next()) { + if (tw.getFileMode(0) == FileMode.GITLINK) { + continue; + } + ZipEntry entry = new ZipEntry(tw.getPathString()); + entry.setSize(tw.getObjectReader().getObjectSize(tw.getObjectId(0), + Constants.OBJ_BLOB)); + entry.setComment(commit.getName()); + zos.putNextEntry(entry); + + ObjectId entid = tw.getObjectId(0); + FileMode entmode = tw.getFileMode(0); + RevBlob blob = (RevBlob) rw.lookupAny(entid, entmode.getObjectType()); + rw.parseBody(blob); + + ObjectLoader ldr = repository.open(blob.getId(), Constants.OBJ_BLOB); + byte[] tmp = new byte[4096]; + InputStream in = ldr.openStream(); + int n; + while ((n = in.read(tmp)) > 0) { + zos.write(tmp, 0, n); + } + in.close(); + } + zos.finish(); + success = true; + } catch (IOException e) { + error(e, repository, "{0} failed to zip files from commit {1}", commit.getName()); + } finally { + tw.release(); + rw.dispose(); + } + return success; + } + + /** + * tar the contents of the tree at the (optionally) specified revision and + * the (optionally) specified basepath to the supplied outputstream. + * + * @param repository + * @param basePath + * if unspecified, entire repository is assumed. + * @param objectId + * if unspecified, HEAD is assumed. + * @param os + * @return true if repository was successfully zipped to supplied output + * stream + */ + public static boolean tar(Repository repository, String basePath, String objectId, + OutputStream os) { + return tar(null, repository, basePath, objectId, os); + } + + /** + * tar.gz the contents of the tree at the (optionally) specified revision and + * the (optionally) specified basepath to the supplied outputstream. + * + * @param repository + * @param basePath + * if unspecified, entire repository is assumed. + * @param objectId + * if unspecified, HEAD is assumed. + * @param os + * @return true if repository was successfully zipped to supplied output + * stream + */ + public static boolean gz(Repository repository, String basePath, String objectId, + OutputStream os) { + return tar(CompressorStreamFactory.GZIP, repository, basePath, objectId, os); + } + + /** + * tar.xz the contents of the tree at the (optionally) specified revision and + * the (optionally) specified basepath to the supplied outputstream. + * + * @param repository + * @param basePath + * if unspecified, entire repository is assumed. + * @param objectId + * if unspecified, HEAD is assumed. + * @param os + * @return true if repository was successfully zipped to supplied output + * stream + */ + public static boolean xz(Repository repository, String basePath, String objectId, + OutputStream os) { + return tar(CompressorStreamFactory.XZ, repository, basePath, objectId, os); + } + + /** + * tar.bzip2 the contents of the tree at the (optionally) specified revision and + * the (optionally) specified basepath to the supplied outputstream. + * + * @param repository + * @param basePath + * if unspecified, entire repository is assumed. + * @param objectId + * if unspecified, HEAD is assumed. + * @param os + * @return true if repository was successfully zipped to supplied output + * stream + */ + public static boolean bzip2(Repository repository, String basePath, String objectId, + OutputStream os) { + + return tar(CompressorStreamFactory.BZIP2, repository, basePath, objectId, os); + } + + /** + * Compresses/archives the contents of the tree at the (optionally) + * specified revision and the (optionally) specified basepath to the + * supplied outputstream. + * + * @param algorithm + * compression algorithm for tar (optional) + * @param repository + * @param basePath + * if unspecified, entire repository is assumed. + * @param objectId + * if unspecified, HEAD is assumed. + * @param os + * @return true if repository was successfully zipped to supplied output + * stream + */ + private static boolean tar(String algorithm, Repository repository, String basePath, String objectId, + OutputStream os) { + RevCommit commit = JGitUtils.getCommit(repository, objectId); + if (commit == null) { + return false; + } + + OutputStream cos = os; + if (!StringUtils.isEmpty(algorithm)) { + try { + cos = new CompressorStreamFactory().createCompressorOutputStream(algorithm, os); + } catch (CompressorException e1) { + error(e1, repository, "{0} failed to open {1} stream", algorithm); + } + } + boolean success = false; + RevWalk rw = new RevWalk(repository); + TreeWalk tw = new TreeWalk(repository); + try { + tw.addTree(commit.getTree()); + TarArchiveOutputStream tos = new TarArchiveOutputStream(cos); + tos.setAddPaxHeadersForNonAsciiNames(true); + tos.setLongFileMode(TarArchiveOutputStream.LONGFILE_POSIX); + if (!StringUtils.isEmpty(basePath)) { + PathFilter f = PathFilter.create(basePath); + tw.setFilter(f); + } + tw.setRecursive(true); + while (tw.next()) { + FileMode mode = tw.getFileMode(0); + if (mode == FileMode.GITLINK) { + continue; + } + ObjectId id = tw.getObjectId(0); + + // new entry + TarArchiveEntry entry = new TarArchiveEntry(tw.getPathString()); + entry.setSize(tw.getObjectReader().getObjectSize(id, Constants.OBJ_BLOB)); + + if (FileMode.SYMLINK.equals(mode)) { + // symlink + entry.setMode(mode.getBits()); + + // read the symlink target + ByteArrayOutputStream bs = new ByteArrayOutputStream(); + RevBlob blob = (RevBlob) rw.lookupAny(id, mode.getObjectType()); + rw.parseBody(blob); + ObjectLoader ldr = repository.open(blob.getId(), Constants.OBJ_BLOB); + IOUtils.copy(ldr.openStream(), bs); + entry.setLinkName(bs.toString("UTF-8")); + } else { + // regular file or executable file + entry.setMode(mode.getBits()); + } + entry.setModTime(commit.getAuthorIdent().getWhen()); + + tos.putArchiveEntry(entry); + + if (!FileMode.SYMLINK.equals(mode)) { + // write the blob + RevBlob blob = (RevBlob) rw.lookupAny(id, mode.getObjectType()); + rw.parseBody(blob); + ObjectLoader ldr = repository.open(blob.getId(), Constants.OBJ_BLOB); + IOUtils.copy(ldr.openStream(), tos); + } + + // close entry + tos.closeArchiveEntry(); + } + tos.finish(); + tos.close(); + cos.close(); + success = true; + } catch (IOException e) { + error(e, repository, "{0} failed to {1} stream files from commit {2}", algorithm, commit.getName()); + } finally { + tw.release(); + rw.dispose(); + } + return success; + } +} diff --git a/src/com/gitblit/utils/JGitUtils.java b/src/com/gitblit/utils/JGitUtils.java index bc44f00f..9cfb37fd 100644 --- a/src/com/gitblit/utils/JGitUtils.java +++ b/src/com/gitblit/utils/JGitUtils.java @@ -19,7 +19,6 @@ import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; -import java.io.OutputStream; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Arrays; @@ -30,8 +29,6 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.regex.Pattern; -import java.util.zip.ZipEntry; -import java.util.zip.ZipOutputStream; import org.eclipse.jgit.api.CloneCommand; import org.eclipse.jgit.api.FetchCommand; @@ -1723,70 +1720,4 @@ public class JGitUtils { } return success; } - - /** - * Zips the contents of the tree at the (optionally) specified revision and - * the (optionally) specified basepath to the supplied outputstream. - * - * @param repository - * @param basePath - * if unspecified, entire repository is assumed. - * @param objectId - * if unspecified, HEAD is assumed. - * @param os - * @return true if repository was successfully zipped to supplied output - * stream - */ - public static boolean zip(Repository repository, String basePath, String objectId, - OutputStream os) { - RevCommit commit = getCommit(repository, objectId); - if (commit == null) { - return false; - } - boolean success = false; - RevWalk rw = new RevWalk(repository); - TreeWalk tw = new TreeWalk(repository); - try { - tw.addTree(commit.getTree()); - ZipOutputStream zos = new ZipOutputStream(os); - zos.setComment("Generated by Gitblit"); - if (!StringUtils.isEmpty(basePath)) { - PathFilter f = PathFilter.create(basePath); - tw.setFilter(f); - } - tw.setRecursive(true); - while (tw.next()) { - if (tw.getFileMode(0) == FileMode.GITLINK) { - continue; - } - ZipEntry entry = new ZipEntry(tw.getPathString()); - entry.setSize(tw.getObjectReader().getObjectSize(tw.getObjectId(0), - Constants.OBJ_BLOB)); - entry.setComment(commit.getName()); - zos.putNextEntry(entry); - - ObjectId entid = tw.getObjectId(0); - FileMode entmode = tw.getFileMode(0); - RevBlob blob = (RevBlob) rw.lookupAny(entid, entmode.getObjectType()); - rw.parseBody(blob); - - ObjectLoader ldr = repository.open(blob.getId(), Constants.OBJ_BLOB); - byte[] tmp = new byte[4096]; - InputStream in = ldr.openStream(); - int n; - while ((n = in.read(tmp)) > 0) { - zos.write(tmp, 0, n); - } - in.close(); - } - zos.finish(); - success = true; - } catch (IOException e) { - error(e, repository, "{0} failed to zip files from commit {1}", commit.getName()); - } finally { - tw.release(); - rw.dispose(); - } - return success; - } } diff --git a/src/com/gitblit/wicket/pages/CommitPage.html b/src/com/gitblit/wicket/pages/CommitPage.html index 20e6b607..79a038c9 100644 --- a/src/com/gitblit/wicket/pages/CommitPage.html +++ b/src/com/gitblit/wicket/pages/CommitPage.html @@ -30,7 +30,7 @@ tree [commit tree] - | + | parent diff --git a/src/com/gitblit/wicket/pages/CommitPage.java b/src/com/gitblit/wicket/pages/CommitPage.java index 7bc6b41d..b2a8112b 100644 --- a/src/com/gitblit/wicket/pages/CommitPage.java +++ b/src/com/gitblit/wicket/pages/CommitPage.java @@ -22,7 +22,6 @@ import java.util.List; import org.apache.wicket.PageParameters; 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.repeater.Item; import org.apache.wicket.markup.repeater.data.DataView; import org.apache.wicket.markup.repeater.data.ListDataProvider; @@ -32,16 +31,15 @@ import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.revwalk.RevCommit; import com.gitblit.Constants; -import com.gitblit.DownloadZipServlet; import com.gitblit.GitBlit; -import com.gitblit.Keys; import com.gitblit.models.GitNote; -import com.gitblit.models.SubmoduleModel; import com.gitblit.models.PathModel.PathChangeModel; +import com.gitblit.models.SubmoduleModel; import com.gitblit.utils.JGitUtils; import com.gitblit.wicket.WicketUtils; import com.gitblit.wicket.panels.CommitHeaderPanel; import com.gitblit.wicket.panels.CommitLegendPanel; +import com.gitblit.wicket.panels.CompressedDownloadsPanel; import com.gitblit.wicket.panels.GravatarImage; import com.gitblit.wicket.panels.LinkPanel; import com.gitblit.wicket.panels.RefsPanel; @@ -95,8 +93,8 @@ public class CommitPage extends RepositoryPage { newCommitParameter())); add(new BookmarkablePageLink("treeLink", TreePage.class, newCommitParameter())); final String baseUrl = WicketUtils.getGitblitURL(getRequest()); - add(new ExternalLink("zipLink", DownloadZipServlet.asLink(baseUrl, repositoryName, - objectId, null)).setVisible(GitBlit.getBoolean(Keys.web.allowZipDownloads, true))); + + add(new CompressedDownloadsPanel("compressedLinks", baseUrl, repositoryName, objectId, null)); // Parent Commits ListDataProvider parentsDp = new ListDataProvider(parents); diff --git a/src/com/gitblit/wicket/pages/TreePage.html b/src/com/gitblit/wicket/pages/TreePage.html index 0047ff0d..b7e55ed6 100644 --- a/src/com/gitblit/wicket/pages/TreePage.html +++ b/src/com/gitblit/wicket/pages/TreePage.html @@ -9,7 +9,7 @@ @@ -32,14 +32,14 @@ - | | | + | | | - | | + | | diff --git a/src/com/gitblit/wicket/pages/TreePage.java b/src/com/gitblit/wicket/pages/TreePage.java index 973634b7..345814f4 100644 --- a/src/com/gitblit/wicket/pages/TreePage.java +++ b/src/com/gitblit/wicket/pages/TreePage.java @@ -20,7 +20,6 @@ import java.util.List; import org.apache.wicket.PageParameters; 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.Fragment; import org.apache.wicket.markup.repeater.Item; import org.apache.wicket.markup.repeater.data.DataView; @@ -30,15 +29,13 @@ import org.eclipse.jgit.lib.FileMode; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.revwalk.RevCommit; -import com.gitblit.DownloadZipServlet; -import com.gitblit.GitBlit; -import com.gitblit.Keys; import com.gitblit.models.PathModel; import com.gitblit.models.SubmoduleModel; import com.gitblit.utils.ByteFormat; import com.gitblit.utils.JGitUtils; import com.gitblit.wicket.WicketUtils; import com.gitblit.wicket.panels.CommitHeaderPanel; +import com.gitblit.wicket.panels.CompressedDownloadsPanel; import com.gitblit.wicket.panels.LinkPanel; import com.gitblit.wicket.panels.PathBreadcrumbsPanel; @@ -58,9 +55,8 @@ public class TreePage extends RepositoryPage { WicketUtils.newPathParameter(repositoryName, objectId, path))); add(new BookmarkablePageLink("headLink", TreePage.class, WicketUtils.newPathParameter(repositoryName, Constants.HEAD, path))); - add(new ExternalLink("zipLink", DownloadZipServlet.asLink(getRequest() - .getRelativePathPrefixToContextRoot(), repositoryName, objectId, path)) - .setVisible(GitBlit.getBoolean(Keys.web.allowZipDownloads, true))); + add(new CompressedDownloadsPanel("compressedLinks", getRequest() + .getRelativePathPrefixToContextRoot(), repositoryName, objectId, path)); add(new CommitHeaderPanel("commitHeader", repositoryName, commit)); @@ -114,10 +110,10 @@ public class TreePage extends RepositoryPage { entry.path))); links.add(new BookmarkablePageLink("history", HistoryPage.class, WicketUtils.newPathParameter(repositoryName, entry.commitId, - entry.path))); - links.add(new ExternalLink("zip", DownloadZipServlet.asLink(baseUrl, - repositoryName, objectId, entry.path)).setVisible(GitBlit - .getBoolean(Keys.web.allowZipDownloads, true))); + entry.path))); + links.add(new CompressedDownloadsPanel("compressedLinks", baseUrl, + repositoryName, objectId, entry.path)); + item.add(links); } else if (entry.isSubmodule()) { // submodule @@ -143,9 +139,8 @@ public class TreePage extends RepositoryPage { links.add(new BookmarkablePageLink("history", HistoryPage.class, WicketUtils.newPathParameter(submodulePath, submoduleId, "")).setEnabled(hasSubmodule)); - links.add(new ExternalLink("zip", DownloadZipServlet.asLink(baseUrl, - submodulePath, submoduleId, "")).setVisible(GitBlit - .getBoolean(Keys.web.allowZipDownloads, true)).setEnabled(hasSubmodule)); + links.add(new CompressedDownloadsPanel("compressedLinks", baseUrl, + submodulePath, submoduleId, "").setEnabled(hasSubmodule)); item.add(links); } else { // blob link diff --git a/src/com/gitblit/wicket/panels/CompressedDownloadsPanel.html b/src/com/gitblit/wicket/panels/CompressedDownloadsPanel.html new file mode 100644 index 00000000..7123d0a7 --- /dev/null +++ b/src/com/gitblit/wicket/panels/CompressedDownloadsPanel.html @@ -0,0 +1,12 @@ + + + + + + |ref + + + \ No newline at end of file diff --git a/src/com/gitblit/wicket/panels/CompressedDownloadsPanel.java b/src/com/gitblit/wicket/panels/CompressedDownloadsPanel.java new file mode 100644 index 00000000..b22c7587 --- /dev/null +++ b/src/com/gitblit/wicket/panels/CompressedDownloadsPanel.java @@ -0,0 +1,77 @@ +/* + * Copyright 2012 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.panels; + +import java.util.List; + +import org.apache.wicket.Component; +import org.apache.wicket.markup.html.basic.Label; +import org.apache.wicket.markup.html.panel.Panel; +import org.apache.wicket.markup.repeater.Item; +import org.apache.wicket.markup.repeater.data.DataView; +import org.apache.wicket.markup.repeater.data.ListDataProvider; + +import com.gitblit.DownloadZipServlet; +import com.gitblit.DownloadZipServlet.Format; +import com.gitblit.GitBlit; +import com.gitblit.Keys; + +public class CompressedDownloadsPanel extends Panel { + + private static final long serialVersionUID = 1L; + + public CompressedDownloadsPanel(String id, final String baseUrl, final String repositoryName, final String objectId, final String path) { + super(id); + + List types = GitBlit.getStrings(Keys.web.compressedDownloads); + if (types.isEmpty()) { + types.add(Format.zip.name()); + types.add(Format.gz.name()); + } + + ListDataProvider refsDp = new ListDataProvider(types); + DataView refsView = new DataView("compressedLinks", refsDp) { + private static final long serialVersionUID = 1L; + int counter; + + @Override + protected void onBeforeRender() { + super.onBeforeRender(); + counter = 0; + } + + @Override + public void populateItem(final Item item) { + String compressionType = item.getModelObject(); + Format format = Format.fromName(compressionType); + + String href = DownloadZipServlet.asLink(baseUrl, repositoryName, + objectId, path, format); + Component c = new LinkPanel("compressedLink", null, format.name(), href); + item.add(c); + Label lb = new Label("linkSep", "|"); + lb.setVisible(counter > 0); + lb.setRenderBodyOnly(true); + item.add(lb.setEscapeModelStrings(false)); + item.setRenderBodyOnly(true); + counter++; + } + }; + add(refsView); + + setVisible(GitBlit.getBoolean(Keys.web.allowZipDownloads, true)); + } +} \ No newline at end of file diff --git a/tests/com/gitblit/tests/JGitUtilsTest.java b/tests/com/gitblit/tests/JGitUtilsTest.java index 7e4d6309..ce72a46f 100644 --- a/tests/com/gitblit/tests/JGitUtilsTest.java +++ b/tests/com/gitblit/tests/JGitUtilsTest.java @@ -50,6 +50,7 @@ import com.gitblit.models.GitNote; import com.gitblit.models.PathModel; import com.gitblit.models.PathModel.PathChangeModel; import com.gitblit.models.RefModel; +import com.gitblit.utils.CompressionUtils; import com.gitblit.utils.JGitUtils; import com.gitblit.utils.StringUtils; @@ -446,16 +447,16 @@ public class JGitUtilsTest { @Test public void testZip() throws Exception { - assertFalse(JGitUtils.zip(null, null, null, null)); + assertFalse(CompressionUtils.zip(null, null, null, null)); Repository repository = GitBlitSuite.getHelloworldRepository(); File zipFileA = new File(GitBlitSuite.REPOSITORIES, "helloworld.zip"); FileOutputStream fosA = new FileOutputStream(zipFileA); - boolean successA = JGitUtils.zip(repository, null, Constants.HEAD, fosA); + boolean successA = CompressionUtils.zip(repository, null, Constants.HEAD, fosA); fosA.close(); File zipFileB = new File(GitBlitSuite.REPOSITORIES, "helloworld-java.zip"); FileOutputStream fosB = new FileOutputStream(zipFileB); - boolean successB = JGitUtils.zip(repository, "java.java", Constants.HEAD, fosB); + boolean successB = CompressionUtils.zip(repository, "java.java", Constants.HEAD, fosB); fosB.close(); repository.close(); -- cgit v1.2.3 From 8744a1e9de208117bc6187d9e917b9ed8da83f94 Mon Sep 17 00:00:00 2001 From: Luca Milanesio Date: Sun, 2 Dec 2012 08:50:55 +0000 Subject: FIX: Allow correct search for RefModel using branch name. DisplayName used previously contained ONLY the last part of ref-spec: this would have not worked when looking for objects with full ref-spec. --- src/com/gitblit/utils/JGitUtils.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/com/gitblit/utils/JGitUtils.java b/src/com/gitblit/utils/JGitUtils.java index 9cfb37fd..beaa27da 100644 --- a/src/com/gitblit/utils/JGitUtils.java +++ b/src/com/gitblit/utils/JGitUtils.java @@ -1528,7 +1528,7 @@ public class JGitUtils { try { // search for the branch in local heads for (RefModel ref : JGitUtils.getLocalBranches(repository, false, -1)) { - if (ref.displayName.endsWith(name)) { + if (ref.reference.getName().endsWith(name)) { branch = ref; break; } @@ -1537,7 +1537,7 @@ public class JGitUtils { // search for the branch in remote heads if (branch == null) { for (RefModel ref : JGitUtils.getRemoteBranches(repository, false, -1)) { - if (ref.displayName.endsWith(name)) { + if (ref.reference.getName().endsWith(name)) { branch = ref; break; } -- cgit v1.2.3 From 13f880f5f959e2d4ae2304c9cf9760fc1de32f10 Mon Sep 17 00:00:00 2001 From: Luca Milanesio Date: Sun, 2 Dec 2012 08:52:04 +0000 Subject: FIX: typo in error message key when access to branch is denied. --- src/com/gitblit/wicket/pages/RepositoryPage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/com/gitblit/wicket/pages/RepositoryPage.java b/src/com/gitblit/wicket/pages/RepositoryPage.java index c90e3530..346edc3e 100644 --- a/src/com/gitblit/wicket/pages/RepositoryPage.java +++ b/src/com/gitblit/wicket/pages/RepositoryPage.java @@ -115,7 +115,7 @@ public abstract class RepositoryPage extends BasePage { boolean canAccess = user.hasBranchPermission(repositoryName, branch.reference.getName()); if (!canAccess) { - error(getString("gb.accessDeined"), true); + error(getString("gb.accessDenied"), true); } } } -- cgit v1.2.3 From 9da9764c5073118fc3b46bb360e1071426a9b9f4 Mon Sep 17 00:00:00 2001 From: Luca Milanesio Date: Sun, 2 Dec 2012 08:52:28 +0000 Subject: Branch display filtering according to user access permissions. --- src/com/gitblit/wicket/panels/BranchesPanel.java | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/com/gitblit/wicket/panels/BranchesPanel.java b/src/com/gitblit/wicket/panels/BranchesPanel.java index cfe9f5fe..956e3494 100644 --- a/src/com/gitblit/wicket/panels/BranchesPanel.java +++ b/src/com/gitblit/wicket/panels/BranchesPanel.java @@ -36,8 +36,10 @@ import com.gitblit.GitBlit; import com.gitblit.SyndicationServlet; import com.gitblit.models.RefModel; import com.gitblit.models.RepositoryModel; +import com.gitblit.models.UserModel; import com.gitblit.utils.JGitUtils; import com.gitblit.utils.StringUtils; +import com.gitblit.wicket.GitBlitWebSession; import com.gitblit.wicket.WicketUtils; import com.gitblit.wicket.pages.BranchesPage; import com.gitblit.wicket.pages.CommitPage; @@ -58,9 +60,21 @@ public class BranchesPanel extends BasePanel { // branches List branches = new ArrayList(); - branches.addAll(JGitUtils.getLocalBranches(r, false, maxCount)); + UserModel user = GitBlitWebSession.get().getUser(); + + List localBranches = JGitUtils.getLocalBranches(r, false, maxCount); + for (RefModel refModel : localBranches) { + if (user.hasBranchPermission(model.name, refModel.reference.getName())) { + branches.add(refModel); + } + } if (model.showRemoteBranches) { - branches.addAll(JGitUtils.getRemoteBranches(r, false, maxCount)); + List remoteBranches = JGitUtils.getRemoteBranches(r, false, maxCount); + for (RefModel refModel : remoteBranches) { + if (user.hasBranchPermission(model.name, refModel.reference.getName())) { + branches.add(refModel); + } + } } Collections.sort(branches); Collections.reverse(branches); -- cgit v1.2.3 From 635006f7b005fad8fc9d7844a103b344eeee51f2 Mon Sep 17 00:00:00 2001 From: James Moger Date: Sun, 2 Dec 2012 13:14:58 -0500 Subject: Handle anonymous browsing of branches panel --- src/com/gitblit/wicket/panels/BranchesPanel.java | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/com/gitblit/wicket/panels/BranchesPanel.java b/src/com/gitblit/wicket/panels/BranchesPanel.java index 956e3494..1bdf451d 100644 --- a/src/com/gitblit/wicket/panels/BranchesPanel.java +++ b/src/com/gitblit/wicket/panels/BranchesPanel.java @@ -61,6 +61,9 @@ public class BranchesPanel extends BasePanel { // branches List branches = new ArrayList(); UserModel user = GitBlitWebSession.get().getUser(); + if (user == null) { + user = UserModel.ANONYMOUS; + } List localBranches = JGitUtils.getLocalBranches(r, false, maxCount); for (RefModel refModel : localBranches) { -- cgit v1.2.3 From 8481ab5b01b2b848f05e43af345072921c2219b9 Mon Sep 17 00:00:00 2001 From: James Moger Date: Sun, 2 Dec 2012 13:16:19 -0500 Subject: Do not prematurely reduce branches by maxCount when using branch permissions --- src/com/gitblit/wicket/panels/BranchesPanel.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/com/gitblit/wicket/panels/BranchesPanel.java b/src/com/gitblit/wicket/panels/BranchesPanel.java index 1bdf451d..26fedc1e 100644 --- a/src/com/gitblit/wicket/panels/BranchesPanel.java +++ b/src/com/gitblit/wicket/panels/BranchesPanel.java @@ -65,14 +65,14 @@ public class BranchesPanel extends BasePanel { user = UserModel.ANONYMOUS; } - List localBranches = JGitUtils.getLocalBranches(r, false, maxCount); + List localBranches = JGitUtils.getLocalBranches(r, false, -1); for (RefModel refModel : localBranches) { if (user.hasBranchPermission(model.name, refModel.reference.getName())) { branches.add(refModel); } } if (model.showRemoteBranches) { - List remoteBranches = JGitUtils.getRemoteBranches(r, false, maxCount); + List remoteBranches = JGitUtils.getRemoteBranches(r, false, -1); for (RefModel refModel : remoteBranches) { if (user.hasBranchPermission(model.name, refModel.reference.getName())) { branches.add(refModel); -- cgit v1.2.3