Browse Source

Delete/Rename repos & user. Edit link. Dropped crypt. Other git urls.

tags/v0.5.0
James Moger 13 years ago
parent
commit
8a2e9c3633

+ 5
- 3
distrib/gitblit.properties View File

@@ -17,8 +17,10 @@ git.exportAll = true
# e.g. /libraries/mylibrary.git
git.nestedRepositories = true
# The root clone url
git.cloneUrl = https://localhost/git/
# Show other URLs on the summary page for accessing your git repositories
# Use spaces to separate urls. {0} is the token for the repository name.
# git.otherUrls = ssh://localhost/git/{0} git://localhost/git/{0}
git.otherUrls =
#
# Authentication Settings
@@ -34,7 +36,7 @@ web.authenticateAdminPages = true
realm.realmFile = users.properties
# How to store passwords.
# Valid values are plain, md5 or crypt (unix style). Default is md5.
# Valid values are plain or md5. Default is md5.
realm.passwordStorage = md5
# Minimum valid length for a plain text password.

+ 67
- 36
src/com/gitblit/GitBlit.java View File

@@ -9,14 +9,13 @@ import java.util.List;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.http.Cookie;
import org.apache.wicket.protocol.http.WebResponse;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.StoredConfig;
import org.eclipse.jgit.transport.resolver.FileResolver;
import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
import org.eclipse.jgit.util.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -61,8 +60,12 @@ public class GitBlit implements ServletContextListener {
return storedSettings.getBoolean(Keys.web.debugMode, false);
}
public String getCloneUrl(String repositoryName) {
return storedSettings.getString(Keys.git.cloneUrl, "https://localhost/git/") + repositoryName;
public List<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) {
@@ -76,49 +79,31 @@ public class GitBlit implements ServletContextListener {
return loginService.authenticate(username, password);
}
public UserModel authenticate(Cookie[] cookies) {
if (loginService == null) {
return null;
}
if (cookies != null && cookies.length > 0) {
for (Cookie cookie : cookies) {
if (cookie.getName().equals(Constants.NAME)) {
String value = cookie.getValue();
return loginService.authenticate(value.toCharArray());
}
}
}
return null;
}
public void setCookie(WebResponse response, UserModel user) {
Cookie userCookie = new Cookie(Constants.NAME, user.getCookie());
userCookie.setMaxAge(Integer.MAX_VALUE);
userCookie.setPath("/");
response.addCookie(userCookie);
}
public List<String> getAllUsernames() {
List<String> names = loginService.getAllUsernames();
List<String> names = new ArrayList<String>(loginService.getAllUsernames());
Collections.sort(names);
return names;
}
public boolean deleteUser(String username) {
return loginService.deleteUser(username);
}
public UserModel getUserModel(String username) {
UserModel user = loginService.getUserModel(username);
return user;
}
public List<String> getRepositoryUsers(RepositoryModel repository) {
return loginService.getUsernamesForRole(repository.name);
}
public boolean setRepositoryUsers(RepositoryModel repository, List<String> repositoryUsers) {
return loginService.setUsernamesForRole(repository.name, repositoryUsers);
}
public void editUserModel(UserModel user, boolean isCreate) throws GitBlitException {
if (!loginService.updateUserModel(user)) {
public void editUserModel(String username, UserModel user, boolean isCreate) throws GitBlitException {
if (!loginService.updateUserModel(username, user)) {
throw new GitBlitException(isCreate ? "Failed to add user!" : "Failed to update user!");
}
}
@@ -152,7 +137,7 @@ public class GitBlit implements ServletContextListener {
}
return repositories;
}
public RepositoryModel getRepositoryModel(UserModel user, String repositoryName) {
RepositoryModel model = getRepositoryModel(repositoryName);
if (model.accessRestriction.atLeast(AccessRestrictionType.VIEW)) {
@@ -184,7 +169,7 @@ public class GitBlit implements ServletContextListener {
r.close();
return model;
}
private String getConfig(StoredConfig config, String field, String defaultValue) {
String value = config.getString("gitblit", null, field);
if (StringUtils.isEmpty(value)) {
@@ -192,21 +177,37 @@ public class GitBlit implements ServletContextListener {
}
return value;
}
private boolean getConfig(StoredConfig config, String field, boolean defaultValue) {
return config.getBoolean("gitblit", field, defaultValue);
}
public void editRepositoryModel(RepositoryModel repository, boolean isCreate) throws GitBlitException {
public void editRepositoryModel(String repositoryName, RepositoryModel repository, boolean isCreate) throws GitBlitException {
Repository r = null;
if (isCreate) {
if (new File(repositoriesFolder, repository.name).exists()) {
throw new GitBlitException(MessageFormat.format("Can not create repository {0} because it already exists.", repository.name));
throw new GitBlitException(MessageFormat.format("Can not create repository ''{0}'' because it already exists.", repository.name));
}
// create repository
logger.info("create repository " + repository.name);
r = JGitUtils.createRepository(repositoriesFolder, repository.name, true);
} else {
// rename repository
if (!repositoryName.equalsIgnoreCase(repository.name)) {
File folder = new File(repositoriesFolder, repositoryName);
File destFolder = new File(repositoriesFolder, repository.name);
if (destFolder.exists()) {
throw new GitBlitException(MessageFormat.format("Can not rename repository ''{0}'' to ''{1}'' because ''{1}'' already exists.", repositoryName, repository.name));
}
if (!folder.renameTo(destFolder)) {
throw new GitBlitException(MessageFormat.format("Failed to rename repository ''{0}'' to ''{1}''.", repositoryName, repository.name));
}
// rename the roles
if (!loginService.renameRole(repositoryName, repository.name)) {
throw new GitBlitException(MessageFormat.format("Failed to rename repository permissions ''{0}'' to ''{1}''.", repositoryName, repository.name));
}
}
// load repository
logger.info("edit repository " + repository.name);
try {
@@ -235,6 +236,36 @@ public class GitBlit implements ServletContextListener {
r.close();
}
public boolean deleteRepositoryModel(RepositoryModel model) {
return deleteRepository(model.name);
}
public boolean deleteRepository(String repositoryName) {
try {
File folder = new File(repositoriesFolder, repositoryName);
if (folder.exists() && folder.isDirectory()) {
FileUtils.delete(folder, FileUtils.RECURSIVE);
if (loginService.deleteRole(repositoryName)) {
return true;
}
}
} catch (Throwable t) {
logger.error(MessageFormat.format("Failed to delete repository {0}", repositoryName), t);
}
return false;
}
public boolean renameRepository(RepositoryModel model, String newName) {
File folder = new File(repositoriesFolder, model.name);
if (folder.exists() && folder.isDirectory()) {
File newFolder = new File(repositoriesFolder, newName);
if (folder.renameTo(newFolder)) {
return loginService.renameRole(model.name, newName);
}
}
return false;
}
public void configureContext(IStoredSettings settings) {
logger.info("Using configuration from " + settings.toString());
this.storedSettings = settings;

+ 4
- 3
src/com/gitblit/ILoginService.java View File

@@ -8,14 +8,16 @@ public interface ILoginService {
UserModel authenticate(String username, char[] password);
UserModel authenticate(char[] cookie);
UserModel getUserModel(String username);
boolean updateUserModel(UserModel model);
boolean updateUserModel(String username, UserModel model);
boolean deleteUserModel(UserModel model);
boolean deleteUser(String username);
List<String> getAllUsernames();
List<String> getUsernamesForRole(String role);
@@ -25,5 +27,4 @@ public interface ILoginService {
boolean renameRole(String oldRole, String newRole);
boolean deleteRole(String role);
}

+ 17
- 12
src/com/gitblit/JettyLoginService.java View File

@@ -23,7 +23,6 @@ import org.eclipse.jetty.util.log.Log;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.gitblit.utils.StringUtils;
import com.gitblit.wicket.models.UserModel;
public class JettyLoginService extends MappedLoginService implements ILoginService {
@@ -45,7 +44,6 @@ public class JettyLoginService extends MappedLoginService implements ILoginServi
return null;
}
UserModel user = new UserModel(username);
user.setCookie(StringUtils.getSHA1((Constants.NAME + username + new String(password))));
user.canAdmin(identity.isUserInRole(Constants.ADMIN_ROLE, null));
// Add repositories
@@ -61,12 +59,6 @@ public class JettyLoginService extends MappedLoginService implements ILoginServi
return user;
}
@Override
public UserModel authenticate(char[] cookie) {
// TODO cookie login
return null;
}
@Override
public UserModel getUserModel(String username) {
UserIdentity identity = _users.get(username);
@@ -107,6 +99,11 @@ public class JettyLoginService extends MappedLoginService implements ILoginServi
@Override
public boolean updateUserModel(UserModel model) {
return updateUserModel(model.getUsername(), model);
}
@Override
public boolean updateUserModel(String username, UserModel model) {
try {
Properties allUsers = readRealmFile();
ArrayList<String> roles = new ArrayList<String>(model.getRepositories());
@@ -125,11 +122,13 @@ public class JettyLoginService extends MappedLoginService implements ILoginServi
}
// trim trailing comma
sb.setLength(sb.length() - 1);
allUsers.remove(username);
allUsers.put(model.getUsername(), sb.toString());
writeRealmFile(allUsers);
// Update login service
removeUser(username);
putUser(model.getUsername(), Credential.getCredential(model.getPassword()), roles.toArray(new String[0]));
return true;
} catch (Throwable t) {
@@ -140,21 +139,26 @@ public class JettyLoginService extends MappedLoginService implements ILoginServi
@Override
public boolean deleteUserModel(UserModel model) {
return deleteUser(model.getUsername());
}
@Override
public boolean deleteUser(String username) {
try {
// Read realm file
Properties allUsers = readRealmFile();
allUsers.remove(model.getUsername());
allUsers.remove(username);
writeRealmFile(allUsers);
// Drop user from map
_users.remove(model.getUsername());
removeUser(username);
return true;
} catch (Throwable t) {
logger.error(MessageFormat.format("Failed to delete user model {0}!", model.getUsername()), t);
logger.error(MessageFormat.format("Failed to delete user {0}!", username), t);
}
return false;
}
@Override
public List<String> getAllUsernames() {
List<String> list = new ArrayList<String>();
@@ -366,6 +370,7 @@ public class JettyLoginService extends MappedLoginService implements ILoginServi
// persist changes
writeRealmFile(allUsers);
return true;
} catch (Throwable t) {
logger.error(MessageFormat.format("Failed to delete role {0}!", role), t);
}

+ 5
- 1
src/com/gitblit/utils/StringUtils.java View File

@@ -40,9 +40,13 @@ public class StringUtils {
}
public static String flattenStrings(List<String> values) {
return flattenStrings(values, " ");
}
public static String flattenStrings(List<String> values, String separator) {
StringBuilder sb = new StringBuilder();
for (String value : values) {
sb.append(value).append(" ");
sb.append(value).append(separator);
}
return sb.toString().trim();
}

+ 1
- 26
src/com/gitblit/wicket/LoginPage.java View File

@@ -1,7 +1,5 @@
package com.gitblit.wicket;
import javax.servlet.http.Cookie;
import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.basic.Label;
@@ -12,8 +10,6 @@ import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.protocol.http.WebRequest;
import org.apache.wicket.protocol.http.WebResponse;
import com.gitblit.Constants;
import com.gitblit.GitBlit;
@@ -28,8 +24,6 @@ public class LoginPage extends WebPage {
public LoginPage(PageParameters params) {
super(params);
tryAutomaticLogin();
add(new Label("title", GitBlit.self().settings().getString(Keys.web.siteName, Constants.NAME)));
add(new Label("name", Constants.NAME));
@@ -52,8 +46,6 @@ public class LoginPage extends WebPage {
setRedirect(true);
setResponsePage(getApplication().getHomePage());
}
tryAutomaticLogin();
}
@Override
@@ -68,29 +60,12 @@ public class LoginPage extends WebPage {
loginUser(user);
}
}
private void tryAutomaticLogin() {
UserModel user = null;
// Grab cookie from Browser Session
Cookie[] cookies = ((WebRequest) getRequestCycle().getRequest()).getCookies();
if (cookies != null && cookies.length > 0) {
user = GitBlit.self().authenticate(cookies);
}
// Login the user
loginUser(user);
}
private void loginUser(UserModel user) {
if (user != null) {
// Set the user into the session
GitBlitWebSession.get().setUser(user);
// Set Cookie
WebResponse response = (WebResponse) getRequestCycle().getResponse();
GitBlit.self().setCookie(response, user);
if (!continueToOriginalDestination()) {
// Redirect to home page
setResponsePage(getApplication().getHomePage());

+ 20
- 2
src/com/gitblit/wicket/RepositoryPage.java View File

@@ -35,6 +35,7 @@ import com.gitblit.utils.StringUtils;
import com.gitblit.wicket.models.RepositoryModel;
import com.gitblit.wicket.pages.BranchesPage;
import com.gitblit.wicket.pages.DocsPage;
import com.gitblit.wicket.pages.EditRepositoryPage;
import com.gitblit.wicket.pages.LogPage;
import com.gitblit.wicket.pages.SearchPage;
import com.gitblit.wicket.pages.SummaryPage;
@@ -65,6 +66,7 @@ public abstract class RepositoryPage extends BasePage {
put("tags", "gb.tags");
put("tree", "gb.tree");
put("tickets", "gb.tickets");
put("edit", "gb.edit");
}
};
@@ -90,16 +92,29 @@ public abstract class RepositoryPage extends BasePage {
// per-repository extra page links
List<String> extraPageLinks = new ArrayList<String>();
// Conditionally add tickets page
// Conditionally add tickets link
if (model.useTickets && JGitUtils.getTicketsBranch(r) != null) {
extraPageLinks.add("tickets");
}
// Conditionally add docs page
// Conditionally add docs link
if (model.useDocs) {
extraPageLinks.add("docs");
}
final boolean showAdmin;
if (GitBlit.self().settings().getBoolean(Keys.web.authenticateAdminPages, true)) {
boolean allowAdmin = GitBlit.self().settings().getBoolean(Keys.web.allowAdministration, false);
showAdmin = allowAdmin && GitBlitWebSession.get().canAdmin();
} else {
showAdmin = GitBlit.self().settings().getBoolean(Keys.web.allowAdministration, false);
}
// Conditionally add edit link
if (showAdmin || GitBlitWebSession.get().isLoggedIn() && (model.owner != null && model.owner.equalsIgnoreCase(GitBlitWebSession.get().getUser().getUsername()))) {
extraPageLinks.add("edit");
}
ListDataProvider<String> extrasDp = new ListDataProvider<String>(extraPageLinks);
DataView<String> extrasView = new DataView<String>("extra", extrasDp) {
private static final long serialVersionUID = 1L;
@@ -112,6 +127,9 @@ public abstract class RepositoryPage extends BasePage {
} else if (extra.equals("docs")) {
item.add(new Label("extraSeparator", " | "));
item.add(new LinkPanel("extraLink", null, getString("gb.docs"), DocsPage.class, WicketUtils.newRepositoryParameter(repositoryName)));
} else if (extra.equals("edit")) {
item.add(new Label("extraSeparator", " | "));
item.add(new LinkPanel("extraLink", null, getString("gb.edit"), EditRepositoryPage.class, WicketUtils.newRepositoryParameter(repositoryName)));
}
}
};

+ 6
- 1
src/com/gitblit/wicket/models/RepositoryModel.java View File

@@ -33,5 +33,10 @@ public class RepositoryModel implements Serializable {
this.owner = owner;
this.lastChange = lastchange;
this.accessRestriction = AccessRestrictionType.NONE;
}
}
@Override
public String toString() {
return name;
}
}

+ 1
- 9
src/com/gitblit/wicket/models/UserModel.java View File

@@ -10,7 +10,6 @@ public class UserModel implements Serializable {
private String username;
private String password;
private String cookie;
private boolean canAdmin = false;
private List<String> repositories = new ArrayList<String>();
@@ -42,14 +41,6 @@ public class UserModel implements Serializable {
return canAdmin || repositories.contains(repositoryName);
}
public void setCookie(String cookie) {
this.cookie = cookie;
}
public String getCookie() {
return cookie;
}
public void setRepositories(List<String> repositories) {
this.repositories.clear();
this.repositories.addAll(repositories);
@@ -63,6 +54,7 @@ public class UserModel implements Serializable {
return repositories;
}
@Override
public String toString() {
return username;
}

+ 8
- 4
src/com/gitblit/wicket/pages/EditRepositoryPage.java View File

@@ -36,6 +36,8 @@ public class EditRepositoryPage extends BasePage {
private final boolean isCreate;
private boolean isAdmin = false;
public EditRepositoryPage() {
// create constructor
super();
@@ -67,6 +69,7 @@ public class EditRepositoryPage extends BasePage {
}
}
final String oldName = repositoryModel.name;
final Palette<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);
Form<RepositoryModel> form = new Form<RepositoryModel>("editForm", model) {
@@ -94,7 +97,7 @@ public class EditRepositoryPage extends BasePage {
ok |= c == vc;
}
if (!ok) {
error(MessageFormat.format("Illegal character '{0}' in repository name!", c));
error(MessageFormat.format("Illegal character ''{0}'' in repository name!", c));
return;
}
}
@@ -107,7 +110,7 @@ public class EditRepositoryPage extends BasePage {
}
// save the repository
GitBlit.self().editRepositoryModel(repositoryModel, isCreate);
GitBlit.self().editRepositoryModel(oldName, repositoryModel, isCreate);
// save the repository access list
if (repositoryModel.accessRestriction.exceeds(AccessRestrictionType.NONE)) {
@@ -117,7 +120,7 @@ public class EditRepositoryPage extends BasePage {
repositoryUsers.add(users.next());
}
// ensure the owner is added to the user list
if (!repositoryUsers.contains(repositoryModel.owner)) {
if (repositoryModel.owner != null && !repositoryUsers.contains(repositoryModel.owner)) {
repositoryUsers.add(repositoryModel.owner);
}
GitBlit.self().setRepositoryUsers(repositoryModel, repositoryUsers);
@@ -132,7 +135,7 @@ public class EditRepositoryPage extends BasePage {
};
// field names reflective match RepositoryModel fields
form.add(new TextField<String>("name").setEnabled(isCreate));
form.add(new TextField<String>("name").setEnabled(isCreate || isAdmin));
form.add(new TextField<String>("description"));
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()));
@@ -175,6 +178,7 @@ public class EditRepositoryPage extends BasePage {
// Edit Repository
if (user.canAdmin()) {
// Admins can edit everything
isAdmin = true;
return;
} else {
if (!model.owner.equalsIgnoreCase(user.getUsername())) {

+ 7
- 9
src/com/gitblit/wicket/pages/EditUserPage.java View File

@@ -67,6 +67,7 @@ public class EditUserPage extends BasePage {
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);
Form<UserModel> form = new Form<UserModel>("editForm", model) {
@@ -87,7 +88,7 @@ public class EditUserPage extends BasePage {
if (isCreate) {
UserModel model = GitBlit.self().getUserModel(username);
if (model != null) {
error(MessageFormat.format("Username {0} is unavailable.", username));
error(MessageFormat.format("Username ''{0}'' is unavailable.", username));
return;
}
}
@@ -108,14 +109,11 @@ public class EditUserPage extends BasePage {
return;
}
// Optionally encrypt/obfuscate the password.
// Optionally store the password MD5 digest.
String type = GitBlit.self().settings().getString(Keys.realm.passwordStorage, "md5");
if (type.equalsIgnoreCase("md5")) {
// store MD5 checksum of password
// store MD5 digest of password
userModel.setPassword(MD5.digest(userModel.getPassword()));
} else if (type.equalsIgnoreCase("crypt")) {
// simple unix encryption
userModel.setPassword(Crypt.crypt(userModel.getUsername(), userModel.getPassword()));
}
}
@@ -126,7 +124,7 @@ public class EditUserPage extends BasePage {
}
userModel.setRepositories(repos);
try {
GitBlit.self().editUserModel(userModel, isCreate);
GitBlit.self().editUserModel(oldName, userModel, isCreate);
} catch (GitBlitException e) {
error(e.getMessage());
return;
@@ -134,7 +132,7 @@ public class EditUserPage extends BasePage {
setRedirect(false);
if (isCreate) {
// create another user
info(MessageFormat.format("New user {0} successfully created.", userModel.getUsername()));
info(MessageFormat.format("New user ''{0}'' successfully created.", userModel.getUsername()));
setResponsePage(EditUserPage.class);
} else {
// back to home
@@ -144,7 +142,7 @@ public class EditUserPage extends BasePage {
};
// field names reflective match UserModel fields
form.add(new TextField<String>("username").setEnabled(isCreate));
form.add(new TextField<String>("username"));
PasswordTextField passwordField = new PasswordTextField("password");
passwordField.setResetPassword(false);
form.add(passwordField);

+ 0
- 1
src/com/gitblit/wicket/pages/RepositoriesPage.java View File

@@ -46,7 +46,6 @@ public class RepositoriesPage extends BasePage {
String cachedMessage = GitBlitWebSession.get().clearErrorMessage();
if (!StringUtils.isEmpty(cachedMessage)) {
error(cachedMessage);
System.out.println("displayed message");
}
// Load the markdown welcome message

+ 1
- 1
src/com/gitblit/wicket/pages/SummaryPage.html View File

@@ -20,7 +20,7 @@
<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.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>
</div>
</div>

+ 45
- 19
src/com/gitblit/wicket/pages/SummaryPage.java View File

@@ -3,10 +3,14 @@ package com.gitblit.wicket.pages;
import java.awt.Color;
import java.awt.Dimension;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.protocol.http.WebRequest;
import org.eclipse.jgit.lib.Repository;
import org.wicketstuff.googlecharts.AbstractChartData;
import org.wicketstuff.googlecharts.Chart;
@@ -19,10 +23,12 @@ import org.wicketstuff.googlecharts.LineStyle;
import org.wicketstuff.googlecharts.MarkerType;
import org.wicketstuff.googlecharts.ShapeMarker;
import com.gitblit.Constants;
import com.gitblit.Constants.AccessRestrictionType;
import com.gitblit.GitBlit;
import com.gitblit.Keys;
import com.gitblit.utils.JGitUtils;
import com.gitblit.utils.StringUtils;
import com.gitblit.utils.TimeUtils;
import com.gitblit.wicket.RepositoryPage;
import com.gitblit.wicket.WicketUtils;
@@ -67,25 +73,45 @@ public class SummaryPage extends RepositoryPage {
} else {
add(new Label("repositoryStats", MessageFormat.format("{0} commits and {1} tags in {2}", metricsTotal.count, metricsTotal.tag, TimeUtils.duration(metricsTotal.duration))));
}
AccessRestrictionType accessRestriction = getRepositoryModel().accessRestriction;
switch (accessRestriction) {
case NONE:
add(WicketUtils.newClearPixel("accessRestrictionIcon").setVisible(false));
break;
case PUSH:
add(WicketUtils.newImage("accessRestrictionIcon", "lock_go_16x16.png", getAccessRestrictions().get(accessRestriction)));
break;
case CLONE:
add(WicketUtils.newImage("accessRestrictionIcon", "lock_pull_16x16.png", getAccessRestrictions().get(accessRestriction)));
break;
case VIEW:
add(WicketUtils.newImage("accessRestrictionIcon", "shield_16x16.png", getAccessRestrictions().get(accessRestriction)));
break;
default:
List<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(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 TagsPanel("tagsPanel", repositoryName, r, numberRefs));
@@ -113,9 +139,9 @@ public class SummaryPage extends RepositoryPage {
commitAxis.setLabels(new String[] { "", String.valueOf((int) maxValue(metrics)) });
provider.addAxis(commitAxis);
provider.setLineStyles(new LineStyle[] {new LineStyle(2, 4, 0), new LineStyle(0, 4, 1)});
provider.setLineStyles(new LineStyle[] { new LineStyle(2, 4, 0), new LineStyle(0, 4, 1) });
provider.addShapeMarker(new ShapeMarker(MarkerType.CIRCLE, Color.BLUE, 1, -1, 5));
add(new Chart("commitsChart", provider));
} else {
add(WicketUtils.newBlankImage("commitsChart"));

+ 20
- 0
src/com/gitblit/wicket/panels/BasePanel.java View File

@@ -2,8 +2,10 @@ package com.gitblit.wicket.panels;
import java.util.TimeZone;
import org.apache.wicket.AttributeModifier;
import org.apache.wicket.Component;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.Model;
import com.gitblit.GitBlit;
import com.gitblit.Keys;
@@ -30,4 +32,22 @@ public abstract class BasePanel extends Panel {
WicketUtils.setHtmlTooltip(component, getString("gb.searchForCommitter") + " " + value);
}
}
public class JavascriptEventConfirmation extends AttributeModifier {
private static final long serialVersionUID = 1L;
public JavascriptEventConfirmation(String event, String msg) {
super(event, true, new Model<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;
}
}
}

+ 1
- 1
src/com/gitblit/wicket/panels/RepositoriesPanel.html View File

@@ -31,7 +31,7 @@
</wicket:fragment>
<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:id="repositoryOwnerLinks">

+ 107
- 18
src/com/gitblit/wicket/panels/RepositoriesPanel.java View File

@@ -1,5 +1,6 @@
package com.gitblit.wicket.panels;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@@ -15,6 +16,7 @@ import org.apache.wicket.extensions.markup.html.repeater.util.SortParam;
import org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvider;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.html.panel.Fragment;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.markup.repeater.data.DataView;
@@ -36,22 +38,21 @@ import com.gitblit.wicket.models.UserModel;
import com.gitblit.wicket.pages.EditRepositoryPage;
import com.gitblit.wicket.pages.SummaryPage;
public class RepositoriesPanel extends BasePanel {
private static final long serialVersionUID = 1L;
public RepositoriesPanel(String wicketId, final boolean showAdmin, final Map<AccessRestrictionType, String> accessRestrictionTranslations) {
super(wicketId);
final UserModel user = GitBlitWebSession.get().getUser();
List<RepositoryModel> models = GitBlit.self().getRepositoryModels(user);
IDataProvider<RepositoryModel> dp;
final IDataProvider<RepositoryModel> dp;
Fragment adminLinks = new Fragment("adminPanel", "adminLinks", this);
adminLinks.add(new BookmarkablePageLink<Void>("newRepository", EditRepositoryPage.class));
add(adminLinks.setVisible(showAdmin));
if (GitBlit.self().settings().getString(Keys.web.repositoryListType, "flat").equalsIgnoreCase("grouped")) {
Map<String, List<RepositoryModel>> groups = new HashMap<String, List<RepositoryModel>>();
for (RepositoryModel model : models) {
@@ -69,24 +70,30 @@ public class RepositoriesPanel extends BasePanel {
List<RepositoryModel> groupedModels = new ArrayList<RepositoryModel>();
for (String root : roots) {
List<RepositoryModel> subModels = groups.get(root);
groupedModels.add(new GroupRepositoryModel(root + " (" + subModels.size() + ")"));
groupedModels.add(new GroupRepositoryModel(root, subModels.size()));
groupedModels.addAll(subModels);
}
dp = new ListDataProvider<RepositoryModel>(groupedModels);
dp = new RepositoriesProvider(groupedModels);
} else {
dp = new DataProvider(models);
dp = new SortableRepositoriesProvider(models);
}
DataView<RepositoryModel> dataView = new DataView<RepositoryModel>("row", dp) {
private static final long serialVersionUID = 1L;
int counter = 0;
@Override
protected void onBeforeRender() {
super.onBeforeRender();
counter = 0;
}
public void populateItem(final Item<RepositoryModel> item) {
final RepositoryModel entry = item.getModelObject();
if (entry instanceof GroupRepositoryModel) {
Fragment row = new Fragment("rowContent", "groupRepositoryRow", this);
item.add(row);
row.add(new Label("groupName", entry.name));
row.add(new Label("groupName", entry.toString()));
WicketUtils.setCssClass(item, "group");
return;
}
@@ -144,12 +151,30 @@ public class RepositoriesPanel extends BasePanel {
row.add(lastChangeLabel);
WicketUtils.setCssClass(lastChangeLabel, TimeUtils.timeAgoCss(entry.lastChange));
boolean showOwner = user != null && user.getUsername().equalsIgnoreCase(entry.owner);
boolean showOwner = user != null && user.getUsername().equalsIgnoreCase(entry.owner);
if (showAdmin) {
Fragment repositoryLinks = new Fragment("repositoryLinks", "repositoryAdminLinks", this);
repositoryLinks.add(new BookmarkablePageLink<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);
} else if (showOwner) {
Fragment repositoryLinks = new Fragment("repositoryLinks", "repositoryOwnerLinks", this);
@@ -179,16 +204,24 @@ public class RepositoriesPanel extends BasePanel {
add(fragment);
}
}
private class GroupRepositoryModel extends RepositoryModel {
private static final long serialVersionUID = 1L;
GroupRepositoryModel(String name) {
int count = 0;
GroupRepositoryModel(String name, int count) {
super(name, "", "", new Date(0));
this.count = count;
}
@Override
public String toString() {
return name + " (" + count + ")";
}
}
protected enum SortBy {
repository, description, owner, date;
}
@@ -204,15 +237,71 @@ public class RepositoriesPanel extends BasePanel {
};
}
private class DataProvider extends SortableDataProvider<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 List<RepositoryModel> list = null;
protected DataProvider(List<RepositoryModel> list) {
protected SortableRepositoriesProvider(List<RepositoryModel> list) {
this.list = list;
setSort(SortBy.date.name(), false);
}
public void remove(RepositoryModel model) {
list.remove(model);
}
@Override
public int size() {
if (list == null)

+ 29
- 4
src/com/gitblit/wicket/panels/UsersPanel.java View File

@@ -1,6 +1,10 @@
package com.gitblit.wicket.panels;
import java.text.MessageFormat;
import java.util.List;
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.html.panel.Fragment;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.markup.repeater.data.DataView;
@@ -10,7 +14,6 @@ import com.gitblit.GitBlit;
import com.gitblit.wicket.LinkPanel;
import com.gitblit.wicket.WicketUtils;
import com.gitblit.wicket.pages.EditUserPage;
import com.gitblit.wicket.pages.RepositoriesPage;
public class UsersPanel extends BasePanel {
@@ -22,10 +25,17 @@ public class UsersPanel extends BasePanel {
Fragment adminLinks = new Fragment("adminPanel", "adminLinks", this);
adminLinks.add(new BookmarkablePageLink<Void>("newUser", EditUserPage.class));
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 int counter = 0;
@Override
protected void onBeforeRender() {
super.onBeforeRender();
counter = 0;
}
public void populateItem(final Item<String> item) {
final String entry = item.getModelObject();
@@ -34,7 +44,22 @@ public class UsersPanel extends BasePanel {
item.add(editLink);
Fragment userLinks = new Fragment("userLinks", "userAdminLinks", this);
userLinks.add(new BookmarkablePageLink<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);
WicketUtils.setAlternatingBackground(item, counter);

BIN
src/com/gitblit/wicket/resources/gitblt.png View File


BIN
src/com/gitblit/wicket/resources/gitblt3.png View File


Loading…
Cancel
Save