From fb9813874c811ae06604c30d875e9dce57df9874 Mon Sep 17 00:00:00 2001 From: SHaselbauer Date: Mon, 21 Jan 2013 16:28:11 -0500 Subject: Merge multiple owners feature (pull request #63, #66) --- src/com/gitblit/GitBlit.java | 48 ++++--- src/com/gitblit/GitFilter.java | 2 +- src/com/gitblit/client/EditRepositoryDialog.java | 6 +- src/com/gitblit/client/EditUserDialog.java | 4 +- src/com/gitblit/client/GitblitClient.java | 4 +- .../gitblit/client/RegistrantPermissionsPanel.java | 4 +- src/com/gitblit/client/RepositoriesPanel.java | 5 +- src/com/gitblit/client/RepositoriesTableModel.java | 4 +- src/com/gitblit/models/RepositoryModel.java | 99 ++++++++++---- src/com/gitblit/models/UserModel.java | 9 +- src/com/gitblit/utils/MultiConfigUtil.java | 89 +++++++++++++ src/com/gitblit/utils/StringComparator.java | 24 ++++ src/com/gitblit/wicket/GitBlitWebApp.properties | 8 +- src/com/gitblit/wicket/GitBlitWebApp_es.properties | 6 +- src/com/gitblit/wicket/GitBlitWebApp_ja.properties | 6 +- src/com/gitblit/wicket/GitBlitWebApp_ko.properties | 8 +- src/com/gitblit/wicket/GitBlitWebApp_nl.properties | 8 +- src/com/gitblit/wicket/GitBlitWebApp_pl.properties | 6 +- .../gitblit/wicket/GitBlitWebApp_pt_BR.properties | 8 +- .../gitblit/wicket/pages/EditRepositoryPage.html | 2 +- .../gitblit/wicket/pages/EditRepositoryPage.java | 26 +++- src/com/gitblit/wicket/pages/RepositoryPage.java | 10 +- src/com/gitblit/wicket/pages/RootSubPage.java | 2 +- src/com/gitblit/wicket/pages/SummaryPage.html | 2 +- src/com/gitblit/wicket/pages/SummaryPage.java | 19 ++- .../wicket/panels/ProjectRepositoryPanel.html | 2 +- .../wicket/panels/ProjectRepositoryPanel.java | 146 +++++++++++++-------- .../wicket/panels/RegistrantPermissionsPanel.java | 4 +- .../gitblit/wicket/panels/RepositoriesPanel.html | 6 +- .../gitblit/wicket/panels/RepositoriesPanel.java | 78 ++++++----- 30 files changed, 445 insertions(+), 200 deletions(-) create mode 100644 src/com/gitblit/utils/MultiConfigUtil.java create mode 100644 src/com/gitblit/utils/StringComparator.java (limited to 'src') diff --git a/src/com/gitblit/GitBlit.java b/src/com/gitblit/GitBlit.java index 3eb246b8..a607bd84 100644 --- a/src/com/gitblit/GitBlit.java +++ b/src/com/gitblit/GitBlit.java @@ -109,6 +109,7 @@ import com.gitblit.utils.HttpUtils; import com.gitblit.utils.JGitUtils; import com.gitblit.utils.JsonUtils; import com.gitblit.utils.MetricUtils; +import com.gitblit.utils.MultiConfigUtil; import com.gitblit.utils.ObjectCache; import com.gitblit.utils.StringUtils; import com.gitblit.utils.TimeUtils; @@ -180,6 +181,8 @@ public class GitBlit implements ServletContextListener { private TimeZone timezone; private FileBasedConfig projectConfigs; + + private MultiConfigUtil multiConfigUtil = new MultiConfigUtil(); public GitBlit() { if (gitblit == null) { @@ -822,7 +825,7 @@ public class GitBlit implements ServletContextListener { // TODO reconsider ownership as a user property // manually specify personal repository ownerships for (RepositoryModel rm : repositoryListCache.values()) { - if (rm.isUsersPersonalRepository(user.username) || rm.isOwner(user.username)) { + if (rm.isUsersPersonalRepository(user.username) || rm.isRepoAdministrator(user.username)) { RegistrantAccessPermission rp = new RegistrantAccessPermission(rm.name, AccessPermission.REWIND, PermissionType.OWNER, RegistrantType.REPOSITORY, null, false); // user may be owner of a repository to which they've inherited @@ -936,14 +939,14 @@ public class GitBlit implements ServletContextListener { for (RepositoryModel model : getRepositoryModels(user)) { if (model.isUsersPersonalRepository(username)) { // personal repository - model.owner = user.username; + model.addRepoAdministrator(user.username); String oldRepositoryName = model.name; model.name = "~" + user.username + model.name.substring(model.projectPath.length()); model.projectPath = "~" + user.username; updateRepositoryModel(oldRepositoryName, model, false); - } else if (model.isOwner(username)) { + } else if (model.isRepoAdministrator(username)) { // common/shared repo - model.owner = user.username; + model.addRepoAdministrator(user.username); updateRepositoryModel(model.name, model, false); } } @@ -1662,7 +1665,7 @@ public class GitBlit implements ServletContextListener { if (config != null) { model.description = getConfig(config, "description", ""); - model.owner = getConfig(config, "owner", ""); + model.addRepoAdministrators(multiConfigUtil.convertStringToSet(getConfig(config, "owner", ""))); model.useTickets = getConfig(config, "useTickets", false); model.useDocs = getConfig(config, "useDocs", false); model.allowForks = getConfig(config, "allowForks", true); @@ -2169,7 +2172,7 @@ public class GitBlit implements ServletContextListener { public void updateConfiguration(Repository r, RepositoryModel repository) { StoredConfig config = r.getConfig(); config.setString(Constants.CONFIG_GITBLIT, null, "description", repository.description); - config.setString(Constants.CONFIG_GITBLIT, null, "owner", repository.owner); + config.setString(Constants.CONFIG_GITBLIT, null, "owner", multiConfigUtil.convertCollectionToSingleLineString(repository.getRepoAdministrators())); config.setBoolean(Constants.CONFIG_GITBLIT, null, "useTickets", repository.useTickets); config.setBoolean(Constants.CONFIG_GITBLIT, null, "useDocs", repository.useDocs); config.setBoolean(Constants.CONFIG_GITBLIT, null, "allowForks", repository.allowForks); @@ -3079,9 +3082,15 @@ public class GitBlit implements ServletContextListener { } // schedule lucene engine - logger.info("Lucene executor is scheduled to process indexed branches every 2 minutes."); - scheduledExecutor.scheduleAtFixedRate(luceneExecutor, 1, 2, TimeUnit.MINUTES); - + boolean branchIndexingActivated = settings.getBoolean( + Keys.git.branchIndexingActivated, true); + logger.info("Branch indexing is " + + (branchIndexingActivated ? "" : "not") + " activated"); + if (branchIndexingActivated) { + logger.info("Lucene executor is scheduled to process indexed branches every 2 minutes."); + scheduledExecutor.scheduleAtFixedRate(luceneExecutor, 1, 2, + TimeUnit.MINUTES); + } // schedule gc engine if (gcExecutor.isReady()) { logger.info("GC executor is scheduled to scan repositories every 24 hours."); @@ -3249,18 +3258,23 @@ public class GitBlit implements ServletContextListener { // create a Gitblit repository model for the clone RepositoryModel cloneModel = repository.cloneAs(cloneName); - // owner has REWIND/RW+ permissions - cloneModel.owner = user.username; + // owner has REWIND/RW+ permissions + cloneModel.addRepoAdministrator(user.username); updateRepositoryModel(cloneName, cloneModel, false); // add the owner of the source repository to the clone's access list - if (!StringUtils.isEmpty(repository.owner)) { - UserModel originOwner = getUserModel(repository.owner); - if (originOwner != null) { - originOwner.setRepositoryPermission(cloneName, AccessPermission.CLONE); - updateUserModel(originOwner.username, originOwner, false); + Set repoAdministrators = repository.getRepoAdministrators(); + if (repoAdministrators != null) { + for (String repoAdministrator : repoAdministrators) { + if (!StringUtils.isEmpty(repoAdministrator)) { + UserModel originOwner = getUserModel(repoAdministrator); + if (originOwner != null) { + originOwner.setRepositoryPermission(cloneName, AccessPermission.CLONE); + updateUserModel(originOwner.username, originOwner, false); + } + } } - } + } // grant origin's user list clone permission to fork List users = getRepositoryUsers(repository); diff --git a/src/com/gitblit/GitFilter.java b/src/com/gitblit/GitFilter.java index 2b769d4b..82b37dc6 100644 --- a/src/com/gitblit/GitFilter.java +++ b/src/com/gitblit/GitFilter.java @@ -222,7 +222,7 @@ public class GitFilter extends AccessRestrictionFilter { // create repository RepositoryModel model = new RepositoryModel(); model.name = repository; - model.owner = user.username; + model.addRepoAdministrator(user.username); model.projectPath = StringUtils.getFirstPathElement(repository); if (model.isUsersPersonalRepository(user.username)) { // personal repository, default to private for user diff --git a/src/com/gitblit/client/EditRepositoryDialog.java b/src/com/gitblit/client/EditRepositoryDialog.java index 6f9ed525..5c03ff82 100644 --- a/src/com/gitblit/client/EditRepositoryDialog.java +++ b/src/com/gitblit/client/EditRepositoryDialog.java @@ -335,7 +335,7 @@ public class EditRepositoryDialog extends JDialog { usersPalette = new RegistrantPermissionsPanel(RegistrantType.USER); JPanel northFieldsPanel = new JPanel(new GridLayout(0, 1, 0, 5)); - northFieldsPanel.add(newFieldPanel(Translation.get("gb.owner"), ownerField)); + northFieldsPanel.add(newFieldPanel(Translation.get("gb.repoAdministrators"), ownerField)); northFieldsPanel.add(newFieldPanel(Translation.get("gb.accessRestriction"), accessRestriction), BorderLayout.NORTH); @@ -556,8 +556,8 @@ public class EditRepositoryDialog extends JDialog { repository.name = rname; repository.description = descriptionField.getText(); - repository.owner = ownerField.getSelectedItem() == null ? null - : ownerField.getSelectedItem().toString(); + repository.addRepoAdministrator(ownerField.getSelectedItem() == null ? null + : ownerField.getSelectedItem().toString()); repository.HEAD = headRefField.getSelectedItem() == null ? null : headRefField.getSelectedItem().toString(); repository.gcPeriod = (Integer) gcPeriod.getSelectedItem(); diff --git a/src/com/gitblit/client/EditUserDialog.java b/src/com/gitblit/client/EditUserDialog.java index 0400f5c9..cb04b315 100644 --- a/src/com/gitblit/client/EditUserDialog.java +++ b/src/com/gitblit/client/EditUserDialog.java @@ -389,7 +389,7 @@ public class EditUserDialog extends JDialog { List restricted = new ArrayList(); for (RepositoryModel repo : repositories) { // exclude Owner or personal repositories - if (!repo.isOwner(username) && !repo.isUsersPersonalRepository(username)) { + if (!repo.isRepoAdministrator(username) && !repo.isUsersPersonalRepository(username)) { if (repo.accessRestriction.exceeds(AccessRestrictionType.NONE) && repo.authorizationControl.equals(AuthorizationControl.NAMED)) { restricted.add(repo.name); @@ -438,7 +438,7 @@ public class EditUserDialog extends JDialog { permission.mutable = false; continue; } - boolean isOwner = rm.isOwner(username); + boolean isOwner = rm.isRepoAdministrator(username); if (isOwner) { permission.permissionType = PermissionType.OWNER; permission.mutable = false; diff --git a/src/com/gitblit/client/GitblitClient.java b/src/com/gitblit/client/GitblitClient.java index 1101cd60..01db46e5 100644 --- a/src/com/gitblit/client/GitblitClient.java +++ b/src/com/gitblit/client/GitblitClient.java @@ -162,7 +162,7 @@ public class GitblitClient implements Serializable { } public boolean isOwner(RepositoryModel model) { - return account != null && account.equalsIgnoreCase(model.owner); + return model.isRepoAdministrator(account); } public String getURL(String action, String repository, String objectId) { @@ -532,7 +532,7 @@ public class GitblitClient implements Serializable { // TODO reconsider ownership as a user property // manually specify personal repository ownerships for (RepositoryModel rm : allRepositories) { - if (rm.isUsersPersonalRepository(user.username) || rm.isOwner(user.username)) { + if (rm.isUsersPersonalRepository(user.username) || rm.isRepoAdministrator(user.username)) { RegistrantAccessPermission rp = new RegistrantAccessPermission(rm.name, AccessPermission.REWIND, PermissionType.OWNER, RegistrantType.REPOSITORY, null, false); // user may be owner of a repository to which they've inherited diff --git a/src/com/gitblit/client/RegistrantPermissionsPanel.java b/src/com/gitblit/client/RegistrantPermissionsPanel.java index 98dbfb72..46ba689c 100644 --- a/src/com/gitblit/client/RegistrantPermissionsPanel.java +++ b/src/com/gitblit/client/RegistrantPermissionsPanel.java @@ -209,8 +209,8 @@ public class RegistrantPermissionsPanel extends JPanel { setToolTipText(Translation.get("gb.administratorPermission")); break; case OWNER: - setText(Translation.get("gb.owner")); - setToolTipText(Translation.get("gb.ownerPermission")); + setText(Translation.get("gb.repoAdministrators")); + setToolTipText(Translation.get("gb.repoAdministratorPermission")); break; case TEAM: setText(ap.source == null ? Translation.get("gb.team") : ap.source); diff --git a/src/com/gitblit/client/RepositoriesPanel.java b/src/com/gitblit/client/RepositoriesPanel.java index 769d33b8..6700b21a 100644 --- a/src/com/gitblit/client/RepositoriesPanel.java +++ b/src/com/gitblit/client/RepositoriesPanel.java @@ -52,6 +52,7 @@ import com.gitblit.Keys; import com.gitblit.models.RegistrantAccessPermission; import com.gitblit.models.FeedModel; import com.gitblit.models.RepositoryModel; +import com.gitblit.utils.MultiConfigUtil; import com.gitblit.utils.StringUtils; /** @@ -84,6 +85,8 @@ public abstract class RepositoriesPanel extends JPanel { private JTextField filterTextfield; private JButton clearCache; + + private MultiConfigUtil multiConfigUtil = new MultiConfigUtil(); public RepositoriesPanel(GitblitClient gitblit) { super(); @@ -453,7 +456,7 @@ public abstract class RepositoriesPanel extends JPanel { dialog.setLocationRelativeTo(RepositoriesPanel.this); List usernames = gitblit.getUsernames(); List members = gitblit.getUserAccessPermissions(repository); - dialog.setUsers(repository.owner, usernames, members); + dialog.setUsers(multiConfigUtil.convertCollectionToSingleLineString(repository.getRepoAdministrators()), usernames, members); dialog.setTeams(gitblit.getTeamnames(), gitblit.getTeamAccessPermissions(repository)); dialog.setRepositories(gitblit.getRepositories()); dialog.setFederationSets(gitblit.getFederationSets(), repository.federationSets); diff --git a/src/com/gitblit/client/RepositoriesTableModel.java b/src/com/gitblit/client/RepositoriesTableModel.java index c3eaf6e5..65f49ca0 100644 --- a/src/com/gitblit/client/RepositoriesTableModel.java +++ b/src/com/gitblit/client/RepositoriesTableModel.java @@ -73,7 +73,7 @@ public class RepositoriesTableModel extends AbstractTableModel { case Description: return Translation.get("gb.description"); case Owner: - return Translation.get("gb.owner"); + return Translation.get("gb.repoAdministrators"); case Last_Change: return Translation.get("gb.lastChange"); case Size: @@ -111,7 +111,7 @@ public class RepositoriesTableModel extends AbstractTableModel { case Description: return model.description; case Owner: - return model.owner; + return model.getRepoAdministrators(); case Indicators: return model; case Last_Change: diff --git a/src/com/gitblit/models/RepositoryModel.java b/src/com/gitblit/models/RepositoryModel.java index 5be33a2d..a27e9fdb 100644 --- a/src/com/gitblit/models/RepositoryModel.java +++ b/src/com/gitblit/models/RepositoryModel.java @@ -23,10 +23,14 @@ import java.util.Map; import java.util.Set; import java.util.TreeSet; +import org.apache.wicket.markup.html.basic.MultiLineLabel; + import com.gitblit.Constants.AccessRestrictionType; import com.gitblit.Constants.AuthorizationControl; import com.gitblit.Constants.FederationStrategy; import com.gitblit.utils.ArrayUtils; +import com.gitblit.utils.MultiConfigUtil; +import com.gitblit.utils.StringComparator; import com.gitblit.utils.StringUtils; /** @@ -36,14 +40,15 @@ import com.gitblit.utils.StringUtils; * @author James Moger * */ -public class RepositoryModel implements Serializable, Comparable { +public class RepositoryModel implements Serializable, + Comparable { private static final long serialVersionUID = 1L; // field names are reflectively mapped in EditRepository page public String name; public String description; - public String owner; + private Set repoAdministrators = new TreeSet(new StringComparator()); public Date lastChange; public boolean hasCommits; public boolean showRemoteBranches; @@ -79,26 +84,29 @@ public class RepositoryModel implements Serializable, Comparable(); - this.federationStrategy = FederationStrategy.FEDERATE_THIS; + this.federationStrategy = FederationStrategy.FEDERATE_THIS; this.projectPath = StringUtils.getFirstPathElement(name); } - + public List getLocalBranches() { if (ArrayUtils.isEmpty(availableRefs)) { return new ArrayList(); @@ -111,30 +119,30 @@ public class RepositoryModel implements Serializable, Comparable(); } forks.add(repository); } - + public void removeFork(String repository) { if (forks == null) { return; } forks.remove(repository); } - + public void resetDisplayName() { displayName = null; } - + @Override public int hashCode() { return name.hashCode(); } - + @Override public boolean equals(Object o) { if (o instanceof RepositoryModel) { @@ -155,27 +163,25 @@ public class RepositoryModel implements Serializable, Comparable 0) { + this.repoAdministrators.add(repoAdministrator.toLowerCase()); + } + } + + public void removeRepoAdministrator(String repoAdministrator) { + if (repoAdministrator != null && repoAdministrator.trim().length() > 0) { + this.repoAdministrators.remove(repoAdministrator.toLowerCase()); + } + } + + public void addRepoAdministrators(Set repoAdministrators) { + if (repoAdministrators != null) { + for (String admin : repoAdministrators) { + this.addRepoAdministrator(admin); + } + } + } + + public void removeRepoAdministrators(Set repoAdministrators) { + if (repoAdministrators != null) { + for (String admin : repoAdministrators) { + this.removeRepoAdministrator(admin); + } + } + } + + public void removeAllRepoAdministrators() { + this.repoAdministrators.clear(); + } + + public Set getRepoAdministrators() { + return this.repoAdministrators; + } + + public boolean isRepoAdministrator(String username) { + if (username == null || username.trim().length() == 0) { + return false; + } + return this.repoAdministrators.contains(username.toLowerCase()); + } } \ No newline at end of file diff --git a/src/com/gitblit/models/UserModel.java b/src/com/gitblit/models/UserModel.java index 54e81cb5..c513febc 100644 --- a/src/com/gitblit/models/UserModel.java +++ b/src/com/gitblit/models/UserModel.java @@ -108,8 +108,7 @@ public class UserModel implements Principal, Serializable, Comparable @Deprecated @Unused public boolean canAccessRepository(RepositoryModel repository) { - boolean isOwner = !StringUtils.isEmpty(repository.owner) - && repository.owner.equals(username); + boolean isOwner = repository.isRepoAdministrator(username); boolean allowAuthenticated = isAuthenticated && AuthorizationControl.AUTHENTICATED.equals(repository.authorizationControl); return canAdmin() || isOwner || repositories.contains(repository.name.toLowerCase()) || hasTeamAccess(repository.name) || allowAuthenticated; @@ -304,7 +303,7 @@ public class UserModel implements Principal, Serializable, Comparable } // repository owner - either specified owner or personal repository - if (repository.isOwner(username) || repository.isUsersPersonalRepository(username)) { + if (repository.isRepoAdministrator(username) || repository.isUsersPersonalRepository(username)) { ap.permissionType = PermissionType.OWNER; ap.permission = AccessPermission.REWIND; return ap; @@ -412,7 +411,7 @@ public class UserModel implements Principal, Serializable, Comparable // can not fork your own repository return false; } - if (canAdmin() || repository.isOwner(username)) { + if (canAdmin() || repository.isRepoAdministrator(username)) { return true; } if (!repository.allowForks) { @@ -429,7 +428,7 @@ public class UserModel implements Principal, Serializable, Comparable } public boolean canEdit(RepositoryModel model) { - return canAdmin() || model.isUsersPersonalRepository(username) || model.isOwner(username); + return canAdmin() || model.isUsersPersonalRepository(username) || model.isRepoAdministrator(username); } /** diff --git a/src/com/gitblit/utils/MultiConfigUtil.java b/src/com/gitblit/utils/MultiConfigUtil.java new file mode 100644 index 00000000..1ed8122f --- /dev/null +++ b/src/com/gitblit/utils/MultiConfigUtil.java @@ -0,0 +1,89 @@ +/* + * Copyright 2011 gitblit.com. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitblit.utils; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * Utility class to convert Strings into Collections and vice versa. + * + * @author saheba + * + */ +public class MultiConfigUtil implements Serializable { + private static final long serialVersionUID = 1324076956473037856L; + + public static final String OPTION_SEPARATOR = ";"; + + /** + * converts a collection of strings into a single line string by concatenating them and separating the different elements with the OPTION_SEPARATOR + * + * @param collection of strings + * + * @return + */ + public String convertCollectionToSingleLineString(Collection collection) { + String result = ""; + for (String string : collection) { + if (!result.equals("")) { + result += OPTION_SEPARATOR; + } + result += string; + } + return result; + } + + /** + * converts a collection of strings into a list of strings + * + * @param collection + * + * @return + */ + public List convertCollectionToList(Collection collection) { + List result = new ArrayList(); + for (String string : collection) { + result.add(string); + } + return result; + } + + /** + * converts a single line string into a set of strings by splitting the given string with the OPTION_SEPARATOR + * + * @param string which contains one or more options concatenated with the OPTION_SEPARATOR + * + * @return + */ + public Set convertStringToSet(String string) { + Set result = new HashSet(); + if (string != null && string.trim().length() > 0) { + String[] splitted = string.split(OPTION_SEPARATOR); + for (int i = 0; i < splitted.length; i++) { + String possible = splitted[i].trim(); + if (possible.length() > 0) { + result.add(possible); + } + } + } + return result; + } +} diff --git a/src/com/gitblit/utils/StringComparator.java b/src/com/gitblit/utils/StringComparator.java new file mode 100644 index 00000000..da9b3478 --- /dev/null +++ b/src/com/gitblit/utils/StringComparator.java @@ -0,0 +1,24 @@ +package com.gitblit.utils; + +import java.io.Serializable; +import java.util.Comparator; + +/** + * A comparator for {@link java.util.TreeSet} that sorts strings ascending inside the {@link java.util.TreeSet} + * + * @author saheba + * + */ +public class StringComparator implements Comparator, Serializable { + private static final long serialVersionUID = 7563266118711225424L; + + /* (non-Javadoc) + * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object) + */ + @Override + public int compare(String o1, String o2) { + // TODO Auto-generated method stub + return o1.compareTo(o2); + } + +} diff --git a/src/com/gitblit/wicket/GitBlitWebApp.properties b/src/com/gitblit/wicket/GitBlitWebApp.properties index 16f76411..d601e1ef 100644 --- a/src/com/gitblit/wicket/GitBlitWebApp.properties +++ b/src/com/gitblit/wicket/GitBlitWebApp.properties @@ -1,5 +1,5 @@ gb.repository = repository -gb.owner = owner +gb.repoAdministrators = repository administrators gb.description = description gb.lastChange = last change gb.refs = refs @@ -94,7 +94,7 @@ gb.zip = zip gb.showReadme = show readme gb.showReadmeDescription = show a \"readme\" Markdown file on the summary page gb.nameDescription = use '/' to group repositories. e.g. libraries/mycoollib.git -gb.ownerDescription = the owner may edit repository settings +gb.repoAdministratorsDescription = the repository administrators may edit repository settings gb.blob = blob gb.commitActivityTrend = commit activity trend gb.commitActivityDOW = commit activity by day of week @@ -279,7 +279,7 @@ gb.displayName = display name gb.emailAddress = email address gb.errorAdminLoginRequired = Administration requires a login gb.errorOnlyAdminMayCreateRepository = Only an administrator may create a repository -gb.errorOnlyAdminOrOwnerMayEditRepository = Only an administrator or the owner may edit a repository +gb.errorOnlyAdminOrRepoAdminMayEditRepository = Only an administrator or a repository administrator may edit a repository gb.errorAdministrationDisabled = Administration is disabled gb.lastNDays = last {0} days gb.completeGravatarProfile = Complete profile on Gravatar.com @@ -364,7 +364,7 @@ gb.gcPeriod = GC period gb.gcPeriodDescription = duration between garbage collections gb.gcThreshold = GC threshold gb.gcThresholdDescription = minimum total size of loose objects to trigger early garbage collection -gb.ownerPermission = repository owner +gb.repoAdministratorPermission = repository administrator gb.administrator = admin gb.administratorPermission = Gitblit administrator gb.team = team diff --git a/src/com/gitblit/wicket/GitBlitWebApp_es.properties b/src/com/gitblit/wicket/GitBlitWebApp_es.properties index 64c9ca13..478a0ab6 100644 --- a/src/com/gitblit/wicket/GitBlitWebApp_es.properties +++ b/src/com/gitblit/wicket/GitBlitWebApp_es.properties @@ -1,5 +1,5 @@ gb.repository = Repositorio -gb.owner = Propietario +gb.repoAdministrators = Administradores del repositorio gb.description = Descripci\u00F3n gb.lastChange = Actualizado gb.refs = Refs @@ -94,7 +94,7 @@ gb.zip = Zip gb.showReadme = Ver l\u00E9eme gb.showReadmeDescription = Mostrar el archivo \"l\u00E9eme\" de Markdown en la p\u00E1gina resumen gb.nameDescription = Usa '/' para agrupar repositorios. ej. librerias/mylibreria.git -gb.ownerDescription = El propietario puede editar la configuraci\u00F3n del repositorio +gb.repoAdministratorsDescription = Administradores del repositorio puede editar la configuraci\u00F3n del repositorio gb.blob = Objeto gb.commitActivityTrend = Tendencia de actividad del repositorio gb.commitActivityDOW = Actividad de consignas por d\u00EDa de la semana @@ -364,7 +364,7 @@ gb.gcPeriod = Periodo para GC gb.gcPeriodDescription = Duraci\u00F3n entre periodos de limpieza gb.gcThreshold = L\u00EDmites para GC gb.gcThresholdDescription = Tama\u00F1o m\u00EDnimo total de objetos sueltos para activar la recolecci\u00F3n inmediata de basura -gb.ownerPermission = Propietario del repositorio +gb.repoAdministratorPermission = Administrador del repositorio gb.administrator = Admin gb.administratorPermission = Administrador de Gitblit gb.team = Equipo diff --git a/src/com/gitblit/wicket/GitBlitWebApp_ja.properties b/src/com/gitblit/wicket/GitBlitWebApp_ja.properties index 086df7b7..d4e35118 100755 --- a/src/com/gitblit/wicket/GitBlitWebApp_ja.properties +++ b/src/com/gitblit/wicket/GitBlitWebApp_ja.properties @@ -1,5 +1,5 @@ gb.repository = \u30ea\u30dd\u30b8\u30c8\u30ea -gb.owner = \u6240\u6709\u8005 +gb.repoAdministrators = \u30EA\u30DD\u30B8\u30C8\u30EA\u7BA1\u7406\u8005 gb.description = \u8aac\u660e gb.lastChange = \u6700\u5f8c\u306e\u5909\u66f4 gb.refs = refs @@ -94,7 +94,7 @@ gb.zip = zip gb.showReadme = readme\u8868\u793a gb.showReadmeDescription = \"readme\" Markdown\u30d5\u30a1\u30a4\u30eb\u3092\u6982\u8981\u30da\u30fc\u30b8\u306b\u8868\u793a\u3059\u308b gb.nameDescription = \u30ea\u30dd\u30b8\u30c8\u30ea\u3092\u30b0\u30eb\u30fc\u30d7\u5316\u3059\u308b\u306b\u306f '/' \u3092\u4f7f\u3046\u3002 e.g. libraries/mycoollib.git -gb.ownerDescription = \u6240\u6709\u8005\u306f\u30ea\u30dd\u30b8\u30c8\u30ea\u306e\u8a2d\u5b9a\u3092\u5909\u66f4\u3067\u304d\u308b +gb.repoAdministratorsDescription = \u30EA\u30DD\u30B8\u30C8\u30EA\u7BA1\u7406\u8005\u306f\u30ea\u30dd\u30b8\u30c8\u30ea\u306e\u8a2d\u5b9a\u3092\u5909\u66f4\u3067\u304d\u308b gb.blob = blob gb.commitActivityTrend = commit activity trend gb.commitActivityDOW = commit activity by day of week @@ -279,7 +279,7 @@ gb.displayName = display name gb.emailAddress = email address gb.errorAdminLoginRequired = Administration requires a login gb.errorOnlyAdminMayCreateRepository = Only an administrator may create a repository -gb.errorOnlyAdminOrOwnerMayEditRepository = Only an administrator or the owner may edit a repository +gb.errorOnlyAdminOrRepoAdminMayEditRepository = Only an administrator or a repository administrator may edit a repository gb.errorAdministrationDisabled = Administration is disabled gb.lastNDays = last {0} days gb.completeGravatarProfile = Complete profile on Gravatar.com diff --git a/src/com/gitblit/wicket/GitBlitWebApp_ko.properties b/src/com/gitblit/wicket/GitBlitWebApp_ko.properties index 18eda26c..bff593da 100644 --- a/src/com/gitblit/wicket/GitBlitWebApp_ko.properties +++ b/src/com/gitblit/wicket/GitBlitWebApp_ko.properties @@ -1,5 +1,5 @@ gb.repository = \uC800\uC7A5\uC18C -gb.owner = \uC18C\uC720\uC790 +gb.repoAdministrators = \uC800\uC7A5\uC18C \uAD00\uB9AC\uC790 gb.description = \uC124\uBA85 gb.lastChange = \uCD5C\uADFC \uBCC0\uACBD gb.refs = refs @@ -94,7 +94,7 @@ gb.zip = zip gb.showReadme = \uB9AC\uB4DC\uBBF8(readme) \uBCF4\uAE30 gb.showReadmeDescription = \uC694\uC57D\uD398\uC774\uC9C0\uC5D0\uC11C \"readme\" \uB9C8\uD06C\uB2E4\uC6B4 \uD30C\uC77C \uBCF4\uAE30 gb.nameDescription = \uC800\uC7A5\uC18C\uB97C \uADF8\uB8F9\uC73C\uB85C \uBB36\uC73C\uB824\uBA74 '/' \uB97C \uC0AC\uC6A9. \uC608) libraries/reponame.git -gb.ownerDescription = \uC18C\uC720\uC790\uB294 \uC800\uC7A5\uC18C \uC124\uC815\uC744 \uBCC0\uACBD\uD560 \uC218 \uC788\uC74C +gb.repoAdministratorsDescription = \uC800\uC7A5\uC18C \uAD00\uB9AC\uC790 \uC800\uC7A5\uC18C \uC124\uC815\uC744 \uBCC0\uACBD\uD560 \uC218 \uC788\uC74C gb.blob = blob gb.commitActivityTrend = \uCEE4\uBC0B \uD65C\uB3D9 \uD2B8\uB79C\uB4DC gb.commitActivityDOW = 1\uC8FC\uC77C\uC758 \uC77C\uB2E8\uC704 \uCEE4\uBC0B \uD65C\uB3D9 @@ -279,7 +279,7 @@ gb.displayName = \uD45C\uC2DC\uB418\uB294 \uC774\uB984 gb.emailAddress = \uC774\uBA54\uC77C \uC8FC\uC18C gb.errorAdminLoginRequired = \uAD00\uB9AC\uB97C \uC704\uD574\uC11C\uB294 \uB85C\uADF8\uC778\uC774 \uD544\uC694 gb.errorOnlyAdminMayCreateRepository = \uAD00\uB9AC\uC790\uB9CC \uC800\uC7A5\uC18C\uB97C \uB9CC\uB4E4\uC218 \uC788\uC74C -gb.errorOnlyAdminOrOwnerMayEditRepository = \uAD00\uB9AC\uC790\uC640 \uC18C\uC720\uC790\uB9CC \uC800\uC7A5\uC18C\uB97C \uC218\uC815\uD560 \uC218 \uC788\uC74C +gb.errorOnlyAdminOrRepoAdminMayEditRepository = \uAD00\uB9AC\uC790\uC640 \uC800\uC7A5\uC18C \uAD00\uB9AC\uC790\uB9CC \uC800\uC7A5\uC18C\uB97C \uC218\uC815\uD560 \uC218 \uC788\uC74C gb.errorAdministrationDisabled = \uAD00\uB9AC\uAE30\uB2A5 \uBE44\uD65C\uC131\uD654\uB428 gb.lastNDays = {0} \uC77C\uC804 gb.completeGravatarProfile = Gravatar.com \uC5D0 \uD504\uB85C\uD30C\uC77C \uC0DD\uC131\uB428 @@ -364,7 +364,7 @@ gb.gcPeriod = GC \uC8FC\uAE30 gb.gcPeriodDescription = \uAC00\uBE44\uC9C0 \uD074\uB809\uC158\uAC04\uC758 \uC2DC\uAC04 \uAC04\uACA9 gb.gcThreshold = GC \uAE30\uC900\uC810 gb.gcThresholdDescription = \uC870\uAE30 \uAC00\uBE44\uC9C0 \uCEEC\uB809\uC158\uC744 \uBC1C\uC0DD\uC2DC\uD0A4\uAE30 \uC704\uD55C \uC624\uBE0C\uC81D\uD2B8\uB4E4\uC758 \uCD5C\uC18C \uC804\uCCB4 \uD06C\uAE30 -gb.ownerPermission = \uC800\uC7A5\uC18C \uC624\uB108 +gb.repoAdministratorPermission = \uC800\uC7A5\uC18C \uAD00\uB9AC\uC790 gb.administrator = \uAD00\uB9AC\uC790 gb.administratorPermission = Gitblit \uAD00\uB9AC\uC790 gb.team = \uD300 diff --git a/src/com/gitblit/wicket/GitBlitWebApp_nl.properties b/src/com/gitblit/wicket/GitBlitWebApp_nl.properties index 5471ad8a..75a0ac61 100644 --- a/src/com/gitblit/wicket/GitBlitWebApp_nl.properties +++ b/src/com/gitblit/wicket/GitBlitWebApp_nl.properties @@ -1,5 +1,5 @@ gb.repository = repositorie -gb.owner = eigenaar +gb.repoAdministrators = repository beheerders gb.description = omschrijving gb.lastChange = laatste wijziging gb.refs = refs @@ -94,7 +94,7 @@ gb.zip = zip gb.showReadme = toon readme gb.showReadmeDescription = toon een \"readme\" Markdown bestand in de samenvattingspagina gb.nameDescription = gebruik '/' voor het groeperen van repositories. bijv. libraries/mycoollib.git -gb.ownerDescription = de eigenaar mag repository instellingen wijzigen +gb.repoAdministratorsDescription = repository beheerders mag repository instellingen wijzigen gb.blob = blob gb.commitActivityTrend = commit activiteit trend gb.commitActivityDOW = commit activiteit per dag van de week @@ -279,7 +279,7 @@ gb.displayName = display naam gb.emailAddress = emailadres gb.errorAdminLoginRequired = Aanmelden vereist voor beheerwerk gb.errorOnlyAdminMayCreateRepository = Alleen een beheerder kan een repositorie maken -gb.errorOnlyAdminOrOwnerMayEditRepository = Alleen een beheerder of de eigenaar kan een repositorie wijzigen +gb.errorOnlyAdminOrOwnerMayEditRepository = Alleen een beheerder of een repository beheerder kan een repositorie wijzigen gb.errorAdministrationDisabled = Beheer is uitgeschakeld gb.lastNDays = laatste {0} dagen gb.completeGravatarProfile = Completeer profiel op Gravatar.com @@ -364,7 +364,7 @@ gb.gcPeriod = opruim periode gb.gcPeriodDescription = tijdsduur tussen opruimacties gb.gcThreshold = opruim drempel gb.gcThresholdDescription = minimum totaalomvang van losse objecten voor het starten van opruimactie -gb.ownerPermission = repositorie eigenaar +gb.repoAdministratorPermission = repository beheerder gb.administrator = beheer gb.administratorPermission = Gitblit beheerder gb.team = team diff --git a/src/com/gitblit/wicket/GitBlitWebApp_pl.properties b/src/com/gitblit/wicket/GitBlitWebApp_pl.properties index 82ffa635..4760981a 100644 --- a/src/com/gitblit/wicket/GitBlitWebApp_pl.properties +++ b/src/com/gitblit/wicket/GitBlitWebApp_pl.properties @@ -1,5 +1,5 @@ gb.repository = Repozytorium -gb.owner = W\u0142a\u015Bciciel +gb.repoAdministrators = Administratorzy repozytorium gb.description = Opis gb.lastChange = Ostatnia zmiana gb.refs = Refs @@ -94,7 +94,7 @@ gb.zip = zip gb.showReadme = Poka\u017C readme gb.showReadmeDescription = Poka\u017C sparsowany \"readme\" na stronie podsumowania gb.nameDescription = u\u017Cyj '/' do grupowania repozytori\u00F3w, np. libraries/server-lib.git -gb.ownerDescription = W\u0142a\u015Bciciel mo\u017Ce edytowa\u0107 ustawienia repozytorium +gb.repoAdministratorsDescription = Administrator repozytorium mo\u017Ce edytowa\u0107 ustawienia repozytorium gb.blob = blob gb.commitActivityTrend = Aktywno\u015B\u0107 zmian gb.commitActivityDOW = Aktywno\u015B\u0107 zmian wed\u0142ug dnia tygodnia @@ -279,7 +279,7 @@ gb.displayName = Wy\u015Bwietlana nazwa gb.emailAddress = Adres email gb.errorAdminLoginRequired = Administracja wymaga zalogowania gb.errorOnlyAdminMayCreateRepository = Tylko administrator mo\u017Ce utworzy\u0107 repozytorium -gb.errorOnlyAdminOrOwnerMayEditRepository = Tylko administrator lub w\u0142a\u015Bciciel mo\u017Ce edytowa\u0107 repozytorium. +gb.errorOnlyAdminOrRepoAdminMayEditRepository = Tylko administrator lub administrator repozytorium mo\u017Ce edytowa\u0107 repozytorium. gb.errorAdministrationDisabled = Administracja jest wy\u0142\u0105czona gb.lastNDays = Ostatnich {0} dni gb.completeGravatarProfile = Pe\u0142ny profil na Gravatar.com diff --git a/src/com/gitblit/wicket/GitBlitWebApp_pt_BR.properties b/src/com/gitblit/wicket/GitBlitWebApp_pt_BR.properties index 469d2055..0bbd119c 100644 --- a/src/com/gitblit/wicket/GitBlitWebApp_pt_BR.properties +++ b/src/com/gitblit/wicket/GitBlitWebApp_pt_BR.properties @@ -1,5 +1,5 @@ gb.repository = repositório -gb.owner = proprietário +gb.repoAdministrators = administradores do repositório gb.description = descrição gb.lastChange = última alteração gb.refs = refs @@ -94,7 +94,7 @@ gb.zip = zip gb.showReadme = mostrar readme gb.showReadmeDescription = mostrar um arquivo \"leia-me\" na página de resumo gb.nameDescription = usar '/' para agrupar repositórios. e.g. libraries/mycoollib.git -gb.ownerDescription = o proprietário pode editar configurações do repositório +gb.repoAdministratorsDescription = o administradores do repositório pode editar configurações do repositório gb.blob = blob gb.commitActivityTrend = tendência dos commits gb.commitActivityDOW = commits diários @@ -279,7 +279,7 @@ gb.displayName = nome gb.emailAddress = e-mail gb.errorAdminLoginRequired = Administração requer um login gb.errorOnlyAdminMayCreateRepository = Somente umadministrador pode criar um repositório -gb.errorOnlyAdminOrOwnerMayEditRepository = Somente umadministrador pode editar um repositório +gb.errorOnlyAdminOrRepoAdminMayEditRepository = Somente umadministrador ou um administrador de repositório pode editar um repositório gb.errorAdministrationDisabled = Administração está desabilitada gb.lastNDays = últimos {0} dias gb.completeGravatarProfile = Profile completo em Gravatar.com @@ -364,7 +364,7 @@ gb.gcPeriod = per gb.gcPeriodDescription = duração entre as coletas de lixo gb.gcThreshold = limite do GC gb.gcThresholdDescription = tamanho total mínimo de objetos \"soltos\" que ativam a coleta de lixo -gb.ownerPermission = proprietário do repositório +gb.repoAdministratorPermission = administrador do repositório gb.administrator = administrador gb.administratorPermission = administrador do Gitblit gb.team = equipe diff --git a/src/com/gitblit/wicket/pages/EditRepositoryPage.html b/src/com/gitblit/wicket/pages/EditRepositoryPage.html index 60893f44..be9616c0 100644 --- a/src/com/gitblit/wicket/pages/EditRepositoryPage.html +++ b/src/com/gitblit/wicket/pages/EditRepositoryPage.html @@ -50,7 +50,7 @@
- + diff --git a/src/com/gitblit/wicket/pages/EditRepositoryPage.java b/src/com/gitblit/wicket/pages/EditRepositoryPage.java index a071b69e..9a81bde4 100644 --- a/src/com/gitblit/wicket/pages/EditRepositoryPage.java +++ b/src/com/gitblit/wicket/pages/EditRepositoryPage.java @@ -61,6 +61,7 @@ import com.gitblit.models.RegistrantAccessPermission; import com.gitblit.models.RepositoryModel; import com.gitblit.models.UserModel; import com.gitblit.utils.ArrayUtils; +import com.gitblit.utils.MultiConfigUtil; import com.gitblit.utils.StringUtils; import com.gitblit.wicket.GitBlitWebSession; import com.gitblit.wicket.StringChoiceRenderer; @@ -70,6 +71,8 @@ import com.gitblit.wicket.panels.RegistrantPermissionsPanel; public class EditRepositoryPage extends RootSubPage { + private MultiConfigUtil multiConfigUtil = new MultiConfigUtil(); + private final boolean isCreate; private boolean isAdmin; @@ -94,7 +97,7 @@ public class EditRepositoryPage extends RootSubPage { // personal create permissions, inject personal repository path model.name = user.getPersonalPath() + "/"; model.projectPath = user.getPersonalPath(); - model.owner = user.username; + model.addRepoAdministrator(user.username); // personal repositories are private by default model.accessRestriction = AccessRestrictionType.VIEW; model.authorizationControl = AuthorizationControl.NAMED; @@ -164,6 +167,12 @@ public class EditRepositoryPage extends RootSubPage { final RegistrantPermissionsPanel teamsPalette = new RegistrantPermissionsPanel("teams", RegistrantType.TEAM, GitBlit.self().getAllTeamnames(), repositoryTeams, getAccessPermissions()); + // repo administrators palette + List admins = multiConfigUtil.convertCollectionToList(repositoryModel.getRepoAdministrators()); + List persons = GitBlit.self().getAllUsernames(); + final Palette repoAdministratorsPalette = new Palette("repoAdministrators", new ListModel(admins), new CollectionModel( + persons), new StringChoiceRenderer(), 10, true); + // indexed local branches palette List allLocalBranches = new ArrayList(); allLocalBranches.add(Constants.DEFAULT_BRANCH); @@ -326,6 +335,12 @@ public class EditRepositoryPage extends RootSubPage { } repositoryModel.indexedBranches = indexedBranches; + repositoryModel.removeAllRepoAdministrators(); + Iterator repoAdmins = repoAdministratorsPalette.getSelectedChoices(); + while (repoAdmins.hasNext()) { + repositoryModel.addRepoAdministrator(repoAdmins.next()); + } + // pre-receive scripts List preReceiveScripts = new ArrayList(); Iterator pres = preReceivePalette.getSelectedChoices(); @@ -377,8 +392,7 @@ public class EditRepositoryPage extends RootSubPage { // field names reflective match RepositoryModel fields form.add(new TextField("name").setEnabled(allowEditName)); form.add(new TextField("description")); - form.add(new DropDownChoice("owner", GitBlit.self().getAllUsernames()) - .setEnabled(GitBlitWebSession.get().canAdmin() && !repositoryModel.isPersonalRepository())); + form.add(repoAdministratorsPalette); form.add(new CheckBox("allowForks").setEnabled(GitBlit.getBoolean(Keys.web.allowForking, true))); DropDownChoice accessRestriction = new DropDownChoice("accessRestriction", Arrays .asList(AccessRestrictionType.values()), new AccessRestrictionRenderer()); @@ -559,9 +573,9 @@ public class EditRepositoryPage extends RootSubPage { isAdmin = true; return; } else { - if (!model.owner.equalsIgnoreCase(user.username)) { - // User is not an Admin nor Owner - error(getString("gb.errorOnlyAdminOrOwnerMayEditRepository"), true); + if (!model.isRepoAdministrator(user.username)) { + // User is not an Admin nor RepoAdministrator + error(getString("gb.errorOnlyAdminOrRepoAdminMayEditRepository"), true); } } } diff --git a/src/com/gitblit/wicket/pages/RepositoryPage.java b/src/com/gitblit/wicket/pages/RepositoryPage.java index aac527d7..b67aaa6d 100644 --- a/src/com/gitblit/wicket/pages/RepositoryPage.java +++ b/src/com/gitblit/wicket/pages/RepositoryPage.java @@ -79,7 +79,7 @@ public abstract class RepositoryPage extends BasePage { private final Map registeredPages; private boolean showAdmin; - private boolean isOwner; + private boolean isRepoAdministrator; public RepositoryPage(PageParameters params) { super(params); @@ -183,10 +183,10 @@ public abstract class RepositoryPage extends BasePage { } else { showAdmin = GitBlit.getBoolean(Keys.web.allowAdministration, false); } - isOwner = GitBlitWebSession.get().isLoggedIn() - && (model.owner != null && model.owner.equalsIgnoreCase(GitBlitWebSession.get() + isRepoAdministrator = GitBlitWebSession.get().isLoggedIn() + && (model.isRepoAdministrator(GitBlitWebSession.get() .getUsername())); - if (showAdmin || isOwner) { + if (showAdmin || isRepoAdministrator) { pages.put("edit", new PageRegistration("gb.edit", EditRepositoryPage.class, params)); } return pages; @@ -540,7 +540,7 @@ public abstract class RepositoryPage extends BasePage { } public boolean isOwner() { - return isOwner; + return isRepoAdministrator; } private class SearchForm extends SessionlessForm implements Serializable { diff --git a/src/com/gitblit/wicket/pages/RootSubPage.java b/src/com/gitblit/wicket/pages/RootSubPage.java index e7e12ccc..ed1bdfbf 100644 --- a/src/com/gitblit/wicket/pages/RootSubPage.java +++ b/src/com/gitblit/wicket/pages/RootSubPage.java @@ -88,7 +88,7 @@ public abstract class RootSubPage extends RootPage { if (repositoryModel.accessRestriction.exceeds(AccessRestrictionType.NONE) && repositoryModel.authorizationControl.equals(AuthorizationControl.NAMED)) { if (user != null && - (repositoryModel.isOwner(user.username) || repositoryModel.isUsersPersonalRepository(user.username))) { + (repositoryModel.isRepoAdministrator(user.username) || repositoryModel.isUsersPersonalRepository(user.username))) { // exclude Owner or personal repositories continue; } diff --git a/src/com/gitblit/wicket/pages/SummaryPage.html b/src/com/gitblit/wicket/pages/SummaryPage.html index 45ffddfb..788dbb57 100644 --- a/src/com/gitblit/wicket/pages/SummaryPage.html +++ b/src/com/gitblit/wicket/pages/SummaryPage.html @@ -16,7 +16,7 @@
 


- + diff --git a/src/com/gitblit/wicket/pages/SummaryPage.java b/src/com/gitblit/wicket/pages/SummaryPage.java index 8df2cebc..3b2c92a1 100644 --- a/src/com/gitblit/wicket/pages/SummaryPage.java +++ b/src/com/gitblit/wicket/pages/SummaryPage.java @@ -49,6 +49,7 @@ import com.gitblit.models.UserModel; import com.gitblit.utils.ArrayUtils; import com.gitblit.utils.JGitUtils; import com.gitblit.utils.MarkdownUtils; +import com.gitblit.utils.MultiConfigUtil; import com.gitblit.utils.StringUtils; import com.gitblit.wicket.WicketUtils; import com.gitblit.wicket.panels.BranchesPanel; @@ -59,6 +60,8 @@ import com.gitblit.wicket.panels.TagsPanel; public class SummaryPage extends RepositoryPage { + private MultiConfigUtil multiConfigUtil = new MultiConfigUtil(); + public SummaryPage(PageParameters params) { super(params); @@ -82,16 +85,12 @@ public class SummaryPage extends RepositoryPage { // repository description add(new Label("repositoryDescription", getRepositoryModel().description)); - String owner = getRepositoryModel().owner; - if (StringUtils.isEmpty(owner)) { - add(new Label("repositoryOwner").setVisible(false)); - } else { - UserModel ownerModel = GitBlit.self().getUserModel(owner); - if (ownerModel != null) { - add(new LinkPanel("repositoryOwner", null, ownerModel.getDisplayName(), UserPage.class, WicketUtils.newUsernameParameter(owner))); - } else { - add(new Label("repositoryOwner", owner)); - } + String repoAdministrators = multiConfigUtil.convertCollectionToSingleLineString(getRepositoryModel().getRepoAdministrators()); + if (StringUtils.isEmpty(repoAdministrators)) { + add(new Label("repositoryAdministrators").setVisible(false)); + } else { + //TODO reimplement link panel for each username + add(new Label("repositoryAdministrators", repoAdministrators)); } add(WicketUtils.createTimestampLabel("repositoryLastChange", diff --git a/src/com/gitblit/wicket/panels/ProjectRepositoryPanel.html b/src/com/gitblit/wicket/panels/ProjectRepositoryPanel.html index 46781536..e953235c 100644 --- a/src/com/gitblit/wicket/panels/ProjectRepositoryPanel.html +++ b/src/com/gitblit/wicket/panels/ProjectRepositoryPanel.html @@ -51,7 +51,7 @@ - [owner] + [owner]
diff --git a/src/com/gitblit/wicket/panels/ProjectRepositoryPanel.java b/src/com/gitblit/wicket/panels/ProjectRepositoryPanel.java index 50f0d52d..d4f2a3a8 100644 --- a/src/com/gitblit/wicket/panels/ProjectRepositoryPanel.java +++ b/src/com/gitblit/wicket/panels/ProjectRepositoryPanel.java @@ -36,6 +36,7 @@ import com.gitblit.SyndicationServlet; import com.gitblit.models.RepositoryModel; import com.gitblit.models.UserModel; import com.gitblit.utils.ArrayUtils; +import com.gitblit.utils.MultiConfigUtil; import com.gitblit.utils.StringUtils; import com.gitblit.wicket.GitBlitWebSession; import com.gitblit.wicket.WicketUtils; @@ -51,86 +52,104 @@ public class ProjectRepositoryPanel extends BasePanel { private static final long serialVersionUID = 1L; - public ProjectRepositoryPanel(String wicketId, Localizer localizer, Component parent, - final boolean isAdmin, final RepositoryModel entry, + private MultiConfigUtil multiConfigUtil = new MultiConfigUtil(); + + public ProjectRepositoryPanel(String wicketId, Localizer localizer, + Component parent, final boolean isAdmin, + final RepositoryModel entry, final Map accessRestrictions) { super(wicketId); - final boolean showSwatch = GitBlit.getBoolean(Keys.web.repositoryListSwatches, true); - final boolean gitServlet = GitBlit.getBoolean(Keys.git.enableGitServlet, true); - final boolean showSize = GitBlit.getBoolean(Keys.web.showRepositorySizes, true); + final boolean showSwatch = GitBlit.getBoolean( + Keys.web.repositoryListSwatches, true); + final boolean gitServlet = GitBlit.getBoolean( + Keys.git.enableGitServlet, true); + final boolean showSize = GitBlit.getBoolean( + Keys.web.showRepositorySizes, true); // repository swatch Component swatch; if (entry.isBare) { - swatch = new Label("repositorySwatch", " ").setEscapeModelStrings(false); + swatch = new Label("repositorySwatch", " ") + .setEscapeModelStrings(false); } else { swatch = new Label("repositorySwatch", "!"); - WicketUtils.setHtmlTooltip(swatch, localizer.getString("gb.workingCopyWarning", parent)); + WicketUtils.setHtmlTooltip(swatch, + localizer.getString("gb.workingCopyWarning", parent)); } WicketUtils.setCssBackground(swatch, entry.toString()); add(swatch); swatch.setVisible(showSwatch); PageParameters pp = WicketUtils.newRepositoryParameter(entry.name); - add(new LinkPanel("repositoryName", "list", StringUtils.getRelativePath(entry.projectPath, - StringUtils.stripDotGit(entry.name)), SummaryPage.class, pp)); - add(new Label("repositoryDescription", entry.description).setVisible(!StringUtils - .isEmpty(entry.description))); + add(new LinkPanel("repositoryName", "list", + StringUtils.getRelativePath(entry.projectPath, + StringUtils.stripDotGit(entry.name)), + SummaryPage.class, pp)); + add(new Label("repositoryDescription", entry.description) + .setVisible(!StringUtils.isEmpty(entry.description))); if (StringUtils.isEmpty(entry.originRepository)) { add(new Label("originRepository").setVisible(false)); } else { - Fragment forkFrag = new Fragment("originRepository", "originFragment", this); - forkFrag.add(new LinkPanel("originRepository", null, StringUtils.stripDotGit(entry.originRepository), - SummaryPage.class, WicketUtils.newRepositoryParameter(entry.originRepository))); + Fragment forkFrag = new Fragment("originRepository", + "originFragment", this); + forkFrag.add(new LinkPanel("originRepository", null, StringUtils + .stripDotGit(entry.originRepository), SummaryPage.class, + WicketUtils.newRepositoryParameter(entry.originRepository))); add(forkFrag); } - add(new BookmarkablePageLink("tickets", TicketsPage.class, pp).setVisible(entry.useTickets)); - add(new BookmarkablePageLink("docs", DocsPage.class, pp).setVisible(entry.useDocs)); + add(new BookmarkablePageLink("tickets", TicketsPage.class, pp) + .setVisible(entry.useTickets)); + add(new BookmarkablePageLink("docs", DocsPage.class, pp) + .setVisible(entry.useDocs)); if (entry.isFrozen) { - add(WicketUtils.newImage("frozenIcon", "cold_16x16.png", localizer.getString("gb.isFrozen", parent))); + add(WicketUtils.newImage("frozenIcon", "cold_16x16.png", + localizer.getString("gb.isFrozen", parent))); } else { add(WicketUtils.newClearPixel("frozenIcon").setVisible(false)); } if (entry.isFederated) { - add(WicketUtils.newImage("federatedIcon", "federated_16x16.png", localizer.getString("gb.isFederated", parent))); + add(WicketUtils.newImage("federatedIcon", "federated_16x16.png", + localizer.getString("gb.isFederated", parent))); } else { add(WicketUtils.newClearPixel("federatedIcon").setVisible(false)); } switch (entry.accessRestriction) { case NONE: - add(WicketUtils.newBlankImage("accessRestrictionIcon").setVisible(false)); + add(WicketUtils.newBlankImage("accessRestrictionIcon").setVisible( + false)); break; case PUSH: - add(WicketUtils.newImage("accessRestrictionIcon", "lock_go_16x16.png", + add(WicketUtils.newImage("accessRestrictionIcon", + "lock_go_16x16.png", accessRestrictions.get(entry.accessRestriction))); break; case CLONE: - add(WicketUtils.newImage("accessRestrictionIcon", "lock_pull_16x16.png", + add(WicketUtils.newImage("accessRestrictionIcon", + "lock_pull_16x16.png", accessRestrictions.get(entry.accessRestriction))); break; case VIEW: - add(WicketUtils.newImage("accessRestrictionIcon", "shield_16x16.png", + add(WicketUtils.newImage("accessRestrictionIcon", + "shield_16x16.png", accessRestrictions.get(entry.accessRestriction))); break; default: add(WicketUtils.newBlankImage("accessRestrictionIcon")); } - if (StringUtils.isEmpty(entry.owner)) { - add(new Label("repositoryOwner").setVisible(false)); + if (entry.getRepoAdministrators().size() < 1) { + add(new Label("repositoryAdministrators").setVisible(false)); } else { - UserModel ownerModel = GitBlit.self().getUserModel(entry.owner); - String owner = entry.owner; - if (ownerModel != null) { - owner = ownerModel.getDisplayName(); - } - add(new Label("repositoryOwner", owner + " (" + - localizer.getString("gb.owner", parent) + ")")); + add(new Label("repositoryAdministrators", + multiConfigUtil.convertCollectionToSingleLineString(entry + .getRepoAdministrators()) + + " (" + + localizer.getString("gb.repoAdministrators", parent) + ")")); } UserModel user = GitBlitWebSession.get().getUser(); @@ -138,15 +157,19 @@ public class ProjectRepositoryPanel extends BasePanel { user = UserModel.ANONYMOUS; } Fragment repositoryLinks; - boolean showOwner = entry.isOwner(user.username); + boolean isRepoAdministrator = entry.isRepoAdministrator(user.username); // owner of personal repository gets admin powers - boolean showAdmin = isAdmin || entry.isUsersPersonalRepository(user.username); - - if (showAdmin || showOwner) { - repositoryLinks = new Fragment("repositoryLinks", showAdmin ? "repositoryAdminLinks" - : "repositoryOwnerLinks", this); - repositoryLinks.add(new BookmarkablePageLink("editRepository", EditRepositoryPage.class, - WicketUtils.newRepositoryParameter(entry.name))); + boolean showAdmin = isAdmin + || entry.isUsersPersonalRepository(user.username); + + if (showAdmin || isRepoAdministrator) { + repositoryLinks = new Fragment( + "repositoryLinks", + showAdmin ? "repositoryAdminLinks" : "repositoryOwnerLinks", + this); + repositoryLinks.add(new BookmarkablePageLink( + "editRepository", EditRepositoryPage.class, WicketUtils + .newRepositoryParameter(entry.name))); if (showAdmin) { Link deleteLink = new Link("deleteRepository") { @@ -157,28 +180,41 @@ public class ProjectRepositoryPanel extends BasePanel { if (GitBlit.self().deleteRepositoryModel(entry)) { // redirect to the owning page if (entry.isPersonalRepository()) { - setResponsePage(getPage().getClass(), WicketUtils.newUsernameParameter(entry.projectPath.substring(1))); + setResponsePage( + getPage().getClass(), + WicketUtils + .newUsernameParameter(entry.projectPath + .substring(1))); } else { - setResponsePage(getPage().getClass(), WicketUtils.newProjectParameter(entry.projectPath)); + setResponsePage( + getPage().getClass(), + WicketUtils + .newProjectParameter(entry.projectPath)); } } else { - error(MessageFormat.format(getString("gb.repositoryDeleteFailed"), entry)); + error(MessageFormat.format( + getString("gb.repositoryDeleteFailed"), + entry)); } } }; - deleteLink.add(new JavascriptEventConfirmation("onclick", MessageFormat.format( - localizer.getString("gb.deleteRepository", parent), entry))); + deleteLink.add(new JavascriptEventConfirmation("onclick", + MessageFormat.format(localizer.getString( + "gb.deleteRepository", parent), entry))); repositoryLinks.add(deleteLink); } } else { - repositoryLinks = new Fragment("repositoryLinks", "repositoryUserLinks", this); + repositoryLinks = new Fragment("repositoryLinks", + "repositoryUserLinks", this); } - repositoryLinks.add(new BookmarkablePageLink("tree", TreePage.class, WicketUtils - .newRepositoryParameter(entry.name)).setEnabled(entry.hasCommits)); + repositoryLinks.add(new BookmarkablePageLink("tree", + TreePage.class, WicketUtils.newRepositoryParameter(entry.name)) + .setEnabled(entry.hasCommits)); - repositoryLinks.add(new BookmarkablePageLink("log", LogPage.class, WicketUtils - .newRepositoryParameter(entry.name)).setEnabled(entry.hasCommits)); + repositoryLinks.add(new BookmarkablePageLink("log", + LogPage.class, WicketUtils.newRepositoryParameter(entry.name)) + .setEnabled(entry.hasCommits)); add(repositoryLinks); @@ -190,17 +226,20 @@ public class ProjectRepositoryPanel extends BasePanel { } Label lastChangeLabel = new Label("repositoryLastChange", lastChange); add(lastChangeLabel); - WicketUtils.setCssClass(lastChangeLabel, getTimeUtils().timeAgoCss(entry.lastChange)); + WicketUtils.setCssClass(lastChangeLabel, + getTimeUtils().timeAgoCss(entry.lastChange)); if (entry.hasCommits) { // Existing repository add(new Label("repositorySize", entry.size).setVisible(showSize)); } else { // New repository - add(new Label("repositorySize", localizer.getString("gb.empty", parent)).setEscapeModelStrings(false)); + add(new Label("repositorySize", localizer.getString("gb.empty", + parent)).setEscapeModelStrings(false)); } - add(new ExternalLink("syndication", SyndicationServlet.asLink("", entry.name, null, 0))); + add(new ExternalLink("syndication", SyndicationServlet.asLink("", + entry.name, null, 0))); List repositoryUrls = new ArrayList(); if (gitServlet) { @@ -209,7 +248,8 @@ public class ProjectRepositoryPanel extends BasePanel { } repositoryUrls.addAll(GitBlit.self().getOtherCloneUrls(entry.name)); - String primaryUrl = ArrayUtils.isEmpty(repositoryUrls) ? "" : repositoryUrls.remove(0); + String primaryUrl = ArrayUtils.isEmpty(repositoryUrls) ? "" + : repositoryUrls.remove(0); add(new RepositoryUrlPanel("repositoryCloneUrl", primaryUrl)); } } diff --git a/src/com/gitblit/wicket/panels/RegistrantPermissionsPanel.java b/src/com/gitblit/wicket/panels/RegistrantPermissionsPanel.java index 4156cd19..b3efdd80 100644 --- a/src/com/gitblit/wicket/panels/RegistrantPermissionsPanel.java +++ b/src/com/gitblit/wicket/panels/RegistrantPermissionsPanel.java @@ -162,8 +162,8 @@ public class RegistrantPermissionsPanel extends BasePanel { item.add(administrator); break; case OWNER: - Label owner = new Label("pType", getString("gb.owner")); - WicketUtils.setHtmlTooltip(owner, getString("gb.ownerPermission")); + Label owner = new Label("pType", getString("gb.repoAdministrators")); + WicketUtils.setHtmlTooltip(owner, getString("gb.repoAdministratorPermission")); WicketUtils.setCssClass(owner, "label label-info"); item.add(owner); break; diff --git a/src/com/gitblit/wicket/panels/RepositoriesPanel.html b/src/com/gitblit/wicket/panels/RepositoriesPanel.html index 42f9f1f2..98ff4308 100644 --- a/src/com/gitblit/wicket/panels/RepositoriesPanel.html +++ b/src/com/gitblit/wicket/panels/RepositoriesPanel.html @@ -57,7 +57,7 @@ Repository
- + @@ -72,7 +72,7 @@ Repository - + @@ -88,7 +88,7 @@ - + diff --git a/src/com/gitblit/wicket/panels/RepositoriesPanel.java b/src/com/gitblit/wicket/panels/RepositoriesPanel.java index 976c517f..c6c57a79 100644 --- a/src/com/gitblit/wicket/panels/RepositoriesPanel.java +++ b/src/com/gitblit/wicket/panels/RepositoriesPanel.java @@ -49,6 +49,7 @@ import com.gitblit.SyndicationServlet; import com.gitblit.models.ProjectModel; import com.gitblit.models.RepositoryModel; import com.gitblit.models.UserModel; +import com.gitblit.utils.MultiConfigUtil; import com.gitblit.utils.StringUtils; import com.gitblit.wicket.GitBlitWebSession; import com.gitblit.wicket.WicketUtils; @@ -64,6 +65,8 @@ public class RepositoriesPanel extends BasePanel { private static final long serialVersionUID = 1L; + private MultiConfigUtil multiConfigUtil = new MultiConfigUtil(); + public RepositoriesPanel(String wicketId, final boolean showAdmin, final boolean showManagement, List models, boolean enableLinks, final Map accessRestrictionTranslations) { @@ -287,14 +290,7 @@ public class RepositoriesPanel extends BasePanel { row.add(WicketUtils.newBlankImage("accessRestrictionIcon")); } - String owner = entry.owner; - if (!StringUtils.isEmpty(owner)) { - UserModel ownerModel = GitBlit.self().getUserModel(owner); - if (ownerModel != null) { - owner = ownerModel.getDisplayName(); - } - } - row.add(new Label("repositoryOwner", owner)); + row.add(new Label("repositoryAdministrators", multiConfigUtil.convertCollectionToSingleLineString(entry.getRepoAdministrators()))); String lastChange; if (entry.lastChange.getTime() == 0) { @@ -306,42 +302,29 @@ public class RepositoriesPanel extends BasePanel { row.add(lastChangeLabel); WicketUtils.setCssClass(lastChangeLabel, getTimeUtils().timeAgoCss(entry.lastChange)); - boolean showOwner = user != null && entry.isOwner(user.username); - boolean myPersonalRepository = showOwner && entry.isUsersPersonalRepository(user.username); + boolean isRepoAdministrator = user != null && entry.isRepoAdministrator(user.username); + boolean myPersonalRepository = isRepoAdministrator && entry.isUsersPersonalRepository(user.username); if (showAdmin || myPersonalRepository) { Fragment repositoryLinks = new Fragment("repositoryLinks", "repositoryAdminLinks", this); repositoryLinks.add(new BookmarkablePageLink("editRepository", EditRepositoryPage.class, WicketUtils .newRepositoryParameter(entry.name))); - Link deleteLink = new Link("deleteRepository") { - - private static final long serialVersionUID = 1L; - - @Override - public void onClick() { - if (GitBlit.self().deleteRepositoryModel(entry)) { - if (dp instanceof SortableRepositoriesProvider) { - info(MessageFormat.format(getString("gb.repositoryDeleted"), entry)); - ((SortableRepositoriesProvider) dp).remove(entry); - } else { - setResponsePage(getPage().getClass(), getPage().getPageParameters()); - } - } else { - error(MessageFormat.format(getString("gb.repositoryDeleteFailed"), entry)); - } - } - }; + Link deleteLink = new DeleteLink(entry, dp); deleteLink.add(new JavascriptEventConfirmation("onclick", MessageFormat.format( getString("gb.deleteRepository"), entry))); repositoryLinks.add(deleteLink); row.add(repositoryLinks); - } else if (showOwner) { + } else if (isRepoAdministrator) { Fragment repositoryLinks = new Fragment("repositoryLinks", - "repositoryOwnerLinks", this); + "repositoryAdminLinks", this); repositoryLinks.add(new BookmarkablePageLink("editRepository", EditRepositoryPage.class, WicketUtils .newRepositoryParameter(entry.name))); + Link deleteLink = new DeleteLink(entry, dp); + deleteLink.add(new JavascriptEventConfirmation("onclick", MessageFormat.format( + getString("gb.deleteRepository"), entry))); + repositoryLinks.add(deleteLink); row.add(repositoryLinks); } else { row.add(new Label("repositoryLinks")); @@ -370,6 +353,35 @@ public class RepositoriesPanel extends BasePanel { } } + private class DeleteLink extends Link { + private RepositoryModel entry; + + private IDataProvider dp; + + private static final long serialVersionUID = 1L; + + public DeleteLink(RepositoryModel entry, IDataProvider dp) { + super("deleteRepository"); + this.entry=entry; + this.dp=dp; + } + + @Override + public void onClick() { + if (GitBlit.self().deleteRepositoryModel(entry)) { + if (dp instanceof SortableRepositoriesProvider) { + info(MessageFormat.format(getString("gb.repositoryDeleted"), entry)); + ((SortableRepositoriesProvider) dp).remove(entry); + } else { + setResponsePage(getPage().getClass(), getPage().getPageParameters()); + } + } else { + error(MessageFormat.format(getString("gb.repositoryDeleteFailed"), entry)); + } + } + + } + private static class GroupRepositoryModel extends RepositoryModel { private static final long serialVersionUID = 1L; @@ -463,6 +475,8 @@ public class RepositoriesPanel extends BasePanel { private List list; + private MultiConfigUtil multiConfigUtil = new MultiConfigUtil(); + protected SortableRepositoriesProvider(List list) { this.list = list; setSort(SortBy.date.name(), false); @@ -516,9 +530,9 @@ public class RepositoriesPanel extends BasePanel { @Override public int compare(RepositoryModel o1, RepositoryModel o2) { if (asc) { - return o1.owner.compareTo(o2.owner); + return multiConfigUtil.convertCollectionToSingleLineString(o1.getRepoAdministrators()).compareTo(multiConfigUtil.convertCollectionToSingleLineString(o2.getRepoAdministrators())); } - return o2.owner.compareTo(o1.owner); + return multiConfigUtil.convertCollectionToSingleLineString(o2.getRepoAdministrators()).compareTo(multiConfigUtil.convertCollectionToSingleLineString(o1.getRepoAdministrators())); } }); } else if (prop.equals(SortBy.description.name())) { -- cgit v1.2.3
[description][repository description]
[owner][repository owner]
[owner][repository owner]
[last change][repository last change]
[stats][branch stats] [metrics]
[URL] [repository clone url]
DescriptionOwnerOwner Last Change DescriptionOwnerOwner Last Change [repository name] [repository description][repository owner][repository owner] [last change] [repository size]