Delete/Rename repos & user. Edit link. Dropped crypt. Other git urls.
2 files deleted
18 files modified
| | |
| | | # 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
|
| | |
| | | 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.
|
| | |
| | |
|
| | | 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;
|
| | |
|
| | |
| | | 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) {
|
| | |
| | | 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!");
|
| | | }
|
| | | }
|
| | |
| | | }
|
| | | return repositories;
|
| | | }
|
| | | |
| | |
|
| | | public RepositoryModel getRepositoryModel(UserModel user, String repositoryName) {
|
| | | RepositoryModel model = getRepositoryModel(repositoryName);
|
| | | if (model.accessRestriction.atLeast(AccessRestrictionType.VIEW)) {
|
| | |
| | | r.close();
|
| | | return model;
|
| | | }
|
| | | |
| | |
|
| | | private String getConfig(StoredConfig config, String field, String defaultValue) {
|
| | | String value = config.getString("gitblit", null, field);
|
| | | if (StringUtils.isEmpty(value)) {
|
| | |
| | | }
|
| | | 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 {
|
| | |
| | | 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;
|
| | |
| | |
|
| | | 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();
|
| | |
|
| | |
| | | boolean renameRole(String oldRole, String newRole);
|
| | |
|
| | | boolean deleteRole(String role);
|
| | | |
| | | }
|
| | |
| | | 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 {
|
| | |
| | | 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
|
| | |
| | | }
|
| | | }
|
| | | return user;
|
| | | }
|
| | |
|
| | | @Override
|
| | | public UserModel authenticate(char[] cookie) {
|
| | | // TODO cookie login
|
| | | return null;
|
| | | }
|
| | |
|
| | | @Override
|
| | |
| | |
|
| | | @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());
|
| | |
| | | }
|
| | | // 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) {
|
| | |
| | |
|
| | | @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>();
|
| | |
| | |
|
| | | // persist changes
|
| | | writeRealmFile(allUsers);
|
| | | return true;
|
| | | } catch (Throwable t) {
|
| | | logger.error(MessageFormat.format("Failed to delete role {0}!", role), t);
|
| | | }
|
| | |
| | | }
|
| | |
|
| | | 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();
|
| | | }
|
| | |
| | | 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;
|
| | |
| | | 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;
|
| | |
| | |
|
| | | 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));
|
| | |
| | | setRedirect(true);
|
| | | setResponsePage(getApplication().getHomePage());
|
| | | }
|
| | | |
| | | tryAutomaticLogin();
|
| | | }
|
| | |
|
| | | @Override
|
| | |
| | | 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
|
| | |
| | | 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;
|
| | |
| | | put("tags", "gb.tags");
|
| | | put("tree", "gb.tree");
|
| | | put("tickets", "gb.tickets");
|
| | | put("edit", "gb.edit");
|
| | | }
|
| | | };
|
| | |
|
| | |
| | | // 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);
|
| | |
| | | } 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)));
|
| | | }
|
| | | }
|
| | | };
|
| | |
| | | this.owner = owner;
|
| | | this.lastChange = lastchange;
|
| | | this.accessRestriction = AccessRestrictionType.NONE;
|
| | | } |
| | | }
|
| | | |
| | | @Override
|
| | | public String toString() {
|
| | | return name;
|
| | | }
|
| | | } |
| | |
| | |
|
| | | private String username;
|
| | | private String password;
|
| | | private String cookie;
|
| | | private boolean canAdmin = false;
|
| | | private List<String> repositories = new ArrayList<String>();
|
| | |
|
| | |
| | | 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);
|
| | |
| | | return repositories;
|
| | | }
|
| | |
|
| | | @Override
|
| | | public String toString() {
|
| | | return username;
|
| | | }
|
| | |
| | |
|
| | | private final boolean isCreate;
|
| | |
|
| | | private boolean isAdmin = false;
|
| | | |
| | | public EditRepositoryPage() {
|
| | | // create constructor
|
| | | 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);
|
| | | CompoundPropertyModel<RepositoryModel> model = new CompoundPropertyModel<RepositoryModel>(repositoryModel);
|
| | | Form<RepositoryModel> form = new Form<RepositoryModel>("editForm", model) {
|
| | |
| | | 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;
|
| | | }
|
| | | }
|
| | |
| | | }
|
| | |
|
| | | // 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)) {
|
| | |
| | | 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);
|
| | |
| | | };
|
| | |
|
| | | // 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()));
|
| | |
| | | // Edit Repository
|
| | | if (user.canAdmin()) {
|
| | | // Admins can edit everything
|
| | | isAdmin = true;
|
| | | return;
|
| | | } else {
|
| | | if (!model.owner.equalsIgnoreCase(user.getUsername())) {
|
| | |
| | | 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) {
|
| | |
|
| | |
| | | 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;
|
| | | }
|
| | | }
|
| | |
| | | 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()));
|
| | | }
|
| | | }
|
| | |
|
| | |
| | | }
|
| | | userModel.setRepositories(repos);
|
| | | try {
|
| | | GitBlit.self().editUserModel(userModel, isCreate);
|
| | | GitBlit.self().editUserModel(oldName, userModel, isCreate);
|
| | | } catch (GitBlitException e) {
|
| | | error(e.getMessage());
|
| | | return;
|
| | |
| | | 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
|
| | |
| | | };
|
| | |
|
| | | // 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);
|
| | |
| | | String cachedMessage = GitBlitWebSession.get().clearErrorMessage();
|
| | | if (!StringUtils.isEmpty(cachedMessage)) {
|
| | | error(cachedMessage);
|
| | | System.out.println("displayed 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.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>
|
| | |
| | | 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;
|
| | |
| | | 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;
|
| | |
| | | } 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));
|
| | |
| | | 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"));
|
| | |
| | |
|
| | | 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;
|
| | |
| | | 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: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">
|
| | |
| | | package com.gitblit.wicket.panels;
|
| | |
|
| | | import java.text.MessageFormat;
|
| | | import java.util.ArrayList;
|
| | | import java.util.Collections;
|
| | | import java.util.Comparator;
|
| | |
| | | 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;
|
| | |
| | | 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) {
|
| | |
| | | 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;
|
| | | }
|
| | |
| | | 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);
|
| | |
| | | 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;
|
| | | }
|
| | |
| | | };
|
| | | }
|
| | |
|
| | | 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)
|
| | |
| | | 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;
|
| | |
| | | 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 {
|
| | |
|
| | |
| | | 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();
|
| | |
| | | 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);
|