# e.g. /libraries/mylibrary.git\r
git.nestedRepositories = true\r
\r
-# The root clone url\r
-git.cloneUrl = https://localhost/git/\r
+# Show other URLs on the summary page for accessing your git repositories\r
+# Use spaces to separate urls. {0} is the token for the repository name.\r
+# git.otherUrls = ssh://localhost/git/{0} git://localhost/git/{0}\r
+git.otherUrls = \r
\r
#\r
# Authentication Settings\r
realm.realmFile = users.properties\r
\r
# How to store passwords.\r
-# Valid values are plain, md5 or crypt (unix style). Default is md5. \r
+# Valid values are plain or md5. Default is md5. \r
realm.passwordStorage = md5\r
\r
# Minimum valid length for a plain text password.\r
\r
import javax.servlet.ServletContextEvent;\r
import javax.servlet.ServletContextListener;\r
-import javax.servlet.http.Cookie;\r
\r
-import org.apache.wicket.protocol.http.WebResponse;\r
import org.eclipse.jgit.errors.RepositoryNotFoundException;\r
import org.eclipse.jgit.lib.Repository;\r
import org.eclipse.jgit.lib.StoredConfig;\r
import org.eclipse.jgit.transport.resolver.FileResolver;\r
import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;\r
+import org.eclipse.jgit.util.FileUtils;\r
import org.slf4j.Logger;\r
import org.slf4j.LoggerFactory;\r
\r
return storedSettings.getBoolean(Keys.web.debugMode, false);\r
}\r
\r
- public String getCloneUrl(String repositoryName) {\r
- return storedSettings.getString(Keys.git.cloneUrl, "https://localhost/git/") + repositoryName;\r
+ public List<String> getOtherCloneUrls(String repositoryName) {\r
+ List<String> cloneUrls = new ArrayList<String>();\r
+ for (String url : storedSettings.getStrings(Keys.git.otherUrls)) {\r
+ cloneUrls.add(MessageFormat.format(url, repositoryName));\r
+ }\r
+ return cloneUrls;\r
}\r
\r
public void setLoginService(ILoginService loginService) {\r
return loginService.authenticate(username, password);\r
}\r
\r
- public UserModel authenticate(Cookie[] cookies) {\r
- if (loginService == null) {\r
- return null;\r
- }\r
- if (cookies != null && cookies.length > 0) {\r
- for (Cookie cookie : cookies) {\r
- if (cookie.getName().equals(Constants.NAME)) {\r
- String value = cookie.getValue();\r
- return loginService.authenticate(value.toCharArray());\r
- }\r
- }\r
- }\r
- return null;\r
- }\r
-\r
- public void setCookie(WebResponse response, UserModel user) {\r
- Cookie userCookie = new Cookie(Constants.NAME, user.getCookie());\r
- userCookie.setMaxAge(Integer.MAX_VALUE);\r
- userCookie.setPath("/");\r
- response.addCookie(userCookie);\r
- }\r
- \r
public List<String> getAllUsernames() {\r
- List<String> names = loginService.getAllUsernames();\r
+ List<String> names = new ArrayList<String>(loginService.getAllUsernames());\r
Collections.sort(names);\r
return names;\r
}\r
\r
+ public boolean deleteUser(String username) {\r
+ return loginService.deleteUser(username);\r
+ }\r
+\r
public UserModel getUserModel(String username) {\r
UserModel user = loginService.getUserModel(username);\r
return user;\r
}\r
- \r
+\r
public List<String> getRepositoryUsers(RepositoryModel repository) {\r
return loginService.getUsernamesForRole(repository.name);\r
}\r
- \r
+\r
public boolean setRepositoryUsers(RepositoryModel repository, List<String> repositoryUsers) {\r
return loginService.setUsernamesForRole(repository.name, repositoryUsers);\r
}\r
\r
- public void editUserModel(UserModel user, boolean isCreate) throws GitBlitException {\r
- if (!loginService.updateUserModel(user)) {\r
+ public void editUserModel(String username, UserModel user, boolean isCreate) throws GitBlitException {\r
+ if (!loginService.updateUserModel(username, user)) {\r
throw new GitBlitException(isCreate ? "Failed to add user!" : "Failed to update user!");\r
}\r
}\r
}\r
return repositories;\r
}\r
- \r
+\r
public RepositoryModel getRepositoryModel(UserModel user, String repositoryName) {\r
RepositoryModel model = getRepositoryModel(repositoryName);\r
if (model.accessRestriction.atLeast(AccessRestrictionType.VIEW)) {\r
r.close();\r
return model;\r
}\r
- \r
+\r
private String getConfig(StoredConfig config, String field, String defaultValue) {\r
String value = config.getString("gitblit", null, field);\r
if (StringUtils.isEmpty(value)) {\r
}\r
return value;\r
}\r
- \r
+\r
private boolean getConfig(StoredConfig config, String field, boolean defaultValue) {\r
return config.getBoolean("gitblit", field, defaultValue);\r
}\r
\r
- public void editRepositoryModel(RepositoryModel repository, boolean isCreate) throws GitBlitException {\r
+ public void editRepositoryModel(String repositoryName, RepositoryModel repository, boolean isCreate) throws GitBlitException {\r
Repository r = null;\r
if (isCreate) {\r
if (new File(repositoriesFolder, repository.name).exists()) {\r
- throw new GitBlitException(MessageFormat.format("Can not create repository {0} because it already exists.", repository.name));\r
+ throw new GitBlitException(MessageFormat.format("Can not create repository ''{0}'' because it already exists.", repository.name));\r
}\r
// create repository\r
logger.info("create repository " + repository.name);\r
r = JGitUtils.createRepository(repositoriesFolder, repository.name, true);\r
} else {\r
+ // rename repository\r
+ if (!repositoryName.equalsIgnoreCase(repository.name)) {\r
+ File folder = new File(repositoriesFolder, repositoryName);\r
+ File destFolder = new File(repositoriesFolder, repository.name);\r
+ if (destFolder.exists()) {\r
+ throw new GitBlitException(MessageFormat.format("Can not rename repository ''{0}'' to ''{1}'' because ''{1}'' already exists.", repositoryName, repository.name));\r
+ }\r
+ if (!folder.renameTo(destFolder)) {\r
+ throw new GitBlitException(MessageFormat.format("Failed to rename repository ''{0}'' to ''{1}''.", repositoryName, repository.name));\r
+ }\r
+ // rename the roles\r
+ if (!loginService.renameRole(repositoryName, repository.name)) {\r
+ throw new GitBlitException(MessageFormat.format("Failed to rename repository permissions ''{0}'' to ''{1}''.", repositoryName, repository.name));\r
+ }\r
+ }\r
+\r
// load repository\r
logger.info("edit repository " + repository.name);\r
try {\r
r.close();\r
}\r
\r
+ public boolean deleteRepositoryModel(RepositoryModel model) {\r
+ return deleteRepository(model.name);\r
+ }\r
+\r
+ public boolean deleteRepository(String repositoryName) {\r
+ try {\r
+ File folder = new File(repositoriesFolder, repositoryName);\r
+ if (folder.exists() && folder.isDirectory()) {\r
+ FileUtils.delete(folder, FileUtils.RECURSIVE);\r
+ if (loginService.deleteRole(repositoryName)) {\r
+ return true;\r
+ }\r
+ }\r
+ } catch (Throwable t) {\r
+ logger.error(MessageFormat.format("Failed to delete repository {0}", repositoryName), t);\r
+ }\r
+ return false;\r
+ }\r
+\r
+ public boolean renameRepository(RepositoryModel model, String newName) {\r
+ File folder = new File(repositoriesFolder, model.name);\r
+ if (folder.exists() && folder.isDirectory()) {\r
+ File newFolder = new File(repositoriesFolder, newName);\r
+ if (folder.renameTo(newFolder)) {\r
+ return loginService.renameRole(model.name, newName);\r
+ }\r
+ }\r
+ return false;\r
+ }\r
+\r
public void configureContext(IStoredSettings settings) {\r
logger.info("Using configuration from " + settings.toString());\r
this.storedSettings = settings;\r
\r
UserModel authenticate(String username, char[] password);\r
\r
- UserModel authenticate(char[] cookie);\r
- \r
UserModel getUserModel(String username);\r
\r
boolean updateUserModel(UserModel model);\r
\r
+ boolean updateUserModel(String username, UserModel model);\r
+ \r
boolean deleteUserModel(UserModel model);\r
\r
+ boolean deleteUser(String username);\r
+ \r
List<String> getAllUsernames();\r
\r
List<String> getUsernamesForRole(String role);\r
boolean renameRole(String oldRole, String newRole);\r
\r
boolean deleteRole(String role);\r
- \r
}\r
import org.slf4j.Logger;\r
import org.slf4j.LoggerFactory;\r
\r
-import com.gitblit.utils.StringUtils;\r
import com.gitblit.wicket.models.UserModel;\r
\r
public class JettyLoginService extends MappedLoginService implements ILoginService {\r
return null;\r
}\r
UserModel user = new UserModel(username);\r
- user.setCookie(StringUtils.getSHA1((Constants.NAME + username + new String(password))));\r
user.canAdmin(identity.isUserInRole(Constants.ADMIN_ROLE, null));\r
\r
// Add repositories\r
return user;\r
}\r
\r
- @Override\r
- public UserModel authenticate(char[] cookie) {\r
- // TODO cookie login\r
- return null;\r
- }\r
-\r
@Override\r
public UserModel getUserModel(String username) {\r
UserIdentity identity = _users.get(username);\r
\r
@Override\r
public boolean updateUserModel(UserModel model) {\r
+ return updateUserModel(model.getUsername(), model);\r
+ }\r
+ \r
+ @Override\r
+ public boolean updateUserModel(String username, UserModel model) {\r
try {\r
Properties allUsers = readRealmFile();\r
ArrayList<String> roles = new ArrayList<String>(model.getRepositories());\r
}\r
// trim trailing comma\r
sb.setLength(sb.length() - 1);\r
+ allUsers.remove(username);\r
allUsers.put(model.getUsername(), sb.toString());\r
\r
writeRealmFile(allUsers);\r
\r
// Update login service\r
+ removeUser(username);\r
putUser(model.getUsername(), Credential.getCredential(model.getPassword()), roles.toArray(new String[0]));\r
return true;\r
} catch (Throwable t) {\r
\r
@Override\r
public boolean deleteUserModel(UserModel model) {\r
+ return deleteUser(model.getUsername());\r
+ }\r
+\r
+ @Override\r
+ public boolean deleteUser(String username) {\r
try {\r
// Read realm file\r
Properties allUsers = readRealmFile();\r
- allUsers.remove(model.getUsername());\r
+ allUsers.remove(username);\r
writeRealmFile(allUsers);\r
\r
// Drop user from map\r
- _users.remove(model.getUsername());\r
+ removeUser(username);\r
return true;\r
} catch (Throwable t) {\r
- logger.error(MessageFormat.format("Failed to delete user model {0}!", model.getUsername()), t);\r
+ logger.error(MessageFormat.format("Failed to delete user {0}!", username), t);\r
}\r
return false;\r
}\r
-\r
+ \r
@Override\r
public List<String> getAllUsernames() {\r
List<String> list = new ArrayList<String>();\r
\r
// persist changes\r
writeRealmFile(allUsers);\r
+ return true;\r
} catch (Throwable t) {\r
logger.error(MessageFormat.format("Failed to delete role {0}!", role), t);\r
}\r
}\r
\r
public static String flattenStrings(List<String> values) {\r
+ return flattenStrings(values, " ");\r
+ }\r
+\r
+ public static String flattenStrings(List<String> values, String separator) {\r
StringBuilder sb = new StringBuilder();\r
for (String value : values) {\r
- sb.append(value).append(" ");\r
+ sb.append(value).append(separator);\r
}\r
return sb.toString().trim();\r
}\r
package com.gitblit.wicket;\r
\r
-import javax.servlet.http.Cookie;\r
-\r
import org.apache.wicket.PageParameters;\r
import org.apache.wicket.markup.html.WebPage;\r
import org.apache.wicket.markup.html.basic.Label;\r
import org.apache.wicket.markup.html.panel.FeedbackPanel;\r
import org.apache.wicket.model.IModel;\r
import org.apache.wicket.model.Model;\r
-import org.apache.wicket.protocol.http.WebRequest;\r
-import org.apache.wicket.protocol.http.WebResponse;\r
\r
import com.gitblit.Constants;\r
import com.gitblit.GitBlit;\r
public LoginPage(PageParameters params) {\r
super(params);\r
\r
- tryAutomaticLogin();\r
-\r
add(new Label("title", GitBlit.self().settings().getString(Keys.web.siteName, Constants.NAME)));\r
add(new Label("name", Constants.NAME));\r
\r
setRedirect(true);\r
setResponsePage(getApplication().getHomePage());\r
}\r
- \r
- tryAutomaticLogin();\r
}\r
\r
@Override\r
loginUser(user);\r
}\r
}\r
-\r
- private void tryAutomaticLogin() {\r
- UserModel user = null;\r
-\r
- // Grab cookie from Browser Session\r
- Cookie[] cookies = ((WebRequest) getRequestCycle().getRequest()).getCookies();\r
- if (cookies != null && cookies.length > 0) {\r
- user = GitBlit.self().authenticate(cookies);\r
- }\r
-\r
- // Login the user\r
- loginUser(user);\r
- }\r
-\r
+ \r
private void loginUser(UserModel user) {\r
if (user != null) {\r
// Set the user into the session\r
GitBlitWebSession.get().setUser(user);\r
\r
- // Set Cookie\r
- WebResponse response = (WebResponse) getRequestCycle().getResponse();\r
- GitBlit.self().setCookie(response, user);\r
-\r
if (!continueToOriginalDestination()) {\r
// Redirect to home page\r
setResponsePage(getApplication().getHomePage());\r
import com.gitblit.wicket.models.RepositoryModel;\r
import com.gitblit.wicket.pages.BranchesPage;\r
import com.gitblit.wicket.pages.DocsPage;\r
+import com.gitblit.wicket.pages.EditRepositoryPage;\r
import com.gitblit.wicket.pages.LogPage;\r
import com.gitblit.wicket.pages.SearchPage;\r
import com.gitblit.wicket.pages.SummaryPage;\r
put("tags", "gb.tags");\r
put("tree", "gb.tree");\r
put("tickets", "gb.tickets");\r
+ put("edit", "gb.edit");\r
}\r
};\r
\r
// per-repository extra page links\r
List<String> extraPageLinks = new ArrayList<String>();\r
\r
- // Conditionally add tickets page\r
+ // Conditionally add tickets link\r
if (model.useTickets && JGitUtils.getTicketsBranch(r) != null) {\r
extraPageLinks.add("tickets");\r
}\r
\r
- // Conditionally add docs page\r
+ // Conditionally add docs link\r
if (model.useDocs) {\r
extraPageLinks.add("docs");\r
}\r
\r
+ final boolean showAdmin;\r
+ if (GitBlit.self().settings().getBoolean(Keys.web.authenticateAdminPages, true)) {\r
+ boolean allowAdmin = GitBlit.self().settings().getBoolean(Keys.web.allowAdministration, false);\r
+ showAdmin = allowAdmin && GitBlitWebSession.get().canAdmin();\r
+ } else {\r
+ showAdmin = GitBlit.self().settings().getBoolean(Keys.web.allowAdministration, false);\r
+ }\r
+ \r
+ // Conditionally add edit link\r
+ if (showAdmin || GitBlitWebSession.get().isLoggedIn() && (model.owner != null && model.owner.equalsIgnoreCase(GitBlitWebSession.get().getUser().getUsername()))) {\r
+ extraPageLinks.add("edit");\r
+ }\r
+\r
ListDataProvider<String> extrasDp = new ListDataProvider<String>(extraPageLinks);\r
DataView<String> extrasView = new DataView<String>("extra", extrasDp) {\r
private static final long serialVersionUID = 1L;\r
} else if (extra.equals("docs")) {\r
item.add(new Label("extraSeparator", " | "));\r
item.add(new LinkPanel("extraLink", null, getString("gb.docs"), DocsPage.class, WicketUtils.newRepositoryParameter(repositoryName)));\r
+ } else if (extra.equals("edit")) {\r
+ item.add(new Label("extraSeparator", " | "));\r
+ item.add(new LinkPanel("extraLink", null, getString("gb.edit"), EditRepositoryPage.class, WicketUtils.newRepositoryParameter(repositoryName)));\r
}\r
}\r
};\r
this.owner = owner;\r
this.lastChange = lastchange;\r
this.accessRestriction = AccessRestrictionType.NONE;\r
- } \r
+ }\r
+ \r
+ @Override\r
+ public String toString() {\r
+ return name;\r
+ }\r
}
\ No newline at end of file
\r
private String username;\r
private String password;\r
- private String cookie;\r
private boolean canAdmin = false;\r
private List<String> repositories = new ArrayList<String>();\r
\r
return canAdmin || repositories.contains(repositoryName);\r
}\r
\r
- public void setCookie(String cookie) {\r
- this.cookie = cookie;\r
- }\r
-\r
- public String getCookie() {\r
- return cookie;\r
- }\r
-\r
public void setRepositories(List<String> repositories) {\r
this.repositories.clear();\r
this.repositories.addAll(repositories);\r
return repositories;\r
}\r
\r
+ @Override\r
public String toString() {\r
return username;\r
}\r
\r
private final boolean isCreate;\r
\r
+ private boolean isAdmin = false;\r
+ \r
public EditRepositoryPage() {\r
// create constructor\r
super();\r
}\r
}\r
\r
+ final String oldName = repositoryModel.name;\r
final Palette<String> usersPalette = new Palette<String>("users", new ListModel<String>(repositoryUsers), new CollectionModel<String>(GitBlit.self().getAllUsernames()), new ChoiceRenderer<String>("", ""), 10, false);\r
CompoundPropertyModel<RepositoryModel> model = new CompoundPropertyModel<RepositoryModel>(repositoryModel);\r
Form<RepositoryModel> form = new Form<RepositoryModel>("editForm", model) {\r
ok |= c == vc;\r
}\r
if (!ok) {\r
- error(MessageFormat.format("Illegal character '{0}' in repository name!", c));\r
+ error(MessageFormat.format("Illegal character ''{0}'' in repository name!", c));\r
return;\r
}\r
}\r
}\r
\r
// save the repository\r
- GitBlit.self().editRepositoryModel(repositoryModel, isCreate);\r
+ GitBlit.self().editRepositoryModel(oldName, repositoryModel, isCreate);\r
\r
// save the repository access list\r
if (repositoryModel.accessRestriction.exceeds(AccessRestrictionType.NONE)) {\r
repositoryUsers.add(users.next());\r
}\r
// ensure the owner is added to the user list\r
- if (!repositoryUsers.contains(repositoryModel.owner)) {\r
+ if (repositoryModel.owner != null && !repositoryUsers.contains(repositoryModel.owner)) {\r
repositoryUsers.add(repositoryModel.owner);\r
}\r
GitBlit.self().setRepositoryUsers(repositoryModel, repositoryUsers);\r
};\r
\r
// field names reflective match RepositoryModel fields\r
- form.add(new TextField<String>("name").setEnabled(isCreate));\r
+ form.add(new TextField<String>("name").setEnabled(isCreate || isAdmin));\r
form.add(new TextField<String>("description"));\r
form.add(new DropDownChoice<String>("owner", GitBlit.self().getAllUsernames()).setEnabled(GitBlitWebSession.get().canAdmin()));\r
form.add(new DropDownChoice<AccessRestrictionType>("accessRestriction", Arrays.asList(AccessRestrictionType.values()), new AccessRestrictionRenderer()));\r
// Edit Repository\r
if (user.canAdmin()) {\r
// Admins can edit everything\r
+ isAdmin = true;\r
return;\r
} else {\r
if (!model.owner.equalsIgnoreCase(user.getUsername())) {\r
repos.add(repo);\r
}\r
}\r
+ final String oldName = userModel.getUsername();\r
final Palette<String> repositories = new Palette<String>("repositories", new ListModel<String>(userModel.getRepositories()), new CollectionModel<String>(repos), new ChoiceRenderer<String>("", ""), 10, false);\r
Form<UserModel> form = new Form<UserModel>("editForm", model) {\r
\r
if (isCreate) {\r
UserModel model = GitBlit.self().getUserModel(username);\r
if (model != null) {\r
- error(MessageFormat.format("Username {0} is unavailable.", username));\r
+ error(MessageFormat.format("Username ''{0}'' is unavailable.", username));\r
return;\r
}\r
}\r
return;\r
}\r
\r
- // Optionally encrypt/obfuscate the password.\r
+ // Optionally store the password MD5 digest.\r
String type = GitBlit.self().settings().getString(Keys.realm.passwordStorage, "md5");\r
if (type.equalsIgnoreCase("md5")) {\r
- // store MD5 checksum of password\r
+ // store MD5 digest of password\r
userModel.setPassword(MD5.digest(userModel.getPassword()));\r
- } else if (type.equalsIgnoreCase("crypt")) {\r
- // simple unix encryption\r
- userModel.setPassword(Crypt.crypt(userModel.getUsername(), userModel.getPassword()));\r
}\r
}\r
\r
}\r
userModel.setRepositories(repos);\r
try {\r
- GitBlit.self().editUserModel(userModel, isCreate);\r
+ GitBlit.self().editUserModel(oldName, userModel, isCreate);\r
} catch (GitBlitException e) {\r
error(e.getMessage());\r
return;\r
setRedirect(false);\r
if (isCreate) {\r
// create another user\r
- info(MessageFormat.format("New user {0} successfully created.", userModel.getUsername()));\r
+ info(MessageFormat.format("New user ''{0}'' successfully created.", userModel.getUsername()));\r
setResponsePage(EditUserPage.class);\r
} else {\r
// back to home\r
};\r
\r
// field names reflective match UserModel fields\r
- form.add(new TextField<String>("username").setEnabled(isCreate));\r
+ form.add(new TextField<String>("username"));\r
PasswordTextField passwordField = new PasswordTextField("password");\r
passwordField.setResetPassword(false);\r
form.add(passwordField);\r
String cachedMessage = GitBlitWebSession.get().clearErrorMessage();\r
if (!StringUtils.isEmpty(cachedMessage)) {\r
error(cachedMessage);\r
- System.out.println("displayed message");\r
}\r
\r
// Load the markdown welcome message\r
<tr><th><wicket:message key="gb.owner">[owner]</wicket:message></th><td><span wicket:id="repositoryOwner">[repository owner]</span></td></tr>\r
<tr><th><wicket:message key="gb.lastChange">[last change]</wicket:message></th><td><span wicket:id="repositoryLastChange">[repository last change]</span></td></tr>\r
<tr><th><wicket:message key="gb.stats">[stats]</wicket:message></th><td><span wicket:id="repositoryStats">[repository stats]</span></td></tr>\r
- <tr><th><wicket:message key="gb.url">[URL]</wicket:message></th><td><img style="vertical-align: top; padding-right:5px;" wicket:id="accessRestrictionIcon" /><span wicket:id="repositoryCloneUrl">[repository clone url]</span></td></tr>\r
+ <tr><th valign="top"><wicket:message key="gb.url">[URL]</wicket:message></th><td><img style="vertical-align: top; padding-right:5px;" wicket:id="accessRestrictionIcon" /><span wicket:id="repositoryCloneUrl">[repository clone url]</span></td></tr>\r
</table>\r
</div>\r
</div>\r
import java.awt.Color;\r
import java.awt.Dimension;\r
import java.text.MessageFormat;\r
+import java.util.ArrayList;\r
import java.util.List;\r
\r
+import javax.servlet.http.HttpServletRequest;\r
+\r
import org.apache.wicket.PageParameters;\r
import org.apache.wicket.markup.html.basic.Label;\r
+import org.apache.wicket.protocol.http.WebRequest;\r
import org.eclipse.jgit.lib.Repository;\r
import org.wicketstuff.googlecharts.AbstractChartData;\r
import org.wicketstuff.googlecharts.Chart;\r
import org.wicketstuff.googlecharts.MarkerType;\r
import org.wicketstuff.googlecharts.ShapeMarker;\r
\r
+import com.gitblit.Constants;\r
import com.gitblit.Constants.AccessRestrictionType;\r
import com.gitblit.GitBlit;\r
import com.gitblit.Keys;\r
import com.gitblit.utils.JGitUtils;\r
+import com.gitblit.utils.StringUtils;\r
import com.gitblit.utils.TimeUtils;\r
import com.gitblit.wicket.RepositoryPage;\r
import com.gitblit.wicket.WicketUtils;\r
} else {\r
add(new Label("repositoryStats", MessageFormat.format("{0} commits and {1} tags in {2}", metricsTotal.count, metricsTotal.tag, TimeUtils.duration(metricsTotal.duration))));\r
}\r
- \r
- AccessRestrictionType accessRestriction = getRepositoryModel().accessRestriction;\r
- switch (accessRestriction) {\r
- case NONE:\r
- add(WicketUtils.newClearPixel("accessRestrictionIcon").setVisible(false));\r
- break;\r
- case PUSH:\r
- add(WicketUtils.newImage("accessRestrictionIcon", "lock_go_16x16.png", getAccessRestrictions().get(accessRestriction)));\r
- break;\r
- case CLONE:\r
- add(WicketUtils.newImage("accessRestrictionIcon", "lock_pull_16x16.png", getAccessRestrictions().get(accessRestriction)));\r
- break;\r
- case VIEW:\r
- add(WicketUtils.newImage("accessRestrictionIcon", "shield_16x16.png", getAccessRestrictions().get(accessRestriction)));\r
- break;\r
- default:\r
+\r
+ List<String> repositoryUrls = new ArrayList<String>();\r
+\r
+ if (GitBlit.self().settings().getBoolean(Keys.git.enableGitServlet, true)) {\r
+ AccessRestrictionType accessRestriction = getRepositoryModel().accessRestriction;\r
+ switch (accessRestriction) {\r
+ case NONE:\r
+ add(WicketUtils.newClearPixel("accessRestrictionIcon").setVisible(false));\r
+ break;\r
+ case PUSH:\r
+ add(WicketUtils.newImage("accessRestrictionIcon", "lock_go_16x16.png", getAccessRestrictions().get(accessRestriction)));\r
+ break;\r
+ case CLONE:\r
+ add(WicketUtils.newImage("accessRestrictionIcon", "lock_pull_16x16.png", getAccessRestrictions().get(accessRestriction)));\r
+ break;\r
+ case VIEW:\r
+ add(WicketUtils.newImage("accessRestrictionIcon", "shield_16x16.png", getAccessRestrictions().get(accessRestriction)));\r
+ break;\r
+ default:\r
+ add(WicketUtils.newClearPixel("accessRestrictionIcon").setVisible(false));\r
+ }\r
+\r
+ HttpServletRequest req = ((WebRequest) getRequestCycle().getRequest()).getHttpServletRequest();\r
+ StringBuilder sb = new StringBuilder();\r
+ sb.append(req.getScheme());\r
+ sb.append("://");\r
+ sb.append(req.getServerName());\r
+ if ((req.getScheme().equals("http") && req.getServerPort() != 80) || (req.getScheme().equals("https") && req.getServerPort() != 443)) {\r
+ sb.append(":" + req.getServerPort());\r
+ }\r
+ sb.append(Constants.GIT_SERVLET_PATH);\r
+ sb.append(repositoryName);\r
+ repositoryUrls.add(sb.toString());\r
+ } else {\r
add(WicketUtils.newClearPixel("accessRestrictionIcon").setVisible(false));\r
}\r
- add(new Label("repositoryCloneUrl", GitBlit.self().getCloneUrl(repositoryName)));\r
+ repositoryUrls.addAll(GitBlit.self().getOtherCloneUrls(repositoryName));\r
+\r
+ add(new Label("repositoryCloneUrl", StringUtils.flattenStrings(repositoryUrls, "<br/>")).setEscapeModelStrings(false));\r
\r
add(new LogPanel("commitsPanel", repositoryName, null, r, numberCommits, 0));\r
add(new TagsPanel("tagsPanel", repositoryName, r, numberRefs));\r
commitAxis.setLabels(new String[] { "", String.valueOf((int) maxValue(metrics)) });\r
provider.addAxis(commitAxis);\r
\r
- provider.setLineStyles(new LineStyle[] {new LineStyle(2, 4, 0), new LineStyle(0, 4, 1)}); \r
+ provider.setLineStyles(new LineStyle[] { new LineStyle(2, 4, 0), new LineStyle(0, 4, 1) });\r
provider.addShapeMarker(new ShapeMarker(MarkerType.CIRCLE, Color.BLUE, 1, -1, 5));\r
- \r
+\r
add(new Chart("commitsChart", provider));\r
} else {\r
add(WicketUtils.newBlankImage("commitsChart"));\r
\r
import java.util.TimeZone;\r
\r
+import org.apache.wicket.AttributeModifier;\r
import org.apache.wicket.Component;\r
import org.apache.wicket.markup.html.panel.Panel;\r
+import org.apache.wicket.model.Model;\r
\r
import com.gitblit.GitBlit;\r
import com.gitblit.Keys;\r
WicketUtils.setHtmlTooltip(component, getString("gb.searchForCommitter") + " " + value);\r
}\r
}\r
+\r
+ public class JavascriptEventConfirmation extends AttributeModifier {\r
+\r
+ private static final long serialVersionUID = 1L;\r
+\r
+ public JavascriptEventConfirmation(String event, String msg) {\r
+ super(event, true, new Model<String>(msg));\r
+ }\r
+\r
+ protected String newValue(final String currentValue, final String replacementValue) {\r
+ String prefix = "var conf = confirm('" + replacementValue + "'); " + "if (!conf) return false; ";\r
+ String result = prefix;\r
+ if (currentValue != null) {\r
+ result = prefix + currentValue;\r
+ }\r
+ return result;\r
+ }\r
+ }\r
}\r
</wicket:fragment>\r
\r
<wicket:fragment wicket:id="repositoryAdminLinks">\r
- <span class="link"><a wicket:id="editRepository"><wicket:message key="gb.edit">[edit]</wicket:message></a> | <a wicket:id="renameRepository"><wicket:message key="gb.rename">[rename]</wicket:message></a> | <a wicket:id="deleteRepository"><wicket:message key="gb.delete">[delete]</wicket:message></a></span>\r
+ <span class="link"><a wicket:id="editRepository"><wicket:message key="gb.edit">[edit]</wicket:message></a> | <a wicket:id="deleteRepository"><wicket:message key="gb.delete">[delete]</wicket:message></a></span>\r
</wicket:fragment>\r
\r
<wicket:fragment wicket:id="repositoryOwnerLinks">\r
package com.gitblit.wicket.panels;\r
\r
+import java.text.MessageFormat;\r
import java.util.ArrayList;\r
import java.util.Collections;\r
import java.util.Comparator;\r
import org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvider;\r
import org.apache.wicket.markup.html.basic.Label;\r
import org.apache.wicket.markup.html.link.BookmarkablePageLink;\r
+import org.apache.wicket.markup.html.link.Link;\r
import org.apache.wicket.markup.html.panel.Fragment;\r
import org.apache.wicket.markup.repeater.Item;\r
import org.apache.wicket.markup.repeater.data.DataView;\r
import com.gitblit.wicket.pages.EditRepositoryPage;\r
import com.gitblit.wicket.pages.SummaryPage;\r
\r
-\r
public class RepositoriesPanel extends BasePanel {\r
\r
private static final long serialVersionUID = 1L;\r
- \r
+\r
public RepositoriesPanel(String wicketId, final boolean showAdmin, final Map<AccessRestrictionType, String> accessRestrictionTranslations) {\r
super(wicketId);\r
- \r
+\r
final UserModel user = GitBlitWebSession.get().getUser();\r
List<RepositoryModel> models = GitBlit.self().getRepositoryModels(user);\r
- IDataProvider<RepositoryModel> dp;\r
- \r
+ final IDataProvider<RepositoryModel> dp;\r
+\r
Fragment adminLinks = new Fragment("adminPanel", "adminLinks", this);\r
adminLinks.add(new BookmarkablePageLink<Void>("newRepository", EditRepositoryPage.class));\r
add(adminLinks.setVisible(showAdmin));\r
- \r
+\r
if (GitBlit.self().settings().getString(Keys.web.repositoryListType, "flat").equalsIgnoreCase("grouped")) {\r
Map<String, List<RepositoryModel>> groups = new HashMap<String, List<RepositoryModel>>();\r
for (RepositoryModel model : models) {\r
List<RepositoryModel> groupedModels = new ArrayList<RepositoryModel>();\r
for (String root : roots) {\r
List<RepositoryModel> subModels = groups.get(root);\r
- groupedModels.add(new GroupRepositoryModel(root + " (" + subModels.size() + ")"));\r
+ groupedModels.add(new GroupRepositoryModel(root, subModels.size()));\r
groupedModels.addAll(subModels);\r
}\r
- dp = new ListDataProvider<RepositoryModel>(groupedModels);\r
+ dp = new RepositoriesProvider(groupedModels);\r
} else {\r
- dp = new DataProvider(models);\r
+ dp = new SortableRepositoriesProvider(models);\r
}\r
\r
DataView<RepositoryModel> dataView = new DataView<RepositoryModel>("row", dp) {\r
private static final long serialVersionUID = 1L;\r
int counter = 0;\r
\r
+ @Override\r
+ protected void onBeforeRender() {\r
+ super.onBeforeRender();\r
+ counter = 0;\r
+ }\r
+\r
public void populateItem(final Item<RepositoryModel> item) {\r
final RepositoryModel entry = item.getModelObject();\r
if (entry instanceof GroupRepositoryModel) {\r
Fragment row = new Fragment("rowContent", "groupRepositoryRow", this);\r
item.add(row);\r
- row.add(new Label("groupName", entry.name));\r
+ row.add(new Label("groupName", entry.toString()));\r
WicketUtils.setCssClass(item, "group");\r
return;\r
}\r
row.add(lastChangeLabel);\r
WicketUtils.setCssClass(lastChangeLabel, TimeUtils.timeAgoCss(entry.lastChange));\r
\r
- boolean showOwner = user != null && user.getUsername().equalsIgnoreCase(entry.owner); \r
+ boolean showOwner = user != null && user.getUsername().equalsIgnoreCase(entry.owner);\r
if (showAdmin) {\r
Fragment repositoryLinks = new Fragment("repositoryLinks", "repositoryAdminLinks", this);\r
repositoryLinks.add(new BookmarkablePageLink<Void>("editRepository", EditRepositoryPage.class, WicketUtils.newRepositoryParameter(entry.name)));\r
- repositoryLinks.add(new BookmarkablePageLink<Void>("renameRepository", EditRepositoryPage.class, WicketUtils.newRepositoryParameter(entry.name)).setEnabled(false));\r
- repositoryLinks.add(new BookmarkablePageLink<Void>("deleteRepository", EditRepositoryPage.class, WicketUtils.newRepositoryParameter(entry.name)).setEnabled(false));\r
+ Link<Void> deleteLink = new Link<Void>("deleteRepository") {\r
+\r
+ private static final long serialVersionUID = 1L;\r
+\r
+ @Override\r
+ public void onClick() {\r
+ if (GitBlit.self().deleteRepositoryModel(entry)) {\r
+ info(MessageFormat.format("Repository ''{0}'' deleted.", entry));\r
+ if (dp instanceof SortableRepositoriesProvider) {\r
+ ((SortableRepositoriesProvider) dp).remove(entry);\r
+ } else {\r
+ ((RepositoriesProvider) dp).remove(entry);\r
+ }\r
+ } else {\r
+ error(MessageFormat.format("Failed to delete repository ''{0}''!", entry));\r
+ }\r
+ }\r
+ };\r
+ deleteLink.add(new JavascriptEventConfirmation("onclick", MessageFormat.format("Delete repository \"{0}\"?", entry)));\r
+ repositoryLinks.add(deleteLink);\r
row.add(repositoryLinks);\r
} else if (showOwner) {\r
Fragment repositoryLinks = new Fragment("repositoryLinks", "repositoryOwnerLinks", this);\r
add(fragment);\r
}\r
}\r
- \r
+\r
private class GroupRepositoryModel extends RepositoryModel {\r
\r
private static final long serialVersionUID = 1L;\r
\r
- GroupRepositoryModel(String name) {\r
+ int count = 0;\r
+\r
+ GroupRepositoryModel(String name, int count) {\r
super(name, "", "", new Date(0));\r
+ this.count = count;\r
+ }\r
+\r
+ @Override\r
+ public String toString() {\r
+ return name + " (" + count + ")";\r
}\r
}\r
- \r
+\r
protected enum SortBy {\r
repository, description, owner, date;\r
}\r
};\r
}\r
\r
- private class DataProvider extends SortableDataProvider<RepositoryModel> {\r
+ private class RepositoriesProvider extends ListDataProvider<RepositoryModel> {\r
+\r
+ private static final long serialVersionUID = 1L;\r
+\r
+ public RepositoriesProvider(List<RepositoryModel> list) {\r
+ super(list);\r
+ }\r
+\r
+ @Override\r
+ public List<RepositoryModel> getData() {\r
+ return super.getData();\r
+ }\r
+\r
+ public void remove(RepositoryModel model) {\r
+ int index = getData().indexOf(model);\r
+ RepositoryModel groupModel = null;\r
+ if (index == (getData().size() - 1)) {\r
+ // last element\r
+ if (index > 0) {\r
+ // previous element is group header, then this is last\r
+ // repository in group. remove group too.\r
+ if (getData().get(index - 1) instanceof GroupRepositoryModel) {\r
+ groupModel = getData().get(index - 1);\r
+ }\r
+ }\r
+ } else if (index < (getData().size() - 1)) {\r
+ // not last element. check next element for group match.\r
+ if (getData().get(index - 1) instanceof GroupRepositoryModel && getData().get(index + 1) instanceof GroupRepositoryModel) {\r
+ // repository is sandwiched by group headers so this\r
+ // repository is the only element in the group. remove\r
+ // group.\r
+ groupModel = getData().get(index - 1);\r
+ }\r
+ }\r
+\r
+ if (groupModel == null) {\r
+ // Find the group and decrement the count\r
+ for (int i = index; i >= 0; i--) {\r
+ if (getData().get(i) instanceof GroupRepositoryModel) {\r
+ ((GroupRepositoryModel) getData().get(i)).count--;\r
+ break;\r
+ }\r
+ }\r
+ } else {\r
+ // Remove the group header\r
+ getData().remove(groupModel);\r
+ }\r
+\r
+ getData().remove(model);\r
+ }\r
+ }\r
+\r
+ private class SortableRepositoriesProvider extends SortableDataProvider<RepositoryModel> {\r
private static final long serialVersionUID = 1L;\r
private List<RepositoryModel> list = null;\r
\r
- protected DataProvider(List<RepositoryModel> list) {\r
+ protected SortableRepositoriesProvider(List<RepositoryModel> list) {\r
this.list = list;\r
setSort(SortBy.date.name(), false);\r
}\r
\r
+ public void remove(RepositoryModel model) {\r
+ list.remove(model);\r
+ }\r
+\r
@Override\r
public int size() {\r
if (list == null)\r
package com.gitblit.wicket.panels;\r
\r
+import java.text.MessageFormat;\r
+import java.util.List;\r
+\r
import org.apache.wicket.markup.html.link.BookmarkablePageLink;\r
+import org.apache.wicket.markup.html.link.Link;\r
import org.apache.wicket.markup.html.panel.Fragment;\r
import org.apache.wicket.markup.repeater.Item;\r
import org.apache.wicket.markup.repeater.data.DataView;\r
import com.gitblit.wicket.LinkPanel;\r
import com.gitblit.wicket.WicketUtils;\r
import com.gitblit.wicket.pages.EditUserPage;\r
-import com.gitblit.wicket.pages.RepositoriesPage;\r
\r
public class UsersPanel extends BasePanel {\r
\r
Fragment adminLinks = new Fragment("adminPanel", "adminLinks", this);\r
adminLinks.add(new BookmarkablePageLink<Void>("newUser", EditUserPage.class));\r
add(adminLinks.setVisible(showAdmin));\r
- \r
- DataView<String> usersView = new DataView<String>("userRow", new ListDataProvider<String>(GitBlit.self().getAllUsernames())) {\r
+\r
+ final List<String> usernames = GitBlit.self().getAllUsernames();\r
+ DataView<String> usersView = new DataView<String>("userRow", new ListDataProvider<String>(usernames)) {\r
private static final long serialVersionUID = 1L;\r
private int counter = 0;\r
+ \r
+ @Override\r
+ protected void onBeforeRender() {\r
+ super.onBeforeRender();\r
+ counter = 0;\r
+ }\r
\r
public void populateItem(final Item<String> item) {\r
final String entry = item.getModelObject();\r
item.add(editLink);\r
Fragment userLinks = new Fragment("userLinks", "userAdminLinks", this);\r
userLinks.add(new BookmarkablePageLink<Void>("editUser", EditUserPage.class, WicketUtils.newUsernameParameter(entry)));\r
- userLinks.add(new BookmarkablePageLink<Void>("deleteUser", RepositoriesPage.class, WicketUtils.newUsernameParameter(entry)).setEnabled(false));\r
+ Link<Void> deleteLink = new Link<Void>("deleteUser") {\r
+\r
+ private static final long serialVersionUID = 1L;\r
+\r
+ @Override\r
+ public void onClick() {\r
+ if (GitBlit.self().deleteUser(entry)) {\r
+ usernames.remove(entry);\r
+ info(MessageFormat.format("User ''{0}'' deleted.", entry));\r
+ } else {\r
+ error(MessageFormat.format("Failed to delete user ''{0}''!", entry));\r
+ }\r
+ }\r
+ };\r
+ deleteLink.add(new JavascriptEventConfirmation("onclick", MessageFormat.format("Delete user \"{0}\"?", entry)));\r
+ userLinks.add(deleteLink);\r
item.add(userLinks);\r
\r
WicketUtils.setAlternatingBackground(item, counter);\r