# e.g. /libraries/mylibrary.git | # e.g. /libraries/mylibrary.git | ||||
git.nestedRepositories = true | 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 | # Authentication Settings | ||||
realm.realmFile = users.properties | realm.realmFile = users.properties | ||||
# How to store passwords. | # 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 | realm.passwordStorage = md5 | ||||
# Minimum valid length for a plain text password. | # Minimum valid length for a plain text password. |
import javax.servlet.ServletContextEvent; | import javax.servlet.ServletContextEvent; | ||||
import javax.servlet.ServletContextListener; | 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.errors.RepositoryNotFoundException; | ||||
import org.eclipse.jgit.lib.Repository; | import org.eclipse.jgit.lib.Repository; | ||||
import org.eclipse.jgit.lib.StoredConfig; | import org.eclipse.jgit.lib.StoredConfig; | ||||
import org.eclipse.jgit.transport.resolver.FileResolver; | import org.eclipse.jgit.transport.resolver.FileResolver; | ||||
import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; | import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; | ||||
import org.eclipse.jgit.util.FileUtils; | |||||
import org.slf4j.Logger; | import org.slf4j.Logger; | ||||
import org.slf4j.LoggerFactory; | import org.slf4j.LoggerFactory; | ||||
return storedSettings.getBoolean(Keys.web.debugMode, false); | return storedSettings.getBoolean(Keys.web.debugMode, false); | ||||
} | } | ||||
public String getCloneUrl(String repositoryName) { | |||||
return storedSettings.getString(Keys.git.cloneUrl, "https://localhost/git/") + repositoryName; | |||||
public List<String> getOtherCloneUrls(String repositoryName) { | |||||
List<String> cloneUrls = new ArrayList<String>(); | |||||
for (String url : storedSettings.getStrings(Keys.git.otherUrls)) { | |||||
cloneUrls.add(MessageFormat.format(url, repositoryName)); | |||||
} | |||||
return cloneUrls; | |||||
} | } | ||||
public void setLoginService(ILoginService loginService) { | public void setLoginService(ILoginService loginService) { | ||||
return loginService.authenticate(username, password); | 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<String> getAllUsernames() { | public List<String> getAllUsernames() { | ||||
List<String> names = loginService.getAllUsernames(); | |||||
List<String> names = new ArrayList<String>(loginService.getAllUsernames()); | |||||
Collections.sort(names); | Collections.sort(names); | ||||
return names; | return names; | ||||
} | } | ||||
public boolean deleteUser(String username) { | |||||
return loginService.deleteUser(username); | |||||
} | |||||
public UserModel getUserModel(String username) { | public UserModel getUserModel(String username) { | ||||
UserModel user = loginService.getUserModel(username); | UserModel user = loginService.getUserModel(username); | ||||
return user; | return user; | ||||
} | } | ||||
public List<String> getRepositoryUsers(RepositoryModel repository) { | public List<String> getRepositoryUsers(RepositoryModel repository) { | ||||
return loginService.getUsernamesForRole(repository.name); | return loginService.getUsernamesForRole(repository.name); | ||||
} | } | ||||
public boolean setRepositoryUsers(RepositoryModel repository, List<String> repositoryUsers) { | public boolean setRepositoryUsers(RepositoryModel repository, List<String> repositoryUsers) { | ||||
return loginService.setUsernamesForRole(repository.name, 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!"); | throw new GitBlitException(isCreate ? "Failed to add user!" : "Failed to update user!"); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
return repositories; | return repositories; | ||||
} | } | ||||
public RepositoryModel getRepositoryModel(UserModel user, String repositoryName) { | public RepositoryModel getRepositoryModel(UserModel user, String repositoryName) { | ||||
RepositoryModel model = getRepositoryModel(repositoryName); | RepositoryModel model = getRepositoryModel(repositoryName); | ||||
if (model.accessRestriction.atLeast(AccessRestrictionType.VIEW)) { | if (model.accessRestriction.atLeast(AccessRestrictionType.VIEW)) { | ||||
r.close(); | r.close(); | ||||
return model; | return model; | ||||
} | } | ||||
private String getConfig(StoredConfig config, String field, String defaultValue) { | private String getConfig(StoredConfig config, String field, String defaultValue) { | ||||
String value = config.getString("gitblit", null, field); | String value = config.getString("gitblit", null, field); | ||||
if (StringUtils.isEmpty(value)) { | if (StringUtils.isEmpty(value)) { | ||||
} | } | ||||
return value; | return value; | ||||
} | } | ||||
private boolean getConfig(StoredConfig config, String field, boolean defaultValue) { | private boolean getConfig(StoredConfig config, String field, boolean defaultValue) { | ||||
return config.getBoolean("gitblit", field, 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; | Repository r = null; | ||||
if (isCreate) { | if (isCreate) { | ||||
if (new File(repositoriesFolder, repository.name).exists()) { | 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 | // create repository | ||||
logger.info("create repository " + repository.name); | logger.info("create repository " + repository.name); | ||||
r = JGitUtils.createRepository(repositoriesFolder, repository.name, true); | r = JGitUtils.createRepository(repositoriesFolder, repository.name, true); | ||||
} else { | } 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 | // load repository | ||||
logger.info("edit repository " + repository.name); | logger.info("edit repository " + repository.name); | ||||
try { | try { | ||||
r.close(); | 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) { | public void configureContext(IStoredSettings settings) { | ||||
logger.info("Using configuration from " + settings.toString()); | logger.info("Using configuration from " + settings.toString()); | ||||
this.storedSettings = settings; | this.storedSettings = settings; |
UserModel authenticate(String username, char[] password); | UserModel authenticate(String username, char[] password); | ||||
UserModel authenticate(char[] cookie); | |||||
UserModel getUserModel(String username); | UserModel getUserModel(String username); | ||||
boolean updateUserModel(UserModel model); | boolean updateUserModel(UserModel model); | ||||
boolean updateUserModel(String username, UserModel model); | |||||
boolean deleteUserModel(UserModel model); | boolean deleteUserModel(UserModel model); | ||||
boolean deleteUser(String username); | |||||
List<String> getAllUsernames(); | List<String> getAllUsernames(); | ||||
List<String> getUsernamesForRole(String role); | List<String> getUsernamesForRole(String role); | ||||
boolean renameRole(String oldRole, String newRole); | boolean renameRole(String oldRole, String newRole); | ||||
boolean deleteRole(String role); | boolean deleteRole(String role); | ||||
} | } |
import org.slf4j.Logger; | import org.slf4j.Logger; | ||||
import org.slf4j.LoggerFactory; | import org.slf4j.LoggerFactory; | ||||
import com.gitblit.utils.StringUtils; | |||||
import com.gitblit.wicket.models.UserModel; | import com.gitblit.wicket.models.UserModel; | ||||
public class JettyLoginService extends MappedLoginService implements ILoginService { | public class JettyLoginService extends MappedLoginService implements ILoginService { | ||||
return null; | return null; | ||||
} | } | ||||
UserModel user = new UserModel(username); | UserModel user = new UserModel(username); | ||||
user.setCookie(StringUtils.getSHA1((Constants.NAME + username + new String(password)))); | |||||
user.canAdmin(identity.isUserInRole(Constants.ADMIN_ROLE, null)); | user.canAdmin(identity.isUserInRole(Constants.ADMIN_ROLE, null)); | ||||
// Add repositories | // Add repositories | ||||
return user; | return user; | ||||
} | } | ||||
@Override | |||||
public UserModel authenticate(char[] cookie) { | |||||
// TODO cookie login | |||||
return null; | |||||
} | |||||
@Override | @Override | ||||
public UserModel getUserModel(String username) { | public UserModel getUserModel(String username) { | ||||
UserIdentity identity = _users.get(username); | UserIdentity identity = _users.get(username); | ||||
@Override | @Override | ||||
public boolean updateUserModel(UserModel model) { | public boolean updateUserModel(UserModel model) { | ||||
return updateUserModel(model.getUsername(), model); | |||||
} | |||||
@Override | |||||
public boolean updateUserModel(String username, UserModel model) { | |||||
try { | try { | ||||
Properties allUsers = readRealmFile(); | Properties allUsers = readRealmFile(); | ||||
ArrayList<String> roles = new ArrayList<String>(model.getRepositories()); | ArrayList<String> roles = new ArrayList<String>(model.getRepositories()); | ||||
} | } | ||||
// trim trailing comma | // trim trailing comma | ||||
sb.setLength(sb.length() - 1); | sb.setLength(sb.length() - 1); | ||||
allUsers.remove(username); | |||||
allUsers.put(model.getUsername(), sb.toString()); | allUsers.put(model.getUsername(), sb.toString()); | ||||
writeRealmFile(allUsers); | writeRealmFile(allUsers); | ||||
// Update login service | // Update login service | ||||
removeUser(username); | |||||
putUser(model.getUsername(), Credential.getCredential(model.getPassword()), roles.toArray(new String[0])); | putUser(model.getUsername(), Credential.getCredential(model.getPassword()), roles.toArray(new String[0])); | ||||
return true; | return true; | ||||
} catch (Throwable t) { | } catch (Throwable t) { | ||||
@Override | @Override | ||||
public boolean deleteUserModel(UserModel model) { | public boolean deleteUserModel(UserModel model) { | ||||
return deleteUser(model.getUsername()); | |||||
} | |||||
@Override | |||||
public boolean deleteUser(String username) { | |||||
try { | try { | ||||
// Read realm file | // Read realm file | ||||
Properties allUsers = readRealmFile(); | Properties allUsers = readRealmFile(); | ||||
allUsers.remove(model.getUsername()); | |||||
allUsers.remove(username); | |||||
writeRealmFile(allUsers); | writeRealmFile(allUsers); | ||||
// Drop user from map | // Drop user from map | ||||
_users.remove(model.getUsername()); | |||||
removeUser(username); | |||||
return true; | return true; | ||||
} catch (Throwable t) { | } 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; | return false; | ||||
} | } | ||||
@Override | @Override | ||||
public List<String> getAllUsernames() { | public List<String> getAllUsernames() { | ||||
List<String> list = new ArrayList<String>(); | List<String> list = new ArrayList<String>(); | ||||
// persist changes | // persist changes | ||||
writeRealmFile(allUsers); | writeRealmFile(allUsers); | ||||
return true; | |||||
} catch (Throwable t) { | } catch (Throwable t) { | ||||
logger.error(MessageFormat.format("Failed to delete role {0}!", role), t); | logger.error(MessageFormat.format("Failed to delete role {0}!", role), t); | ||||
} | } |
} | } | ||||
public static String flattenStrings(List<String> values) { | public static String flattenStrings(List<String> values) { | ||||
return flattenStrings(values, " "); | |||||
} | |||||
public static String flattenStrings(List<String> values, String separator) { | |||||
StringBuilder sb = new StringBuilder(); | StringBuilder sb = new StringBuilder(); | ||||
for (String value : values) { | for (String value : values) { | ||||
sb.append(value).append(" "); | |||||
sb.append(value).append(separator); | |||||
} | } | ||||
return sb.toString().trim(); | return sb.toString().trim(); | ||||
} | } |
package com.gitblit.wicket; | package com.gitblit.wicket; | ||||
import javax.servlet.http.Cookie; | |||||
import org.apache.wicket.PageParameters; | import org.apache.wicket.PageParameters; | ||||
import org.apache.wicket.markup.html.WebPage; | import org.apache.wicket.markup.html.WebPage; | ||||
import org.apache.wicket.markup.html.basic.Label; | import org.apache.wicket.markup.html.basic.Label; | ||||
import org.apache.wicket.markup.html.panel.FeedbackPanel; | import org.apache.wicket.markup.html.panel.FeedbackPanel; | ||||
import org.apache.wicket.model.IModel; | import org.apache.wicket.model.IModel; | ||||
import org.apache.wicket.model.Model; | 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.Constants; | ||||
import com.gitblit.GitBlit; | import com.gitblit.GitBlit; | ||||
public LoginPage(PageParameters params) { | public LoginPage(PageParameters params) { | ||||
super(params); | super(params); | ||||
tryAutomaticLogin(); | |||||
add(new Label("title", GitBlit.self().settings().getString(Keys.web.siteName, Constants.NAME))); | add(new Label("title", GitBlit.self().settings().getString(Keys.web.siteName, Constants.NAME))); | ||||
add(new Label("name", Constants.NAME)); | add(new Label("name", Constants.NAME)); | ||||
setRedirect(true); | setRedirect(true); | ||||
setResponsePage(getApplication().getHomePage()); | setResponsePage(getApplication().getHomePage()); | ||||
} | } | ||||
tryAutomaticLogin(); | |||||
} | } | ||||
@Override | @Override | ||||
loginUser(user); | 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) { | private void loginUser(UserModel user) { | ||||
if (user != null) { | if (user != null) { | ||||
// Set the user into the session | // Set the user into the session | ||||
GitBlitWebSession.get().setUser(user); | GitBlitWebSession.get().setUser(user); | ||||
// Set Cookie | |||||
WebResponse response = (WebResponse) getRequestCycle().getResponse(); | |||||
GitBlit.self().setCookie(response, user); | |||||
if (!continueToOriginalDestination()) { | if (!continueToOriginalDestination()) { | ||||
// Redirect to home page | // Redirect to home page | ||||
setResponsePage(getApplication().getHomePage()); | setResponsePage(getApplication().getHomePage()); |
import com.gitblit.wicket.models.RepositoryModel; | import com.gitblit.wicket.models.RepositoryModel; | ||||
import com.gitblit.wicket.pages.BranchesPage; | import com.gitblit.wicket.pages.BranchesPage; | ||||
import com.gitblit.wicket.pages.DocsPage; | import com.gitblit.wicket.pages.DocsPage; | ||||
import com.gitblit.wicket.pages.EditRepositoryPage; | |||||
import com.gitblit.wicket.pages.LogPage; | import com.gitblit.wicket.pages.LogPage; | ||||
import com.gitblit.wicket.pages.SearchPage; | import com.gitblit.wicket.pages.SearchPage; | ||||
import com.gitblit.wicket.pages.SummaryPage; | import com.gitblit.wicket.pages.SummaryPage; | ||||
put("tags", "gb.tags"); | put("tags", "gb.tags"); | ||||
put("tree", "gb.tree"); | put("tree", "gb.tree"); | ||||
put("tickets", "gb.tickets"); | put("tickets", "gb.tickets"); | ||||
put("edit", "gb.edit"); | |||||
} | } | ||||
}; | }; | ||||
// per-repository extra page links | // per-repository extra page links | ||||
List<String> extraPageLinks = new ArrayList<String>(); | List<String> extraPageLinks = new ArrayList<String>(); | ||||
// Conditionally add tickets page | |||||
// Conditionally add tickets link | |||||
if (model.useTickets && JGitUtils.getTicketsBranch(r) != null) { | if (model.useTickets && JGitUtils.getTicketsBranch(r) != null) { | ||||
extraPageLinks.add("tickets"); | extraPageLinks.add("tickets"); | ||||
} | } | ||||
// Conditionally add docs page | |||||
// Conditionally add docs link | |||||
if (model.useDocs) { | if (model.useDocs) { | ||||
extraPageLinks.add("docs"); | 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<String> extrasDp = new ListDataProvider<String>(extraPageLinks); | ListDataProvider<String> extrasDp = new ListDataProvider<String>(extraPageLinks); | ||||
DataView<String> extrasView = new DataView<String>("extra", extrasDp) { | DataView<String> extrasView = new DataView<String>("extra", extrasDp) { | ||||
private static final long serialVersionUID = 1L; | private static final long serialVersionUID = 1L; | ||||
} else if (extra.equals("docs")) { | } else if (extra.equals("docs")) { | ||||
item.add(new Label("extraSeparator", " | ")); | item.add(new Label("extraSeparator", " | ")); | ||||
item.add(new LinkPanel("extraLink", null, getString("gb.docs"), DocsPage.class, WicketUtils.newRepositoryParameter(repositoryName))); | 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))); | |||||
} | } | ||||
} | } | ||||
}; | }; |
this.owner = owner; | this.owner = owner; | ||||
this.lastChange = lastchange; | this.lastChange = lastchange; | ||||
this.accessRestriction = AccessRestrictionType.NONE; | this.accessRestriction = AccessRestrictionType.NONE; | ||||
} | |||||
} | |||||
@Override | |||||
public String toString() { | |||||
return name; | |||||
} | |||||
} | } |
private String username; | private String username; | ||||
private String password; | private String password; | ||||
private String cookie; | |||||
private boolean canAdmin = false; | private boolean canAdmin = false; | ||||
private List<String> repositories = new ArrayList<String>(); | private List<String> repositories = new ArrayList<String>(); | ||||
return canAdmin || repositories.contains(repositoryName); | return canAdmin || repositories.contains(repositoryName); | ||||
} | } | ||||
public void setCookie(String cookie) { | |||||
this.cookie = cookie; | |||||
} | |||||
public String getCookie() { | |||||
return cookie; | |||||
} | |||||
public void setRepositories(List<String> repositories) { | public void setRepositories(List<String> repositories) { | ||||
this.repositories.clear(); | this.repositories.clear(); | ||||
this.repositories.addAll(repositories); | this.repositories.addAll(repositories); | ||||
return repositories; | return repositories; | ||||
} | } | ||||
@Override | |||||
public String toString() { | public String toString() { | ||||
return username; | return username; | ||||
} | } |
private final boolean isCreate; | private final boolean isCreate; | ||||
private boolean isAdmin = false; | |||||
public EditRepositoryPage() { | public EditRepositoryPage() { | ||||
// create constructor | // create constructor | ||||
super(); | super(); | ||||
} | } | ||||
} | } | ||||
final String oldName = repositoryModel.name; | |||||
final Palette<String> usersPalette = new Palette<String>("users", new ListModel<String>(repositoryUsers), new CollectionModel<String>(GitBlit.self().getAllUsernames()), new ChoiceRenderer<String>("", ""), 10, false); | final Palette<String> usersPalette = new Palette<String>("users", new ListModel<String>(repositoryUsers), new CollectionModel<String>(GitBlit.self().getAllUsernames()), new ChoiceRenderer<String>("", ""), 10, false); | ||||
CompoundPropertyModel<RepositoryModel> model = new CompoundPropertyModel<RepositoryModel>(repositoryModel); | CompoundPropertyModel<RepositoryModel> model = new CompoundPropertyModel<RepositoryModel>(repositoryModel); | ||||
Form<RepositoryModel> form = new Form<RepositoryModel>("editForm", model) { | Form<RepositoryModel> form = new Form<RepositoryModel>("editForm", model) { | ||||
ok |= c == vc; | ok |= c == vc; | ||||
} | } | ||||
if (!ok) { | if (!ok) { | ||||
error(MessageFormat.format("Illegal character '{0}' in repository name!", c)); | |||||
error(MessageFormat.format("Illegal character ''{0}'' in repository name!", c)); | |||||
return; | return; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
// save the repository | // save the repository | ||||
GitBlit.self().editRepositoryModel(repositoryModel, isCreate); | |||||
GitBlit.self().editRepositoryModel(oldName, repositoryModel, isCreate); | |||||
// save the repository access list | // save the repository access list | ||||
if (repositoryModel.accessRestriction.exceeds(AccessRestrictionType.NONE)) { | if (repositoryModel.accessRestriction.exceeds(AccessRestrictionType.NONE)) { | ||||
repositoryUsers.add(users.next()); | repositoryUsers.add(users.next()); | ||||
} | } | ||||
// ensure the owner is added to the user list | // 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); | repositoryUsers.add(repositoryModel.owner); | ||||
} | } | ||||
GitBlit.self().setRepositoryUsers(repositoryModel, repositoryUsers); | GitBlit.self().setRepositoryUsers(repositoryModel, repositoryUsers); | ||||
}; | }; | ||||
// field names reflective match RepositoryModel fields | // field names reflective match RepositoryModel fields | ||||
form.add(new TextField<String>("name").setEnabled(isCreate)); | |||||
form.add(new TextField<String>("name").setEnabled(isCreate || isAdmin)); | |||||
form.add(new TextField<String>("description")); | form.add(new TextField<String>("description")); | ||||
form.add(new DropDownChoice<String>("owner", GitBlit.self().getAllUsernames()).setEnabled(GitBlitWebSession.get().canAdmin())); | form.add(new DropDownChoice<String>("owner", GitBlit.self().getAllUsernames()).setEnabled(GitBlitWebSession.get().canAdmin())); | ||||
form.add(new DropDownChoice<AccessRestrictionType>("accessRestriction", Arrays.asList(AccessRestrictionType.values()), new AccessRestrictionRenderer())); | form.add(new DropDownChoice<AccessRestrictionType>("accessRestriction", Arrays.asList(AccessRestrictionType.values()), new AccessRestrictionRenderer())); | ||||
// Edit Repository | // Edit Repository | ||||
if (user.canAdmin()) { | if (user.canAdmin()) { | ||||
// Admins can edit everything | // Admins can edit everything | ||||
isAdmin = true; | |||||
return; | return; | ||||
} else { | } else { | ||||
if (!model.owner.equalsIgnoreCase(user.getUsername())) { | if (!model.owner.equalsIgnoreCase(user.getUsername())) { |
repos.add(repo); | repos.add(repo); | ||||
} | } | ||||
} | } | ||||
final String oldName = userModel.getUsername(); | |||||
final Palette<String> repositories = new Palette<String>("repositories", new ListModel<String>(userModel.getRepositories()), new CollectionModel<String>(repos), new ChoiceRenderer<String>("", ""), 10, false); | final Palette<String> repositories = new Palette<String>("repositories", new ListModel<String>(userModel.getRepositories()), new CollectionModel<String>(repos), new ChoiceRenderer<String>("", ""), 10, false); | ||||
Form<UserModel> form = new Form<UserModel>("editForm", model) { | Form<UserModel> form = new Form<UserModel>("editForm", model) { | ||||
if (isCreate) { | if (isCreate) { | ||||
UserModel model = GitBlit.self().getUserModel(username); | UserModel model = GitBlit.self().getUserModel(username); | ||||
if (model != null) { | if (model != null) { | ||||
error(MessageFormat.format("Username {0} is unavailable.", username)); | |||||
error(MessageFormat.format("Username ''{0}'' is unavailable.", username)); | |||||
return; | return; | ||||
} | } | ||||
} | } | ||||
return; | return; | ||||
} | } | ||||
// Optionally encrypt/obfuscate the password. | |||||
// Optionally store the password MD5 digest. | |||||
String type = GitBlit.self().settings().getString(Keys.realm.passwordStorage, "md5"); | String type = GitBlit.self().settings().getString(Keys.realm.passwordStorage, "md5"); | ||||
if (type.equalsIgnoreCase("md5")) { | if (type.equalsIgnoreCase("md5")) { | ||||
// store MD5 checksum of password | |||||
// store MD5 digest of password | |||||
userModel.setPassword(MD5.digest(userModel.getPassword())); | userModel.setPassword(MD5.digest(userModel.getPassword())); | ||||
} else if (type.equalsIgnoreCase("crypt")) { | |||||
// simple unix encryption | |||||
userModel.setPassword(Crypt.crypt(userModel.getUsername(), userModel.getPassword())); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
userModel.setRepositories(repos); | userModel.setRepositories(repos); | ||||
try { | try { | ||||
GitBlit.self().editUserModel(userModel, isCreate); | |||||
GitBlit.self().editUserModel(oldName, userModel, isCreate); | |||||
} catch (GitBlitException e) { | } catch (GitBlitException e) { | ||||
error(e.getMessage()); | error(e.getMessage()); | ||||
return; | return; | ||||
setRedirect(false); | setRedirect(false); | ||||
if (isCreate) { | if (isCreate) { | ||||
// create another user | // 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); | setResponsePage(EditUserPage.class); | ||||
} else { | } else { | ||||
// back to home | // back to home | ||||
}; | }; | ||||
// field names reflective match UserModel fields | // field names reflective match UserModel fields | ||||
form.add(new TextField<String>("username").setEnabled(isCreate)); | |||||
form.add(new TextField<String>("username")); | |||||
PasswordTextField passwordField = new PasswordTextField("password"); | PasswordTextField passwordField = new PasswordTextField("password"); | ||||
passwordField.setResetPassword(false); | passwordField.setResetPassword(false); | ||||
form.add(passwordField); | form.add(passwordField); |
String cachedMessage = GitBlitWebSession.get().clearErrorMessage(); | String cachedMessage = GitBlitWebSession.get().clearErrorMessage(); | ||||
if (!StringUtils.isEmpty(cachedMessage)) { | if (!StringUtils.isEmpty(cachedMessage)) { | ||||
error(cachedMessage); | error(cachedMessage); | ||||
System.out.println("displayed message"); | |||||
} | } | ||||
// Load the markdown welcome message | // Load the markdown welcome message |
<tr><th><wicket:message key="gb.owner">[owner]</wicket:message></th><td><span wicket:id="repositoryOwner">[repository owner]</span></td></tr> | <tr><th><wicket:message key="gb.owner">[owner]</wicket:message></th><td><span wicket:id="repositoryOwner">[repository owner]</span></td></tr> | ||||
<tr><th><wicket:message key="gb.lastChange">[last change]</wicket:message></th><td><span wicket:id="repositoryLastChange">[repository last change]</span></td></tr> | <tr><th><wicket:message key="gb.lastChange">[last change]</wicket:message></th><td><span wicket:id="repositoryLastChange">[repository last change]</span></td></tr> | ||||
<tr><th><wicket:message key="gb.stats">[stats]</wicket:message></th><td><span wicket:id="repositoryStats">[repository stats]</span></td></tr> | <tr><th><wicket:message key="gb.stats">[stats]</wicket:message></th><td><span wicket:id="repositoryStats">[repository stats]</span></td></tr> | ||||
<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> | |||||
<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> | |||||
</table> | </table> | ||||
</div> | </div> | ||||
</div> | </div> |
import java.awt.Color; | import java.awt.Color; | ||||
import java.awt.Dimension; | import java.awt.Dimension; | ||||
import java.text.MessageFormat; | import java.text.MessageFormat; | ||||
import java.util.ArrayList; | |||||
import java.util.List; | import java.util.List; | ||||
import javax.servlet.http.HttpServletRequest; | |||||
import org.apache.wicket.PageParameters; | import org.apache.wicket.PageParameters; | ||||
import org.apache.wicket.markup.html.basic.Label; | import org.apache.wicket.markup.html.basic.Label; | ||||
import org.apache.wicket.protocol.http.WebRequest; | |||||
import org.eclipse.jgit.lib.Repository; | import org.eclipse.jgit.lib.Repository; | ||||
import org.wicketstuff.googlecharts.AbstractChartData; | import org.wicketstuff.googlecharts.AbstractChartData; | ||||
import org.wicketstuff.googlecharts.Chart; | import org.wicketstuff.googlecharts.Chart; | ||||
import org.wicketstuff.googlecharts.MarkerType; | import org.wicketstuff.googlecharts.MarkerType; | ||||
import org.wicketstuff.googlecharts.ShapeMarker; | import org.wicketstuff.googlecharts.ShapeMarker; | ||||
import com.gitblit.Constants; | |||||
import com.gitblit.Constants.AccessRestrictionType; | import com.gitblit.Constants.AccessRestrictionType; | ||||
import com.gitblit.GitBlit; | import com.gitblit.GitBlit; | ||||
import com.gitblit.Keys; | import com.gitblit.Keys; | ||||
import com.gitblit.utils.JGitUtils; | import com.gitblit.utils.JGitUtils; | ||||
import com.gitblit.utils.StringUtils; | |||||
import com.gitblit.utils.TimeUtils; | import com.gitblit.utils.TimeUtils; | ||||
import com.gitblit.wicket.RepositoryPage; | import com.gitblit.wicket.RepositoryPage; | ||||
import com.gitblit.wicket.WicketUtils; | import com.gitblit.wicket.WicketUtils; | ||||
} else { | } else { | ||||
add(new Label("repositoryStats", MessageFormat.format("{0} commits and {1} tags in {2}", metricsTotal.count, metricsTotal.tag, TimeUtils.duration(metricsTotal.duration)))); | 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<String> repositoryUrls = new ArrayList<String>(); | |||||
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(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, "<br/>")).setEscapeModelStrings(false)); | |||||
add(new LogPanel("commitsPanel", repositoryName, null, r, numberCommits, 0)); | add(new LogPanel("commitsPanel", repositoryName, null, r, numberCommits, 0)); | ||||
add(new TagsPanel("tagsPanel", repositoryName, r, numberRefs)); | add(new TagsPanel("tagsPanel", repositoryName, r, numberRefs)); | ||||
commitAxis.setLabels(new String[] { "", String.valueOf((int) maxValue(metrics)) }); | commitAxis.setLabels(new String[] { "", String.valueOf((int) maxValue(metrics)) }); | ||||
provider.addAxis(commitAxis); | 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)); | provider.addShapeMarker(new ShapeMarker(MarkerType.CIRCLE, Color.BLUE, 1, -1, 5)); | ||||
add(new Chart("commitsChart", provider)); | add(new Chart("commitsChart", provider)); | ||||
} else { | } else { | ||||
add(WicketUtils.newBlankImage("commitsChart")); | add(WicketUtils.newBlankImage("commitsChart")); |
import java.util.TimeZone; | import java.util.TimeZone; | ||||
import org.apache.wicket.AttributeModifier; | |||||
import org.apache.wicket.Component; | import org.apache.wicket.Component; | ||||
import org.apache.wicket.markup.html.panel.Panel; | import org.apache.wicket.markup.html.panel.Panel; | ||||
import org.apache.wicket.model.Model; | |||||
import com.gitblit.GitBlit; | import com.gitblit.GitBlit; | ||||
import com.gitblit.Keys; | import com.gitblit.Keys; | ||||
WicketUtils.setHtmlTooltip(component, getString("gb.searchForCommitter") + " " + value); | 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<String>(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; | |||||
} | |||||
} | |||||
} | } |
</wicket:fragment> | </wicket:fragment> | ||||
<wicket:fragment wicket:id="repositoryAdminLinks"> | <wicket:fragment wicket:id="repositoryAdminLinks"> | ||||
<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> | |||||
<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> | |||||
</wicket:fragment> | </wicket:fragment> | ||||
<wicket:fragment wicket:id="repositoryOwnerLinks"> | <wicket:fragment wicket:id="repositoryOwnerLinks"> |
package com.gitblit.wicket.panels; | package com.gitblit.wicket.panels; | ||||
import java.text.MessageFormat; | |||||
import java.util.ArrayList; | import java.util.ArrayList; | ||||
import java.util.Collections; | import java.util.Collections; | ||||
import java.util.Comparator; | import java.util.Comparator; | ||||
import org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvider; | import org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvider; | ||||
import org.apache.wicket.markup.html.basic.Label; | import org.apache.wicket.markup.html.basic.Label; | ||||
import org.apache.wicket.markup.html.link.BookmarkablePageLink; | 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.html.panel.Fragment; | ||||
import org.apache.wicket.markup.repeater.Item; | import org.apache.wicket.markup.repeater.Item; | ||||
import org.apache.wicket.markup.repeater.data.DataView; | import org.apache.wicket.markup.repeater.data.DataView; | ||||
import com.gitblit.wicket.pages.EditRepositoryPage; | import com.gitblit.wicket.pages.EditRepositoryPage; | ||||
import com.gitblit.wicket.pages.SummaryPage; | import com.gitblit.wicket.pages.SummaryPage; | ||||
public class RepositoriesPanel extends BasePanel { | public class RepositoriesPanel extends BasePanel { | ||||
private static final long serialVersionUID = 1L; | private static final long serialVersionUID = 1L; | ||||
public RepositoriesPanel(String wicketId, final boolean showAdmin, final Map<AccessRestrictionType, String> accessRestrictionTranslations) { | public RepositoriesPanel(String wicketId, final boolean showAdmin, final Map<AccessRestrictionType, String> accessRestrictionTranslations) { | ||||
super(wicketId); | super(wicketId); | ||||
final UserModel user = GitBlitWebSession.get().getUser(); | final UserModel user = GitBlitWebSession.get().getUser(); | ||||
List<RepositoryModel> models = GitBlit.self().getRepositoryModels(user); | List<RepositoryModel> models = GitBlit.self().getRepositoryModels(user); | ||||
IDataProvider<RepositoryModel> dp; | |||||
final IDataProvider<RepositoryModel> dp; | |||||
Fragment adminLinks = new Fragment("adminPanel", "adminLinks", this); | Fragment adminLinks = new Fragment("adminPanel", "adminLinks", this); | ||||
adminLinks.add(new BookmarkablePageLink<Void>("newRepository", EditRepositoryPage.class)); | adminLinks.add(new BookmarkablePageLink<Void>("newRepository", EditRepositoryPage.class)); | ||||
add(adminLinks.setVisible(showAdmin)); | add(adminLinks.setVisible(showAdmin)); | ||||
if (GitBlit.self().settings().getString(Keys.web.repositoryListType, "flat").equalsIgnoreCase("grouped")) { | if (GitBlit.self().settings().getString(Keys.web.repositoryListType, "flat").equalsIgnoreCase("grouped")) { | ||||
Map<String, List<RepositoryModel>> groups = new HashMap<String, List<RepositoryModel>>(); | Map<String, List<RepositoryModel>> groups = new HashMap<String, List<RepositoryModel>>(); | ||||
for (RepositoryModel model : models) { | for (RepositoryModel model : models) { | ||||
List<RepositoryModel> groupedModels = new ArrayList<RepositoryModel>(); | List<RepositoryModel> groupedModels = new ArrayList<RepositoryModel>(); | ||||
for (String root : roots) { | for (String root : roots) { | ||||
List<RepositoryModel> subModels = groups.get(root); | List<RepositoryModel> subModels = groups.get(root); | ||||
groupedModels.add(new GroupRepositoryModel(root + " (" + subModels.size() + ")")); | |||||
groupedModels.add(new GroupRepositoryModel(root, subModels.size())); | |||||
groupedModels.addAll(subModels); | groupedModels.addAll(subModels); | ||||
} | } | ||||
dp = new ListDataProvider<RepositoryModel>(groupedModels); | |||||
dp = new RepositoriesProvider(groupedModels); | |||||
} else { | } else { | ||||
dp = new DataProvider(models); | |||||
dp = new SortableRepositoriesProvider(models); | |||||
} | } | ||||
DataView<RepositoryModel> dataView = new DataView<RepositoryModel>("row", dp) { | DataView<RepositoryModel> dataView = new DataView<RepositoryModel>("row", dp) { | ||||
private static final long serialVersionUID = 1L; | private static final long serialVersionUID = 1L; | ||||
int counter = 0; | int counter = 0; | ||||
@Override | |||||
protected void onBeforeRender() { | |||||
super.onBeforeRender(); | |||||
counter = 0; | |||||
} | |||||
public void populateItem(final Item<RepositoryModel> item) { | public void populateItem(final Item<RepositoryModel> item) { | ||||
final RepositoryModel entry = item.getModelObject(); | final RepositoryModel entry = item.getModelObject(); | ||||
if (entry instanceof GroupRepositoryModel) { | if (entry instanceof GroupRepositoryModel) { | ||||
Fragment row = new Fragment("rowContent", "groupRepositoryRow", this); | Fragment row = new Fragment("rowContent", "groupRepositoryRow", this); | ||||
item.add(row); | item.add(row); | ||||
row.add(new Label("groupName", entry.name)); | |||||
row.add(new Label("groupName", entry.toString())); | |||||
WicketUtils.setCssClass(item, "group"); | WicketUtils.setCssClass(item, "group"); | ||||
return; | return; | ||||
} | } | ||||
row.add(lastChangeLabel); | row.add(lastChangeLabel); | ||||
WicketUtils.setCssClass(lastChangeLabel, TimeUtils.timeAgoCss(entry.lastChange)); | 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) { | if (showAdmin) { | ||||
Fragment repositoryLinks = new Fragment("repositoryLinks", "repositoryAdminLinks", this); | Fragment repositoryLinks = new Fragment("repositoryLinks", "repositoryAdminLinks", this); | ||||
repositoryLinks.add(new BookmarkablePageLink<Void>("editRepository", EditRepositoryPage.class, WicketUtils.newRepositoryParameter(entry.name))); | repositoryLinks.add(new BookmarkablePageLink<Void>("editRepository", EditRepositoryPage.class, WicketUtils.newRepositoryParameter(entry.name))); | ||||
repositoryLinks.add(new BookmarkablePageLink<Void>("renameRepository", EditRepositoryPage.class, WicketUtils.newRepositoryParameter(entry.name)).setEnabled(false)); | |||||
repositoryLinks.add(new BookmarkablePageLink<Void>("deleteRepository", EditRepositoryPage.class, WicketUtils.newRepositoryParameter(entry.name)).setEnabled(false)); | |||||
Link<Void> deleteLink = new Link<Void>("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); | row.add(repositoryLinks); | ||||
} else if (showOwner) { | } else if (showOwner) { | ||||
Fragment repositoryLinks = new Fragment("repositoryLinks", "repositoryOwnerLinks", this); | Fragment repositoryLinks = new Fragment("repositoryLinks", "repositoryOwnerLinks", this); | ||||
add(fragment); | add(fragment); | ||||
} | } | ||||
} | } | ||||
private class GroupRepositoryModel extends RepositoryModel { | private class GroupRepositoryModel extends RepositoryModel { | ||||
private static final long serialVersionUID = 1L; | private static final long serialVersionUID = 1L; | ||||
GroupRepositoryModel(String name) { | |||||
int count = 0; | |||||
GroupRepositoryModel(String name, int count) { | |||||
super(name, "", "", new Date(0)); | super(name, "", "", new Date(0)); | ||||
this.count = count; | |||||
} | |||||
@Override | |||||
public String toString() { | |||||
return name + " (" + count + ")"; | |||||
} | } | ||||
} | } | ||||
protected enum SortBy { | protected enum SortBy { | ||||
repository, description, owner, date; | repository, description, owner, date; | ||||
} | } | ||||
}; | }; | ||||
} | } | ||||
private class DataProvider extends SortableDataProvider<RepositoryModel> { | |||||
private class RepositoriesProvider extends ListDataProvider<RepositoryModel> { | |||||
private static final long serialVersionUID = 1L; | |||||
public RepositoriesProvider(List<RepositoryModel> list) { | |||||
super(list); | |||||
} | |||||
@Override | |||||
public List<RepositoryModel> 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<RepositoryModel> { | |||||
private static final long serialVersionUID = 1L; | private static final long serialVersionUID = 1L; | ||||
private List<RepositoryModel> list = null; | private List<RepositoryModel> list = null; | ||||
protected DataProvider(List<RepositoryModel> list) { | |||||
protected SortableRepositoriesProvider(List<RepositoryModel> list) { | |||||
this.list = list; | this.list = list; | ||||
setSort(SortBy.date.name(), false); | setSort(SortBy.date.name(), false); | ||||
} | } | ||||
public void remove(RepositoryModel model) { | |||||
list.remove(model); | |||||
} | |||||
@Override | @Override | ||||
public int size() { | public int size() { | ||||
if (list == null) | if (list == null) |
package com.gitblit.wicket.panels; | 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.BookmarkablePageLink; | ||||
import org.apache.wicket.markup.html.link.Link; | |||||
import org.apache.wicket.markup.html.panel.Fragment; | import org.apache.wicket.markup.html.panel.Fragment; | ||||
import org.apache.wicket.markup.repeater.Item; | import org.apache.wicket.markup.repeater.Item; | ||||
import org.apache.wicket.markup.repeater.data.DataView; | import org.apache.wicket.markup.repeater.data.DataView; | ||||
import com.gitblit.wicket.LinkPanel; | import com.gitblit.wicket.LinkPanel; | ||||
import com.gitblit.wicket.WicketUtils; | import com.gitblit.wicket.WicketUtils; | ||||
import com.gitblit.wicket.pages.EditUserPage; | import com.gitblit.wicket.pages.EditUserPage; | ||||
import com.gitblit.wicket.pages.RepositoriesPage; | |||||
public class UsersPanel extends BasePanel { | public class UsersPanel extends BasePanel { | ||||
Fragment adminLinks = new Fragment("adminPanel", "adminLinks", this); | Fragment adminLinks = new Fragment("adminPanel", "adminLinks", this); | ||||
adminLinks.add(new BookmarkablePageLink<Void>("newUser", EditUserPage.class)); | adminLinks.add(new BookmarkablePageLink<Void>("newUser", EditUserPage.class)); | ||||
add(adminLinks.setVisible(showAdmin)); | add(adminLinks.setVisible(showAdmin)); | ||||
DataView<String> usersView = new DataView<String>("userRow", new ListDataProvider<String>(GitBlit.self().getAllUsernames())) { | |||||
final List<String> usernames = GitBlit.self().getAllUsernames(); | |||||
DataView<String> usersView = new DataView<String>("userRow", new ListDataProvider<String>(usernames)) { | |||||
private static final long serialVersionUID = 1L; | private static final long serialVersionUID = 1L; | ||||
private int counter = 0; | private int counter = 0; | ||||
@Override | |||||
protected void onBeforeRender() { | |||||
super.onBeforeRender(); | |||||
counter = 0; | |||||
} | |||||
public void populateItem(final Item<String> item) { | public void populateItem(final Item<String> item) { | ||||
final String entry = item.getModelObject(); | final String entry = item.getModelObject(); | ||||
item.add(editLink); | item.add(editLink); | ||||
Fragment userLinks = new Fragment("userLinks", "userAdminLinks", this); | Fragment userLinks = new Fragment("userLinks", "userAdminLinks", this); | ||||
userLinks.add(new BookmarkablePageLink<Void>("editUser", EditUserPage.class, WicketUtils.newUsernameParameter(entry))); | userLinks.add(new BookmarkablePageLink<Void>("editUser", EditUserPage.class, WicketUtils.newUsernameParameter(entry))); | ||||
userLinks.add(new BookmarkablePageLink<Void>("deleteUser", RepositoriesPage.class, WicketUtils.newUsernameParameter(entry)).setEnabled(false)); | |||||
Link<Void> deleteLink = new Link<Void>("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); | item.add(userLinks); | ||||
WicketUtils.setAlternatingBackground(item, counter); | WicketUtils.setAlternatingBackground(item, counter); |