From: James Moger Date: Tue, 24 May 2011 21:17:51 +0000 (-0400) Subject: Delete/Rename repos & user. Edit link. Dropped crypt. Other git urls. X-Git-Tag: v0.5.0~38 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=8a2e9c363346ef5bf48c8eba09cb8afa46fabeeb;p=gitblit.git Delete/Rename repos & user. Edit link. Dropped crypt. Other git urls. --- diff --git a/distrib/gitblit.properties b/distrib/gitblit.properties index d0e63757..b263f327 100644 --- a/distrib/gitblit.properties +++ b/distrib/gitblit.properties @@ -17,8 +17,10 @@ git.exportAll = true # e.g. /libraries/mylibrary.git git.nestedRepositories = true -# The root clone url -git.cloneUrl = https://localhost/git/ +# Show other URLs on the summary page for accessing your git repositories +# Use spaces to separate urls. {0} is the token for the repository name. +# git.otherUrls = ssh://localhost/git/{0} git://localhost/git/{0} +git.otherUrls = # # Authentication Settings @@ -34,7 +36,7 @@ web.authenticateAdminPages = true realm.realmFile = users.properties # How to store passwords. -# Valid values are plain, md5 or crypt (unix style). Default is md5. +# Valid values are plain or md5. Default is md5. realm.passwordStorage = md5 # Minimum valid length for a plain text password. diff --git a/src/com/gitblit/GitBlit.java b/src/com/gitblit/GitBlit.java index 51c3b451..acb90d81 100644 --- a/src/com/gitblit/GitBlit.java +++ b/src/com/gitblit/GitBlit.java @@ -9,14 +9,13 @@ import java.util.List; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; -import javax.servlet.http.Cookie; -import org.apache.wicket.protocol.http.WebResponse; import org.eclipse.jgit.errors.RepositoryNotFoundException; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.StoredConfig; import org.eclipse.jgit.transport.resolver.FileResolver; import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; +import org.eclipse.jgit.util.FileUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -61,8 +60,12 @@ public class GitBlit implements ServletContextListener { return storedSettings.getBoolean(Keys.web.debugMode, false); } - public String getCloneUrl(String repositoryName) { - return storedSettings.getString(Keys.git.cloneUrl, "https://localhost/git/") + repositoryName; + public List getOtherCloneUrls(String repositoryName) { + List cloneUrls = new ArrayList(); + for (String url : storedSettings.getStrings(Keys.git.otherUrls)) { + cloneUrls.add(MessageFormat.format(url, repositoryName)); + } + return cloneUrls; } public void setLoginService(ILoginService loginService) { @@ -76,49 +79,31 @@ public class GitBlit implements ServletContextListener { return loginService.authenticate(username, password); } - public UserModel authenticate(Cookie[] cookies) { - if (loginService == null) { - return null; - } - if (cookies != null && cookies.length > 0) { - for (Cookie cookie : cookies) { - if (cookie.getName().equals(Constants.NAME)) { - String value = cookie.getValue(); - return loginService.authenticate(value.toCharArray()); - } - } - } - return null; - } - - public void setCookie(WebResponse response, UserModel user) { - Cookie userCookie = new Cookie(Constants.NAME, user.getCookie()); - userCookie.setMaxAge(Integer.MAX_VALUE); - userCookie.setPath("/"); - response.addCookie(userCookie); - } - public List getAllUsernames() { - List names = loginService.getAllUsernames(); + List names = new ArrayList(loginService.getAllUsernames()); Collections.sort(names); return names; } + public boolean deleteUser(String username) { + return loginService.deleteUser(username); + } + public UserModel getUserModel(String username) { UserModel user = loginService.getUserModel(username); return user; } - + public List getRepositoryUsers(RepositoryModel repository) { return loginService.getUsernamesForRole(repository.name); } - + public boolean setRepositoryUsers(RepositoryModel repository, List repositoryUsers) { return loginService.setUsernamesForRole(repository.name, repositoryUsers); } - public void editUserModel(UserModel user, boolean isCreate) throws GitBlitException { - if (!loginService.updateUserModel(user)) { + public void editUserModel(String username, UserModel user, boolean isCreate) throws GitBlitException { + if (!loginService.updateUserModel(username, user)) { throw new GitBlitException(isCreate ? "Failed to add user!" : "Failed to update user!"); } } @@ -152,7 +137,7 @@ public class GitBlit implements ServletContextListener { } return repositories; } - + public RepositoryModel getRepositoryModel(UserModel user, String repositoryName) { RepositoryModel model = getRepositoryModel(repositoryName); if (model.accessRestriction.atLeast(AccessRestrictionType.VIEW)) { @@ -184,7 +169,7 @@ public class GitBlit implements ServletContextListener { r.close(); return model; } - + private String getConfig(StoredConfig config, String field, String defaultValue) { String value = config.getString("gitblit", null, field); if (StringUtils.isEmpty(value)) { @@ -192,21 +177,37 @@ public class GitBlit implements ServletContextListener { } return value; } - + private boolean getConfig(StoredConfig config, String field, boolean defaultValue) { return config.getBoolean("gitblit", field, defaultValue); } - public void editRepositoryModel(RepositoryModel repository, boolean isCreate) throws GitBlitException { + public void editRepositoryModel(String repositoryName, RepositoryModel repository, boolean isCreate) throws GitBlitException { Repository r = null; if (isCreate) { if (new File(repositoriesFolder, repository.name).exists()) { - throw new GitBlitException(MessageFormat.format("Can not create repository {0} because it already exists.", repository.name)); + throw new GitBlitException(MessageFormat.format("Can not create repository ''{0}'' because it already exists.", repository.name)); } // create repository logger.info("create repository " + repository.name); r = JGitUtils.createRepository(repositoriesFolder, repository.name, true); } else { + // rename repository + if (!repositoryName.equalsIgnoreCase(repository.name)) { + File folder = new File(repositoriesFolder, repositoryName); + File destFolder = new File(repositoriesFolder, repository.name); + if (destFolder.exists()) { + throw new GitBlitException(MessageFormat.format("Can not rename repository ''{0}'' to ''{1}'' because ''{1}'' already exists.", repositoryName, repository.name)); + } + if (!folder.renameTo(destFolder)) { + throw new GitBlitException(MessageFormat.format("Failed to rename repository ''{0}'' to ''{1}''.", repositoryName, repository.name)); + } + // rename the roles + if (!loginService.renameRole(repositoryName, repository.name)) { + throw new GitBlitException(MessageFormat.format("Failed to rename repository permissions ''{0}'' to ''{1}''.", repositoryName, repository.name)); + } + } + // load repository logger.info("edit repository " + repository.name); try { @@ -235,6 +236,36 @@ public class GitBlit implements ServletContextListener { r.close(); } + public boolean deleteRepositoryModel(RepositoryModel model) { + return deleteRepository(model.name); + } + + public boolean deleteRepository(String repositoryName) { + try { + File folder = new File(repositoriesFolder, repositoryName); + if (folder.exists() && folder.isDirectory()) { + FileUtils.delete(folder, FileUtils.RECURSIVE); + if (loginService.deleteRole(repositoryName)) { + return true; + } + } + } catch (Throwable t) { + logger.error(MessageFormat.format("Failed to delete repository {0}", repositoryName), t); + } + return false; + } + + public boolean renameRepository(RepositoryModel model, String newName) { + File folder = new File(repositoriesFolder, model.name); + if (folder.exists() && folder.isDirectory()) { + File newFolder = new File(repositoriesFolder, newName); + if (folder.renameTo(newFolder)) { + return loginService.renameRole(model.name, newName); + } + } + return false; + } + public void configureContext(IStoredSettings settings) { logger.info("Using configuration from " + settings.toString()); this.storedSettings = settings; diff --git a/src/com/gitblit/ILoginService.java b/src/com/gitblit/ILoginService.java index 242ff803..a548c9a8 100644 --- a/src/com/gitblit/ILoginService.java +++ b/src/com/gitblit/ILoginService.java @@ -8,14 +8,16 @@ public interface ILoginService { UserModel authenticate(String username, char[] password); - UserModel authenticate(char[] cookie); - UserModel getUserModel(String username); boolean updateUserModel(UserModel model); + boolean updateUserModel(String username, UserModel model); + boolean deleteUserModel(UserModel model); + boolean deleteUser(String username); + List getAllUsernames(); List getUsernamesForRole(String role); @@ -25,5 +27,4 @@ public interface ILoginService { boolean renameRole(String oldRole, String newRole); boolean deleteRole(String role); - } diff --git a/src/com/gitblit/JettyLoginService.java b/src/com/gitblit/JettyLoginService.java index c191f0f0..231f1744 100644 --- a/src/com/gitblit/JettyLoginService.java +++ b/src/com/gitblit/JettyLoginService.java @@ -23,7 +23,6 @@ import org.eclipse.jetty.util.log.Log; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.gitblit.utils.StringUtils; import com.gitblit.wicket.models.UserModel; public class JettyLoginService extends MappedLoginService implements ILoginService { @@ -45,7 +44,6 @@ public class JettyLoginService extends MappedLoginService implements ILoginServi return null; } UserModel user = new UserModel(username); - user.setCookie(StringUtils.getSHA1((Constants.NAME + username + new String(password)))); user.canAdmin(identity.isUserInRole(Constants.ADMIN_ROLE, null)); // Add repositories @@ -61,12 +59,6 @@ public class JettyLoginService extends MappedLoginService implements ILoginServi return user; } - @Override - public UserModel authenticate(char[] cookie) { - // TODO cookie login - return null; - } - @Override public UserModel getUserModel(String username) { UserIdentity identity = _users.get(username); @@ -107,6 +99,11 @@ public class JettyLoginService extends MappedLoginService implements ILoginServi @Override public boolean updateUserModel(UserModel model) { + return updateUserModel(model.getUsername(), model); + } + + @Override + public boolean updateUserModel(String username, UserModel model) { try { Properties allUsers = readRealmFile(); ArrayList roles = new ArrayList(model.getRepositories()); @@ -125,11 +122,13 @@ public class JettyLoginService extends MappedLoginService implements ILoginServi } // trim trailing comma sb.setLength(sb.length() - 1); + allUsers.remove(username); allUsers.put(model.getUsername(), sb.toString()); writeRealmFile(allUsers); // Update login service + removeUser(username); putUser(model.getUsername(), Credential.getCredential(model.getPassword()), roles.toArray(new String[0])); return true; } catch (Throwable t) { @@ -140,21 +139,26 @@ public class JettyLoginService extends MappedLoginService implements ILoginServi @Override public boolean deleteUserModel(UserModel model) { + return deleteUser(model.getUsername()); + } + + @Override + public boolean deleteUser(String username) { try { // Read realm file Properties allUsers = readRealmFile(); - allUsers.remove(model.getUsername()); + allUsers.remove(username); writeRealmFile(allUsers); // Drop user from map - _users.remove(model.getUsername()); + removeUser(username); return true; } catch (Throwable t) { - logger.error(MessageFormat.format("Failed to delete user model {0}!", model.getUsername()), t); + logger.error(MessageFormat.format("Failed to delete user {0}!", username), t); } return false; } - + @Override public List getAllUsernames() { List list = new ArrayList(); @@ -366,6 +370,7 @@ public class JettyLoginService extends MappedLoginService implements ILoginServi // persist changes writeRealmFile(allUsers); + return true; } catch (Throwable t) { logger.error(MessageFormat.format("Failed to delete role {0}!", role), t); } diff --git a/src/com/gitblit/utils/StringUtils.java b/src/com/gitblit/utils/StringUtils.java index 8b7960b3..ddb72860 100644 --- a/src/com/gitblit/utils/StringUtils.java +++ b/src/com/gitblit/utils/StringUtils.java @@ -40,9 +40,13 @@ public class StringUtils { } public static String flattenStrings(List values) { + return flattenStrings(values, " "); + } + + public static String flattenStrings(List values, String separator) { StringBuilder sb = new StringBuilder(); for (String value : values) { - sb.append(value).append(" "); + sb.append(value).append(separator); } return sb.toString().trim(); } diff --git a/src/com/gitblit/wicket/LoginPage.java b/src/com/gitblit/wicket/LoginPage.java index db971d27..63cb18f3 100644 --- a/src/com/gitblit/wicket/LoginPage.java +++ b/src/com/gitblit/wicket/LoginPage.java @@ -1,7 +1,5 @@ package com.gitblit.wicket; -import javax.servlet.http.Cookie; - import org.apache.wicket.PageParameters; import org.apache.wicket.markup.html.WebPage; import org.apache.wicket.markup.html.basic.Label; @@ -12,8 +10,6 @@ import org.apache.wicket.markup.html.form.TextField; 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 com.gitblit.Constants; import com.gitblit.GitBlit; @@ -28,8 +24,6 @@ public class LoginPage extends WebPage { public LoginPage(PageParameters params) { super(params); - tryAutomaticLogin(); - add(new Label("title", GitBlit.self().settings().getString(Keys.web.siteName, Constants.NAME))); add(new Label("name", Constants.NAME)); @@ -52,8 +46,6 @@ public class LoginPage extends WebPage { setRedirect(true); setResponsePage(getApplication().getHomePage()); } - - tryAutomaticLogin(); } @Override @@ -68,29 +60,12 @@ public class LoginPage extends WebPage { loginUser(user); } } - - private void tryAutomaticLogin() { - UserModel user = null; - - // Grab cookie from Browser Session - Cookie[] cookies = ((WebRequest) getRequestCycle().getRequest()).getCookies(); - if (cookies != null && cookies.length > 0) { - user = GitBlit.self().authenticate(cookies); - } - - // Login the user - loginUser(user); - } - + private void loginUser(UserModel user) { if (user != null) { // Set the user into the session GitBlitWebSession.get().setUser(user); - // Set Cookie - WebResponse response = (WebResponse) getRequestCycle().getResponse(); - GitBlit.self().setCookie(response, user); - if (!continueToOriginalDestination()) { // Redirect to home page setResponsePage(getApplication().getHomePage()); diff --git a/src/com/gitblit/wicket/RepositoryPage.java b/src/com/gitblit/wicket/RepositoryPage.java index e3ae6352..7b447bc0 100644 --- a/src/com/gitblit/wicket/RepositoryPage.java +++ b/src/com/gitblit/wicket/RepositoryPage.java @@ -35,6 +35,7 @@ import com.gitblit.utils.StringUtils; import com.gitblit.wicket.models.RepositoryModel; import com.gitblit.wicket.pages.BranchesPage; import com.gitblit.wicket.pages.DocsPage; +import com.gitblit.wicket.pages.EditRepositoryPage; import com.gitblit.wicket.pages.LogPage; import com.gitblit.wicket.pages.SearchPage; import com.gitblit.wicket.pages.SummaryPage; @@ -65,6 +66,7 @@ public abstract class RepositoryPage extends BasePage { put("tags", "gb.tags"); put("tree", "gb.tree"); put("tickets", "gb.tickets"); + put("edit", "gb.edit"); } }; @@ -90,16 +92,29 @@ public abstract class RepositoryPage extends BasePage { // per-repository extra page links List extraPageLinks = new ArrayList(); - // Conditionally add tickets page + // Conditionally add tickets link if (model.useTickets && JGitUtils.getTicketsBranch(r) != null) { extraPageLinks.add("tickets"); } - // Conditionally add docs page + // Conditionally add docs link if (model.useDocs) { extraPageLinks.add("docs"); } + final boolean showAdmin; + if (GitBlit.self().settings().getBoolean(Keys.web.authenticateAdminPages, true)) { + boolean allowAdmin = GitBlit.self().settings().getBoolean(Keys.web.allowAdministration, false); + showAdmin = allowAdmin && GitBlitWebSession.get().canAdmin(); + } else { + showAdmin = GitBlit.self().settings().getBoolean(Keys.web.allowAdministration, false); + } + + // Conditionally add edit link + if (showAdmin || GitBlitWebSession.get().isLoggedIn() && (model.owner != null && model.owner.equalsIgnoreCase(GitBlitWebSession.get().getUser().getUsername()))) { + extraPageLinks.add("edit"); + } + ListDataProvider extrasDp = new ListDataProvider(extraPageLinks); DataView extrasView = new DataView("extra", extrasDp) { private static final long serialVersionUID = 1L; @@ -112,6 +127,9 @@ public abstract class RepositoryPage extends BasePage { } else if (extra.equals("docs")) { item.add(new Label("extraSeparator", " | ")); item.add(new LinkPanel("extraLink", null, getString("gb.docs"), DocsPage.class, WicketUtils.newRepositoryParameter(repositoryName))); + } else if (extra.equals("edit")) { + item.add(new Label("extraSeparator", " | ")); + item.add(new LinkPanel("extraLink", null, getString("gb.edit"), EditRepositoryPage.class, WicketUtils.newRepositoryParameter(repositoryName))); } } }; diff --git a/src/com/gitblit/wicket/models/RepositoryModel.java b/src/com/gitblit/wicket/models/RepositoryModel.java index 2aabfb19..e7b52494 100644 --- a/src/com/gitblit/wicket/models/RepositoryModel.java +++ b/src/com/gitblit/wicket/models/RepositoryModel.java @@ -33,5 +33,10 @@ public class RepositoryModel implements Serializable { this.owner = owner; this.lastChange = lastchange; this.accessRestriction = AccessRestrictionType.NONE; - } + } + + @Override + public String toString() { + return name; + } } \ No newline at end of file diff --git a/src/com/gitblit/wicket/models/UserModel.java b/src/com/gitblit/wicket/models/UserModel.java index 34c32e71..252bcfa2 100644 --- a/src/com/gitblit/wicket/models/UserModel.java +++ b/src/com/gitblit/wicket/models/UserModel.java @@ -10,7 +10,6 @@ public class UserModel implements Serializable { private String username; private String password; - private String cookie; private boolean canAdmin = false; private List repositories = new ArrayList(); @@ -42,14 +41,6 @@ public class UserModel implements Serializable { return canAdmin || repositories.contains(repositoryName); } - public void setCookie(String cookie) { - this.cookie = cookie; - } - - public String getCookie() { - return cookie; - } - public void setRepositories(List repositories) { this.repositories.clear(); this.repositories.addAll(repositories); @@ -63,6 +54,7 @@ public class UserModel implements Serializable { return repositories; } + @Override public String toString() { return username; } diff --git a/src/com/gitblit/wicket/pages/EditRepositoryPage.java b/src/com/gitblit/wicket/pages/EditRepositoryPage.java index 56d1d558..20a9c737 100644 --- a/src/com/gitblit/wicket/pages/EditRepositoryPage.java +++ b/src/com/gitblit/wicket/pages/EditRepositoryPage.java @@ -36,6 +36,8 @@ public class EditRepositoryPage extends BasePage { private final boolean isCreate; + private boolean isAdmin = false; + public EditRepositoryPage() { // create constructor super(); @@ -67,6 +69,7 @@ public class EditRepositoryPage extends BasePage { } } + final String oldName = repositoryModel.name; final Palette usersPalette = new Palette("users", new ListModel(repositoryUsers), new CollectionModel(GitBlit.self().getAllUsernames()), new ChoiceRenderer("", ""), 10, false); CompoundPropertyModel model = new CompoundPropertyModel(repositoryModel); Form form = new Form("editForm", model) { @@ -94,7 +97,7 @@ public class EditRepositoryPage extends BasePage { ok |= c == vc; } if (!ok) { - error(MessageFormat.format("Illegal character '{0}' in repository name!", c)); + error(MessageFormat.format("Illegal character ''{0}'' in repository name!", c)); return; } } @@ -107,7 +110,7 @@ public class EditRepositoryPage extends BasePage { } // save the repository - GitBlit.self().editRepositoryModel(repositoryModel, isCreate); + GitBlit.self().editRepositoryModel(oldName, repositoryModel, isCreate); // save the repository access list if (repositoryModel.accessRestriction.exceeds(AccessRestrictionType.NONE)) { @@ -117,7 +120,7 @@ public class EditRepositoryPage extends BasePage { repositoryUsers.add(users.next()); } // ensure the owner is added to the user list - if (!repositoryUsers.contains(repositoryModel.owner)) { + if (repositoryModel.owner != null && !repositoryUsers.contains(repositoryModel.owner)) { repositoryUsers.add(repositoryModel.owner); } GitBlit.self().setRepositoryUsers(repositoryModel, repositoryUsers); @@ -132,7 +135,7 @@ public class EditRepositoryPage extends BasePage { }; // field names reflective match RepositoryModel fields - form.add(new TextField("name").setEnabled(isCreate)); + form.add(new TextField("name").setEnabled(isCreate || isAdmin)); form.add(new TextField("description")); form.add(new DropDownChoice("owner", GitBlit.self().getAllUsernames()).setEnabled(GitBlitWebSession.get().canAdmin())); form.add(new DropDownChoice("accessRestriction", Arrays.asList(AccessRestrictionType.values()), new AccessRestrictionRenderer())); @@ -175,6 +178,7 @@ public class EditRepositoryPage extends BasePage { // Edit Repository if (user.canAdmin()) { // Admins can edit everything + isAdmin = true; return; } else { if (!model.owner.equalsIgnoreCase(user.getUsername())) { diff --git a/src/com/gitblit/wicket/pages/EditUserPage.java b/src/com/gitblit/wicket/pages/EditUserPage.java index 7522f3ed..4a6882fc 100644 --- a/src/com/gitblit/wicket/pages/EditUserPage.java +++ b/src/com/gitblit/wicket/pages/EditUserPage.java @@ -67,6 +67,7 @@ public class EditUserPage extends BasePage { repos.add(repo); } } + final String oldName = userModel.getUsername(); final Palette repositories = new Palette("repositories", new ListModel(userModel.getRepositories()), new CollectionModel(repos), new ChoiceRenderer("", ""), 10, false); Form form = new Form("editForm", model) { @@ -87,7 +88,7 @@ public class EditUserPage extends BasePage { if (isCreate) { UserModel model = GitBlit.self().getUserModel(username); if (model != null) { - error(MessageFormat.format("Username {0} is unavailable.", username)); + error(MessageFormat.format("Username ''{0}'' is unavailable.", username)); return; } } @@ -108,14 +109,11 @@ public class EditUserPage extends BasePage { return; } - // Optionally encrypt/obfuscate the password. + // Optionally store the password MD5 digest. String type = GitBlit.self().settings().getString(Keys.realm.passwordStorage, "md5"); if (type.equalsIgnoreCase("md5")) { - // store MD5 checksum of password + // store MD5 digest of password userModel.setPassword(MD5.digest(userModel.getPassword())); - } else if (type.equalsIgnoreCase("crypt")) { - // simple unix encryption - userModel.setPassword(Crypt.crypt(userModel.getUsername(), userModel.getPassword())); } } @@ -126,7 +124,7 @@ public class EditUserPage extends BasePage { } userModel.setRepositories(repos); try { - GitBlit.self().editUserModel(userModel, isCreate); + GitBlit.self().editUserModel(oldName, userModel, isCreate); } catch (GitBlitException e) { error(e.getMessage()); return; @@ -134,7 +132,7 @@ public class EditUserPage extends BasePage { setRedirect(false); if (isCreate) { // create another user - info(MessageFormat.format("New user {0} successfully created.", userModel.getUsername())); + info(MessageFormat.format("New user ''{0}'' successfully created.", userModel.getUsername())); setResponsePage(EditUserPage.class); } else { // back to home @@ -144,7 +142,7 @@ public class EditUserPage extends BasePage { }; // field names reflective match UserModel fields - form.add(new TextField("username").setEnabled(isCreate)); + form.add(new TextField("username")); PasswordTextField passwordField = new PasswordTextField("password"); passwordField.setResetPassword(false); form.add(passwordField); diff --git a/src/com/gitblit/wicket/pages/RepositoriesPage.java b/src/com/gitblit/wicket/pages/RepositoriesPage.java index 32552f7e..e421c895 100644 --- a/src/com/gitblit/wicket/pages/RepositoriesPage.java +++ b/src/com/gitblit/wicket/pages/RepositoriesPage.java @@ -46,7 +46,6 @@ public class RepositoriesPage extends BasePage { String cachedMessage = GitBlitWebSession.get().clearErrorMessage(); if (!StringUtils.isEmpty(cachedMessage)) { error(cachedMessage); - System.out.println("displayed message"); } // Load the markdown welcome message diff --git a/src/com/gitblit/wicket/pages/SummaryPage.html b/src/com/gitblit/wicket/pages/SummaryPage.html index 35331f56..1a90c998 100644 --- a/src/com/gitblit/wicket/pages/SummaryPage.html +++ b/src/com/gitblit/wicket/pages/SummaryPage.html @@ -20,7 +20,7 @@ [owner][repository owner] [last change][repository last change] [stats][repository stats] - [URL][repository clone url] + [URL][repository clone url] diff --git a/src/com/gitblit/wicket/pages/SummaryPage.java b/src/com/gitblit/wicket/pages/SummaryPage.java index d83f5961..c596e871 100644 --- a/src/com/gitblit/wicket/pages/SummaryPage.java +++ b/src/com/gitblit/wicket/pages/SummaryPage.java @@ -3,10 +3,14 @@ package com.gitblit.wicket.pages; import java.awt.Color; import java.awt.Dimension; import java.text.MessageFormat; +import java.util.ArrayList; import java.util.List; +import javax.servlet.http.HttpServletRequest; + import org.apache.wicket.PageParameters; import org.apache.wicket.markup.html.basic.Label; +import org.apache.wicket.protocol.http.WebRequest; import org.eclipse.jgit.lib.Repository; import org.wicketstuff.googlecharts.AbstractChartData; import org.wicketstuff.googlecharts.Chart; @@ -19,10 +23,12 @@ import org.wicketstuff.googlecharts.LineStyle; import org.wicketstuff.googlecharts.MarkerType; import org.wicketstuff.googlecharts.ShapeMarker; +import com.gitblit.Constants; import com.gitblit.Constants.AccessRestrictionType; import com.gitblit.GitBlit; import com.gitblit.Keys; import com.gitblit.utils.JGitUtils; +import com.gitblit.utils.StringUtils; import com.gitblit.utils.TimeUtils; import com.gitblit.wicket.RepositoryPage; import com.gitblit.wicket.WicketUtils; @@ -67,25 +73,45 @@ public class SummaryPage extends RepositoryPage { } else { add(new Label("repositoryStats", MessageFormat.format("{0} commits and {1} tags in {2}", metricsTotal.count, metricsTotal.tag, TimeUtils.duration(metricsTotal.duration)))); } - - AccessRestrictionType accessRestriction = getRepositoryModel().accessRestriction; - switch (accessRestriction) { - case NONE: - add(WicketUtils.newClearPixel("accessRestrictionIcon").setVisible(false)); - break; - case PUSH: - add(WicketUtils.newImage("accessRestrictionIcon", "lock_go_16x16.png", getAccessRestrictions().get(accessRestriction))); - break; - case CLONE: - add(WicketUtils.newImage("accessRestrictionIcon", "lock_pull_16x16.png", getAccessRestrictions().get(accessRestriction))); - break; - case VIEW: - add(WicketUtils.newImage("accessRestrictionIcon", "shield_16x16.png", getAccessRestrictions().get(accessRestriction))); - break; - default: + + List repositoryUrls = new ArrayList(); + + if (GitBlit.self().settings().getBoolean(Keys.git.enableGitServlet, true)) { + AccessRestrictionType accessRestriction = getRepositoryModel().accessRestriction; + switch (accessRestriction) { + case NONE: + add(WicketUtils.newClearPixel("accessRestrictionIcon").setVisible(false)); + break; + case PUSH: + add(WicketUtils.newImage("accessRestrictionIcon", "lock_go_16x16.png", getAccessRestrictions().get(accessRestriction))); + break; + case CLONE: + add(WicketUtils.newImage("accessRestrictionIcon", "lock_pull_16x16.png", getAccessRestrictions().get(accessRestriction))); + break; + case VIEW: + add(WicketUtils.newImage("accessRestrictionIcon", "shield_16x16.png", getAccessRestrictions().get(accessRestriction))); + break; + default: + add(WicketUtils.newClearPixel("accessRestrictionIcon").setVisible(false)); + } + + HttpServletRequest req = ((WebRequest) getRequestCycle().getRequest()).getHttpServletRequest(); + StringBuilder sb = new StringBuilder(); + sb.append(req.getScheme()); + sb.append("://"); + sb.append(req.getServerName()); + if ((req.getScheme().equals("http") && req.getServerPort() != 80) || (req.getScheme().equals("https") && req.getServerPort() != 443)) { + sb.append(":" + req.getServerPort()); + } + sb.append(Constants.GIT_SERVLET_PATH); + sb.append(repositoryName); + repositoryUrls.add(sb.toString()); + } else { add(WicketUtils.newClearPixel("accessRestrictionIcon").setVisible(false)); } - add(new Label("repositoryCloneUrl", GitBlit.self().getCloneUrl(repositoryName))); + repositoryUrls.addAll(GitBlit.self().getOtherCloneUrls(repositoryName)); + + add(new Label("repositoryCloneUrl", StringUtils.flattenStrings(repositoryUrls, "
")).setEscapeModelStrings(false)); add(new LogPanel("commitsPanel", repositoryName, null, r, numberCommits, 0)); add(new TagsPanel("tagsPanel", repositoryName, r, numberRefs)); @@ -113,9 +139,9 @@ public class SummaryPage extends RepositoryPage { commitAxis.setLabels(new String[] { "", String.valueOf((int) maxValue(metrics)) }); provider.addAxis(commitAxis); - provider.setLineStyles(new LineStyle[] {new LineStyle(2, 4, 0), new LineStyle(0, 4, 1)}); + provider.setLineStyles(new LineStyle[] { new LineStyle(2, 4, 0), new LineStyle(0, 4, 1) }); provider.addShapeMarker(new ShapeMarker(MarkerType.CIRCLE, Color.BLUE, 1, -1, 5)); - + add(new Chart("commitsChart", provider)); } else { add(WicketUtils.newBlankImage("commitsChart")); diff --git a/src/com/gitblit/wicket/panels/BasePanel.java b/src/com/gitblit/wicket/panels/BasePanel.java index 43cd1263..6ebb8a7a 100644 --- a/src/com/gitblit/wicket/panels/BasePanel.java +++ b/src/com/gitblit/wicket/panels/BasePanel.java @@ -2,8 +2,10 @@ package com.gitblit.wicket.panels; import java.util.TimeZone; +import org.apache.wicket.AttributeModifier; import org.apache.wicket.Component; import org.apache.wicket.markup.html.panel.Panel; +import org.apache.wicket.model.Model; import com.gitblit.GitBlit; import com.gitblit.Keys; @@ -30,4 +32,22 @@ public abstract class BasePanel extends Panel { WicketUtils.setHtmlTooltip(component, getString("gb.searchForCommitter") + " " + value); } } + + public class JavascriptEventConfirmation extends AttributeModifier { + + private static final long serialVersionUID = 1L; + + public JavascriptEventConfirmation(String event, String msg) { + super(event, true, new Model(msg)); + } + + protected String newValue(final String currentValue, final String replacementValue) { + String prefix = "var conf = confirm('" + replacementValue + "'); " + "if (!conf) return false; "; + String result = prefix; + if (currentValue != null) { + result = prefix + currentValue; + } + return result; + } + } } diff --git a/src/com/gitblit/wicket/panels/RepositoriesPanel.html b/src/com/gitblit/wicket/panels/RepositoriesPanel.html index a066b58e..a599d226 100644 --- a/src/com/gitblit/wicket/panels/RepositoriesPanel.html +++ b/src/com/gitblit/wicket/panels/RepositoriesPanel.html @@ -31,7 +31,7 @@ - [edit] | [rename] | [delete] + [edit] | [delete] diff --git a/src/com/gitblit/wicket/panels/RepositoriesPanel.java b/src/com/gitblit/wicket/panels/RepositoriesPanel.java index 6d05888e..c1413792 100644 --- a/src/com/gitblit/wicket/panels/RepositoriesPanel.java +++ b/src/com/gitblit/wicket/panels/RepositoriesPanel.java @@ -1,5 +1,6 @@ package com.gitblit.wicket.panels; +import java.text.MessageFormat; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -15,6 +16,7 @@ import org.apache.wicket.extensions.markup.html.repeater.util.SortParam; import org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvider; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.link.BookmarkablePageLink; +import org.apache.wicket.markup.html.link.Link; import org.apache.wicket.markup.html.panel.Fragment; import org.apache.wicket.markup.repeater.Item; import org.apache.wicket.markup.repeater.data.DataView; @@ -36,22 +38,21 @@ import com.gitblit.wicket.models.UserModel; import com.gitblit.wicket.pages.EditRepositoryPage; import com.gitblit.wicket.pages.SummaryPage; - public class RepositoriesPanel extends BasePanel { private static final long serialVersionUID = 1L; - + public RepositoriesPanel(String wicketId, final boolean showAdmin, final Map accessRestrictionTranslations) { super(wicketId); - + final UserModel user = GitBlitWebSession.get().getUser(); List models = GitBlit.self().getRepositoryModels(user); - IDataProvider dp; - + final IDataProvider dp; + Fragment adminLinks = new Fragment("adminPanel", "adminLinks", this); adminLinks.add(new BookmarkablePageLink("newRepository", EditRepositoryPage.class)); add(adminLinks.setVisible(showAdmin)); - + if (GitBlit.self().settings().getString(Keys.web.repositoryListType, "flat").equalsIgnoreCase("grouped")) { Map> groups = new HashMap>(); for (RepositoryModel model : models) { @@ -69,24 +70,30 @@ public class RepositoriesPanel extends BasePanel { List groupedModels = new ArrayList(); for (String root : roots) { List subModels = groups.get(root); - groupedModels.add(new GroupRepositoryModel(root + " (" + subModels.size() + ")")); + groupedModels.add(new GroupRepositoryModel(root, subModels.size())); groupedModels.addAll(subModels); } - dp = new ListDataProvider(groupedModels); + dp = new RepositoriesProvider(groupedModels); } else { - dp = new DataProvider(models); + dp = new SortableRepositoriesProvider(models); } DataView dataView = new DataView("row", dp) { private static final long serialVersionUID = 1L; int counter = 0; + @Override + protected void onBeforeRender() { + super.onBeforeRender(); + counter = 0; + } + public void populateItem(final Item item) { final RepositoryModel entry = item.getModelObject(); if (entry instanceof GroupRepositoryModel) { Fragment row = new Fragment("rowContent", "groupRepositoryRow", this); item.add(row); - row.add(new Label("groupName", entry.name)); + row.add(new Label("groupName", entry.toString())); WicketUtils.setCssClass(item, "group"); return; } @@ -144,12 +151,30 @@ public class RepositoriesPanel extends BasePanel { row.add(lastChangeLabel); WicketUtils.setCssClass(lastChangeLabel, TimeUtils.timeAgoCss(entry.lastChange)); - boolean showOwner = user != null && user.getUsername().equalsIgnoreCase(entry.owner); + boolean showOwner = user != null && user.getUsername().equalsIgnoreCase(entry.owner); if (showAdmin) { Fragment repositoryLinks = new Fragment("repositoryLinks", "repositoryAdminLinks", this); repositoryLinks.add(new BookmarkablePageLink("editRepository", EditRepositoryPage.class, WicketUtils.newRepositoryParameter(entry.name))); - repositoryLinks.add(new BookmarkablePageLink("renameRepository", EditRepositoryPage.class, WicketUtils.newRepositoryParameter(entry.name)).setEnabled(false)); - repositoryLinks.add(new BookmarkablePageLink("deleteRepository", EditRepositoryPage.class, WicketUtils.newRepositoryParameter(entry.name)).setEnabled(false)); + Link deleteLink = new Link("deleteRepository") { + + private static final long serialVersionUID = 1L; + + @Override + public void onClick() { + if (GitBlit.self().deleteRepositoryModel(entry)) { + info(MessageFormat.format("Repository ''{0}'' deleted.", entry)); + if (dp instanceof SortableRepositoriesProvider) { + ((SortableRepositoriesProvider) dp).remove(entry); + } else { + ((RepositoriesProvider) dp).remove(entry); + } + } else { + error(MessageFormat.format("Failed to delete repository ''{0}''!", entry)); + } + } + }; + deleteLink.add(new JavascriptEventConfirmation("onclick", MessageFormat.format("Delete repository \"{0}\"?", entry))); + repositoryLinks.add(deleteLink); row.add(repositoryLinks); } else if (showOwner) { Fragment repositoryLinks = new Fragment("repositoryLinks", "repositoryOwnerLinks", this); @@ -179,16 +204,24 @@ public class RepositoriesPanel extends BasePanel { add(fragment); } } - + private class GroupRepositoryModel extends RepositoryModel { private static final long serialVersionUID = 1L; - GroupRepositoryModel(String name) { + int count = 0; + + GroupRepositoryModel(String name, int count) { super(name, "", "", new Date(0)); + this.count = count; + } + + @Override + public String toString() { + return name + " (" + count + ")"; } } - + protected enum SortBy { repository, description, owner, date; } @@ -204,15 +237,71 @@ public class RepositoriesPanel extends BasePanel { }; } - private class DataProvider extends SortableDataProvider { + private class RepositoriesProvider extends ListDataProvider { + + private static final long serialVersionUID = 1L; + + public RepositoriesProvider(List list) { + super(list); + } + + @Override + public List getData() { + return super.getData(); + } + + public void remove(RepositoryModel model) { + int index = getData().indexOf(model); + RepositoryModel groupModel = null; + if (index == (getData().size() - 1)) { + // last element + if (index > 0) { + // previous element is group header, then this is last + // repository in group. remove group too. + if (getData().get(index - 1) instanceof GroupRepositoryModel) { + groupModel = getData().get(index - 1); + } + } + } else if (index < (getData().size() - 1)) { + // not last element. check next element for group match. + if (getData().get(index - 1) instanceof GroupRepositoryModel && getData().get(index + 1) instanceof GroupRepositoryModel) { + // repository is sandwiched by group headers so this + // repository is the only element in the group. remove + // group. + groupModel = getData().get(index - 1); + } + } + + if (groupModel == null) { + // Find the group and decrement the count + for (int i = index; i >= 0; i--) { + if (getData().get(i) instanceof GroupRepositoryModel) { + ((GroupRepositoryModel) getData().get(i)).count--; + break; + } + } + } else { + // Remove the group header + getData().remove(groupModel); + } + + getData().remove(model); + } + } + + private class SortableRepositoriesProvider extends SortableDataProvider { private static final long serialVersionUID = 1L; private List list = null; - protected DataProvider(List list) { + protected SortableRepositoriesProvider(List list) { this.list = list; setSort(SortBy.date.name(), false); } + public void remove(RepositoryModel model) { + list.remove(model); + } + @Override public int size() { if (list == null) diff --git a/src/com/gitblit/wicket/panels/UsersPanel.java b/src/com/gitblit/wicket/panels/UsersPanel.java index 17212723..55671ec1 100644 --- a/src/com/gitblit/wicket/panels/UsersPanel.java +++ b/src/com/gitblit/wicket/panels/UsersPanel.java @@ -1,6 +1,10 @@ package com.gitblit.wicket.panels; +import java.text.MessageFormat; +import java.util.List; + import org.apache.wicket.markup.html.link.BookmarkablePageLink; +import org.apache.wicket.markup.html.link.Link; import org.apache.wicket.markup.html.panel.Fragment; import org.apache.wicket.markup.repeater.Item; import org.apache.wicket.markup.repeater.data.DataView; @@ -10,7 +14,6 @@ import com.gitblit.GitBlit; import com.gitblit.wicket.LinkPanel; import com.gitblit.wicket.WicketUtils; import com.gitblit.wicket.pages.EditUserPage; -import com.gitblit.wicket.pages.RepositoriesPage; public class UsersPanel extends BasePanel { @@ -22,10 +25,17 @@ public class UsersPanel extends BasePanel { Fragment adminLinks = new Fragment("adminPanel", "adminLinks", this); adminLinks.add(new BookmarkablePageLink("newUser", EditUserPage.class)); add(adminLinks.setVisible(showAdmin)); - - DataView usersView = new DataView("userRow", new ListDataProvider(GitBlit.self().getAllUsernames())) { + + final List usernames = GitBlit.self().getAllUsernames(); + DataView usersView = new DataView("userRow", new ListDataProvider(usernames)) { private static final long serialVersionUID = 1L; private int counter = 0; + + @Override + protected void onBeforeRender() { + super.onBeforeRender(); + counter = 0; + } public void populateItem(final Item item) { final String entry = item.getModelObject(); @@ -34,7 +44,22 @@ public class UsersPanel extends BasePanel { item.add(editLink); Fragment userLinks = new Fragment("userLinks", "userAdminLinks", this); userLinks.add(new BookmarkablePageLink("editUser", EditUserPage.class, WicketUtils.newUsernameParameter(entry))); - userLinks.add(new BookmarkablePageLink("deleteUser", RepositoriesPage.class, WicketUtils.newUsernameParameter(entry)).setEnabled(false)); + Link deleteLink = new Link("deleteUser") { + + private static final long serialVersionUID = 1L; + + @Override + public void onClick() { + if (GitBlit.self().deleteUser(entry)) { + usernames.remove(entry); + info(MessageFormat.format("User ''{0}'' deleted.", entry)); + } else { + error(MessageFormat.format("Failed to delete user ''{0}''!", entry)); + } + } + }; + deleteLink.add(new JavascriptEventConfirmation("onclick", MessageFormat.format("Delete user \"{0}\"?", entry))); + userLinks.add(deleteLink); item.add(userLinks); WicketUtils.setAlternatingBackground(item, counter); diff --git a/src/com/gitblit/wicket/resources/gitblt.png b/src/com/gitblit/wicket/resources/gitblt.png deleted file mode 100644 index 7535bc3c..00000000 Binary files a/src/com/gitblit/wicket/resources/gitblt.png and /dev/null differ diff --git a/src/com/gitblit/wicket/resources/gitblt3.png b/src/com/gitblit/wicket/resources/gitblt3.png deleted file mode 100644 index f178d03c..00000000 Binary files a/src/com/gitblit/wicket/resources/gitblt3.png and /dev/null differ