瀏覽代碼

Revised multiple owners contribution

tags/v1.3.0
James Moger 11 年之前
父節點
當前提交
661db6c294
共有 36 個檔案被更改,包括 370 行新增454 行删除
  1. 18
    30
      src/com/gitblit/GitBlit.java
  2. 1
    1
      src/com/gitblit/GitFilter.java
  3. 10
    14
      src/com/gitblit/client/EditRepositoryDialog.java
  4. 2
    2
      src/com/gitblit/client/EditUserDialog.java
  5. 2
    2
      src/com/gitblit/client/GitblitClient.java
  6. 1
    1
      src/com/gitblit/client/JPalette.java
  7. 2
    2
      src/com/gitblit/client/RegistrantPermissionsPanel.java
  8. 2
    5
      src/com/gitblit/client/RepositoriesPanel.java
  9. 3
    2
      src/com/gitblit/client/RepositoriesTableModel.java
  10. 50
    60
      src/com/gitblit/models/RepositoryModel.java
  11. 4
    4
      src/com/gitblit/models/UserModel.java
  12. 30
    0
      src/com/gitblit/utils/ArrayUtils.java
  13. 0
    89
      src/com/gitblit/utils/MultiConfigUtil.java
  14. 0
    24
      src/com/gitblit/utils/StringComparator.java
  15. 6
    5
      src/com/gitblit/wicket/GitBlitWebApp.properties
  16. 3
    3
      src/com/gitblit/wicket/GitBlitWebApp_es.properties
  17. 3
    3
      src/com/gitblit/wicket/GitBlitWebApp_ja.properties
  18. 4
    4
      src/com/gitblit/wicket/GitBlitWebApp_ko.properties
  19. 4
    4
      src/com/gitblit/wicket/GitBlitWebApp_nl.properties
  20. 3
    3
      src/com/gitblit/wicket/GitBlitWebApp_pl.properties
  21. 4
    4
      src/com/gitblit/wicket/GitBlitWebApp_pt_BR.properties
  22. 1
    1
      src/com/gitblit/wicket/pages/EditRepositoryPage.html
  23. 15
    17
      src/com/gitblit/wicket/pages/EditRepositoryPage.java
  24. 5
    5
      src/com/gitblit/wicket/pages/RepositoryPage.java
  25. 1
    1
      src/com/gitblit/wicket/pages/RootSubPage.java
  26. 6
    2
      src/com/gitblit/wicket/pages/SummaryPage.html
  27. 26
    11
      src/com/gitblit/wicket/pages/SummaryPage.java
  28. 1
    1
      src/com/gitblit/wicket/panels/ProjectRepositoryPanel.html
  29. 61
    93
      src/com/gitblit/wicket/panels/ProjectRepositoryPanel.java
  30. 2
    2
      src/com/gitblit/wicket/panels/RegistrantPermissionsPanel.java
  31. 3
    3
      src/com/gitblit/wicket/panels/RepositoriesPanel.html
  32. 44
    46
      src/com/gitblit/wicket/panels/RepositoriesPanel.java
  33. 1
    1
      tests/com/gitblit/tests/FederationTests.java
  34. 3
    5
      tests/com/gitblit/tests/GitServletTest.java
  35. 48
    3
      tests/com/gitblit/tests/PermissionsTest.java
  36. 1
    1
      tests/com/gitblit/tests/RpcTests.java

+ 18
- 30
src/com/gitblit/GitBlit.java 查看文件

@@ -109,7 +109,6 @@ 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;
@@ -181,8 +180,6 @@ public class GitBlit implements ServletContextListener {
private TimeZone timezone;
private FileBasedConfig projectConfigs;
private MultiConfigUtil multiConfigUtil = new MultiConfigUtil();
public GitBlit() {
if (gitblit == null) {
@@ -825,7 +822,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.isRepoAdministrator(user.username)) {
if (rm.isUsersPersonalRepository(user.username) || rm.isOwner(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
@@ -939,14 +936,14 @@ public class GitBlit implements ServletContextListener {
for (RepositoryModel model : getRepositoryModels(user)) {
if (model.isUsersPersonalRepository(username)) {
// personal repository
model.addRepoAdministrator(user.username);
model.addOwner(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.isRepoAdministrator(username)) {
} else if (model.isOwner(username)) {
// common/shared repo
model.addRepoAdministrator(user.username);
model.addOwner(user.username);
updateRepositoryModel(model.name, model, false);
}
}
@@ -1665,7 +1662,7 @@ public class GitBlit implements ServletContextListener {
if (config != null) {
model.description = getConfig(config, "description", "");
model.addRepoAdministrators(multiConfigUtil.convertStringToSet(getConfig(config, "owner", "")));
model.addOwners(ArrayUtils.fromString(getConfig(config, "owner", "")));
model.useTickets = getConfig(config, "useTickets", false);
model.useDocs = getConfig(config, "useDocs", false);
model.allowForks = getConfig(config, "allowForks", true);
@@ -2172,7 +2169,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", multiConfigUtil.convertCollectionToSingleLineString(repository.getRepoAdministrators()));
config.setString(Constants.CONFIG_GITBLIT, null, "owner", ArrayUtils.toString(repository.owners));
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);
@@ -3082,15 +3079,9 @@ public class GitBlit implements ServletContextListener {
}
// schedule lucene engine
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);
}
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.");
@@ -3258,23 +3249,20 @@ public class GitBlit implements ServletContextListener {
// create a Gitblit repository model for the clone
RepositoryModel cloneModel = repository.cloneAs(cloneName);
// owner has REWIND/RW+ permissions
cloneModel.addRepoAdministrator(user.username);
// owner has REWIND/RW+ permissions
cloneModel.addOwner(user.username);
updateRepositoryModel(cloneName, cloneModel, false);
// add the owner of the source repository to the clone's access list
Set<String> 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);
}
if (!ArrayUtils.isEmpty(repository.owners)) {
for (String owner : repository.owners) {
UserModel originOwner = getUserModel(owner);
if (originOwner != null) {
originOwner.setRepositoryPermission(cloneName, AccessPermission.CLONE);
updateUserModel(originOwner.username, originOwner, false);
}
}
}
}
// grant origin's user list clone permission to fork
List<String> users = getRepositoryUsers(repository);

+ 1
- 1
src/com/gitblit/GitFilter.java 查看文件

@@ -222,7 +222,7 @@ public class GitFilter extends AccessRestrictionFilter {
// create repository
RepositoryModel model = new RepositoryModel();
model.name = repository;
model.addRepoAdministrator(user.username);
model.addOwner(user.username);
model.projectPath = StringUtils.getFirstPathElement(repository);
if (model.isUsersPersonalRepository(user.username)) {
// personal repository, default to private for user

+ 10
- 14
src/com/gitblit/client/EditRepositoryDialog.java 查看文件

@@ -38,7 +38,6 @@ import java.util.Set;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListCellRenderer;
import javax.swing.ImageIcon;
import javax.swing.JButton;
@@ -117,7 +116,7 @@ public class EditRepositoryDialog extends JDialog {
private JComboBox federationStrategy;
private JComboBox ownerField;
private JPalette<String> ownersPalette;
private JComboBox headRefField;
@@ -126,7 +125,7 @@ public class EditRepositoryDialog extends JDialog {
private JTextField gcThreshold;
private JComboBox maxActivityCommits;
private RegistrantPermissionsPanel usersPalette;
private JPalette<String> setsPalette;
@@ -207,7 +206,7 @@ public class EditRepositoryDialog extends JDialog {
gcThreshold = new JTextField(8);
gcThreshold.setText(anRepository.gcThreshold);
ownerField = new JComboBox();
ownersPalette = new JPalette<String>(true);
useTickets = new JCheckBox(Translation.get("gb.useTicketsDescription"),
anRepository.useTickets);
@@ -334,10 +333,10 @@ 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.repoAdministrators"), ownerField));
JPanel northFieldsPanel = new JPanel(new BorderLayout(0, 5));
northFieldsPanel.add(newFieldPanel(Translation.get("gb.owners"), ownersPalette), BorderLayout.NORTH);
northFieldsPanel.add(newFieldPanel(Translation.get("gb.accessRestriction"),
accessRestriction), BorderLayout.NORTH);
accessRestriction), BorderLayout.CENTER);
JPanel northAccessPanel = new JPanel(new BorderLayout(5, 5));
northAccessPanel.add(northFieldsPanel, BorderLayout.NORTH);
@@ -556,8 +555,8 @@ public class EditRepositoryDialog extends JDialog {
repository.name = rname;
repository.description = descriptionField.getText();
repository.addRepoAdministrator(ownerField.getSelectedItem() == null ? null
: ownerField.getSelectedItem().toString());
repository.owners.clear();
repository.owners.addAll(ownersPalette.getSelections());
repository.HEAD = headRefField.getSelectedItem() == null ? null
: headRefField.getSelectedItem().toString();
repository.gcPeriod = (Integer) gcPeriod.getSelectedItem();
@@ -629,11 +628,8 @@ public class EditRepositoryDialog extends JDialog {
this.allowNamed.setSelected(!authenticated);
}
public void setUsers(String owner, List<String> all, List<RegistrantAccessPermission> permissions) {
ownerField.setModel(new DefaultComboBoxModel(all.toArray()));
if (!StringUtils.isEmpty(owner)) {
ownerField.setSelectedItem(owner);
}
public void setUsers(List<String> owners, List<String> all, List<RegistrantAccessPermission> permissions) {
ownersPalette.setObjects(all, owners);
usersPalette.setObjects(all, permissions);
}

+ 2
- 2
src/com/gitblit/client/EditUserDialog.java 查看文件

@@ -389,7 +389,7 @@ public class EditUserDialog extends JDialog {
List<String> restricted = new ArrayList<String>();
for (RepositoryModel repo : repositories) {
// exclude Owner or personal repositories
if (!repo.isRepoAdministrator(username) && !repo.isUsersPersonalRepository(username)) {
if (!repo.isOwner(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.isRepoAdministrator(username);
boolean isOwner = rm.isOwner(username);
if (isOwner) {
permission.permissionType = PermissionType.OWNER;
permission.mutable = false;

+ 2
- 2
src/com/gitblit/client/GitblitClient.java 查看文件

@@ -162,7 +162,7 @@ public class GitblitClient implements Serializable {
}
public boolean isOwner(RepositoryModel model) {
return model.isRepoAdministrator(account);
return model.isOwner(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.isRepoAdministrator(user.username)) {
if (rm.isUsersPersonalRepository(user.username) || rm.isOwner(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

+ 1
- 1
src/com/gitblit/client/JPalette.java 查看文件

@@ -144,7 +144,7 @@ public class JPalette<T> extends JPanel {
table.getColumn(table.getColumnName(0)).setCellRenderer(nameRenderer);
JScrollPane jsp = new JScrollPane(table);
jsp.setPreferredSize(new Dimension(225, 175));
jsp.setPreferredSize(new Dimension(225, 160));
JPanel panel = new JPanel(new BorderLayout());
JLabel jlabel = new JLabel(label);
jlabel.setFont(jlabel.getFont().deriveFont(Font.BOLD));

+ 2
- 2
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.repoAdministrators"));
setToolTipText(Translation.get("gb.repoAdministratorPermission"));
setText(Translation.get("gb.owner"));
setToolTipText(Translation.get("gb.ownerPermission"));
break;
case TEAM:
setText(ap.source == null ? Translation.get("gb.team") : ap.source);

+ 2
- 5
src/com/gitblit/client/RepositoriesPanel.java 查看文件

@@ -49,10 +49,9 @@ import javax.swing.table.TableRowSorter;
import com.gitblit.Constants;
import com.gitblit.Constants.RpcRequest;
import com.gitblit.Keys;
import com.gitblit.models.RegistrantAccessPermission;
import com.gitblit.models.FeedModel;
import com.gitblit.models.RegistrantAccessPermission;
import com.gitblit.models.RepositoryModel;
import com.gitblit.utils.MultiConfigUtil;
import com.gitblit.utils.StringUtils;
/**
@@ -85,8 +84,6 @@ public abstract class RepositoriesPanel extends JPanel {
private JTextField filterTextfield;
private JButton clearCache;
private MultiConfigUtil multiConfigUtil = new MultiConfigUtil();
public RepositoriesPanel(GitblitClient gitblit) {
super();
@@ -456,7 +453,7 @@ public abstract class RepositoriesPanel extends JPanel {
dialog.setLocationRelativeTo(RepositoriesPanel.this);
List<String> usernames = gitblit.getUsernames();
List<RegistrantAccessPermission> members = gitblit.getUserAccessPermissions(repository);
dialog.setUsers(multiConfigUtil.convertCollectionToSingleLineString(repository.getRepoAdministrators()), usernames, members);
dialog.setUsers(new ArrayList<String>(repository.owners), usernames, members);
dialog.setTeams(gitblit.getTeamnames(), gitblit.getTeamAccessPermissions(repository));
dialog.setRepositories(gitblit.getRepositories());
dialog.setFederationSets(gitblit.getFederationSets(), repository.federationSets);

+ 3
- 2
src/com/gitblit/client/RepositoriesTableModel.java 查看文件

@@ -23,6 +23,7 @@ import java.util.List;
import javax.swing.table.AbstractTableModel;
import com.gitblit.models.RepositoryModel;
import com.gitblit.utils.ArrayUtils;
/**
* Table model of a list of repositories.
@@ -73,7 +74,7 @@ public class RepositoriesTableModel extends AbstractTableModel {
case Description:
return Translation.get("gb.description");
case Owner:
return Translation.get("gb.repoAdministrators");
return Translation.get("gb.owner");
case Last_Change:
return Translation.get("gb.lastChange");
case Size:
@@ -111,7 +112,7 @@ public class RepositoriesTableModel extends AbstractTableModel {
case Description:
return model.description;
case Owner:
return model.getRepoAdministrators();
return ArrayUtils.toString(model.owners);
case Indicators:
return model;
case Last_Change:

+ 50
- 60
src/com/gitblit/models/RepositoryModel.java 查看文件

@@ -17,20 +17,17 @@ package com.gitblit.models;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
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;
/**
@@ -40,15 +37,14 @@ import com.gitblit.utils.StringUtils;
* @author James Moger
*
*/
public class RepositoryModel implements Serializable,
Comparable<RepositoryModel> {
public class RepositoryModel implements Serializable, Comparable<RepositoryModel> {
private static final long serialVersionUID = 1L;
// field names are reflectively mapped in EditRepository page
public String name;
public String description;
private Set<String> repoAdministrators = new TreeSet<String>(new StringComparator());
public List<String> owners;
public Date lastChange;
public boolean hasCommits;
public boolean showRemoteBranches;
@@ -84,29 +80,28 @@ public class RepositoryModel implements Serializable,
public String gcThreshold;
public int gcPeriod;
public int maxActivityCommits;
public transient boolean isCollectingGarbage;
public Date lastGC;
private MultiConfigUtil multiConfigUtil = new MultiConfigUtil();
public RepositoryModel() {
this("", "", "", new Date(0));
}
public RepositoryModel(String name, String description, String owner,
Date lastchange) {
public RepositoryModel(String name, String description, String owner, Date lastchange) {
this.name = name;
this.description = description;
this.addRepoAdministrator(owner);
this.description = description;
this.lastChange = lastchange;
this.accessRestriction = AccessRestrictionType.NONE;
this.authorizationControl = AuthorizationControl.NAMED;
this.federationSets = new ArrayList<String>();
this.federationStrategy = FederationStrategy.FEDERATE_THIS;
this.federationStrategy = FederationStrategy.FEDERATE_THIS;
this.projectPath = StringUtils.getFirstPathElement(name);
this.owners = new ArrayList<String>();
addOwner(owner);
}
public List<String> getLocalBranches() {
if (ArrayUtils.isEmpty(availableRefs)) {
return new ArrayList<String>();
@@ -119,30 +114,30 @@ public class RepositoryModel implements Serializable,
}
return localBranches;
}
public void addFork(String repository) {
if (forks == null) {
forks = new TreeSet<String>();
}
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) {
@@ -163,25 +158,30 @@ public class RepositoryModel implements Serializable,
public int compareTo(RepositoryModel o) {
return StringUtils.compareRepositoryNames(name, o.name);
}
public boolean isFork() {
return !StringUtils.isEmpty(originRepository);
}
public boolean isOwner(String username) {
if (StringUtils.isEmpty(username) || ArrayUtils.isEmpty(owners)) {
return false;
}
return owners.contains(username.toLowerCase());
}
public boolean isPersonalRepository() {
return !StringUtils.isEmpty(projectPath)
&& projectPath.charAt(0) == '~';
return !StringUtils.isEmpty(projectPath) && projectPath.charAt(0) == '~';
}
public boolean isUsersPersonalRepository(String username) {
return !StringUtils.isEmpty(projectPath)
&& projectPath.equalsIgnoreCase("~" + username);
return !StringUtils.isEmpty(projectPath) && projectPath.equalsIgnoreCase("~" + username);
}
public boolean allowAnonymousView() {
return !accessRestriction.atLeast(AccessRestrictionType.VIEW);
}
public RepositoryModel cloneAs(String cloneName) {
RepositoryModel clone = new RepositoryModel();
clone.originRepository = name;
@@ -202,46 +202,36 @@ public class RepositoryModel implements Serializable,
return clone;
}
public void addRepoAdministrator(String repoAdministrator) {
if (repoAdministrator != null && repoAdministrator.trim().length() > 0) {
this.repoAdministrators.add(repoAdministrator.toLowerCase());
public void addOwner(String username) {
if (!StringUtils.isEmpty(username)) {
String name = username.toLowerCase();
// a set would be more efficient, but this complicates JSON
// deserialization so we enforce uniqueness with an arraylist
if (!owners.contains(name)) {
owners.add(name);
}
}
}
public void removeRepoAdministrator(String repoAdministrator) {
if (repoAdministrator != null && repoAdministrator.trim().length() > 0) {
this.repoAdministrators.remove(repoAdministrator.toLowerCase());
public void removeOwner(String username) {
if (!StringUtils.isEmpty(username)) {
owners.remove(username.toLowerCase());
}
}
public void addRepoAdministrators(Set<String> repoAdministrators) {
if (repoAdministrators != null) {
for (String admin : repoAdministrators) {
this.addRepoAdministrator(admin);
public void addOwners(Collection<String> usernames) {
if (!ArrayUtils.isEmpty(usernames)) {
for (String username : usernames) {
addOwner(username);
}
}
}
public void removeRepoAdministrators(Set<String> repoAdministrators) {
if (repoAdministrators != null) {
for (String admin : repoAdministrators) {
this.removeRepoAdministrator(admin);
public void removeOwners(Collection<String> usernames) {
if (!ArrayUtils.isEmpty(owners)) {
for (String username : usernames) {
removeOwner(username);
}
}
}
public void removeAllRepoAdministrators() {
this.repoAdministrators.clear();
}
public Set<String> getRepoAdministrators() {
return this.repoAdministrators;
}
public boolean isRepoAdministrator(String username) {
if (username == null || username.trim().length() == 0) {
return false;
}
return this.repoAdministrators.contains(username.toLowerCase());
}
}

+ 4
- 4
src/com/gitblit/models/UserModel.java 查看文件

@@ -108,7 +108,7 @@ public class UserModel implements Principal, Serializable, Comparable<UserModel>
@Deprecated
@Unused
public boolean canAccessRepository(RepositoryModel repository) {
boolean isOwner = repository.isRepoAdministrator(username);
boolean isOwner = repository.isOwner(username);
boolean allowAuthenticated = isAuthenticated && AuthorizationControl.AUTHENTICATED.equals(repository.authorizationControl);
return canAdmin() || isOwner || repositories.contains(repository.name.toLowerCase())
|| hasTeamAccess(repository.name) || allowAuthenticated;
@@ -303,7 +303,7 @@ public class UserModel implements Principal, Serializable, Comparable<UserModel>
}
// repository owner - either specified owner or personal repository
if (repository.isRepoAdministrator(username) || repository.isUsersPersonalRepository(username)) {
if (repository.isOwner(username) || repository.isUsersPersonalRepository(username)) {
ap.permissionType = PermissionType.OWNER;
ap.permission = AccessPermission.REWIND;
return ap;
@@ -411,7 +411,7 @@ public class UserModel implements Principal, Serializable, Comparable<UserModel>
// can not fork your own repository
return false;
}
if (canAdmin() || repository.isRepoAdministrator(username)) {
if (canAdmin() || repository.isOwner(username)) {
return true;
}
if (!repository.allowForks) {
@@ -428,7 +428,7 @@ public class UserModel implements Principal, Serializable, Comparable<UserModel>
}
public boolean canEdit(RepositoryModel model) {
return canAdmin() || model.isUsersPersonalRepository(username) || model.isRepoAdministrator(username);
return canAdmin() || model.isUsersPersonalRepository(username) || model.isOwner(username);
}
/**

+ 30
- 0
src/com/gitblit/utils/ArrayUtils.java 查看文件

@@ -15,7 +15,9 @@
*/
package com.gitblit.utils;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
@@ -41,4 +43,32 @@ public class ArrayUtils {
public static boolean isEmpty(Collection<?> collection) {
return collection == null || collection.size() == 0;
}
public static String toString(Collection<?> collection) {
if (isEmpty(collection)) {
return "";
}
StringBuilder sb = new StringBuilder();
for (Object o : collection) {
sb.append(o.toString()).append(", ");
}
// trim trailing comma-space
sb.setLength(sb.length() - 2);
return sb.toString();
}
public static Collection<String> fromString(String value) {
if (StringUtils.isEmpty(value)) {
value = "";
}
List<String> list = new ArrayList<String>();
String [] values = value.split(",|;");
for (String v : values) {
String string = v.trim();
if (!StringUtils.isEmpty(string)) {
list.add(string);
}
}
return list;
}
}

+ 0
- 89
src/com/gitblit/utils/MultiConfigUtil.java 查看文件

@@ -1,89 +0,0 @@
/*
* 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<String> 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<String> convertCollectionToList(Collection<String> collection) {
List<String> result = new ArrayList<String>();
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<String> convertStringToSet(String string) {
Set<String> result = new HashSet<String>();
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;
}
}

+ 0
- 24
src/com/gitblit/utils/StringComparator.java 查看文件

@@ -1,24 +0,0 @@
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<String>, 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);
}

}

+ 6
- 5
src/com/gitblit/wicket/GitBlitWebApp.properties 查看文件

@@ -1,5 +1,5 @@
gb.repository = repository
gb.repoAdministrators = repository administrators
gb.owner = owner
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.repoAdministratorsDescription = the repository administrators may edit repository settings
gb.ownerDescription = the owner 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.errorOnlyAdminOrRepoAdminMayEditRepository = Only an administrator or a repository administrator may edit a repository
gb.errorOnlyAdminOrOwnerMayEditRepository = Only an administrator or the owner 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.repoAdministratorPermission = repository administrator
gb.ownerPermission = repository owner
gb.administrator = admin
gb.administratorPermission = Gitblit administrator
gb.team = team
@@ -440,4 +440,5 @@ gb.sslCertificateGeneratedRestart = Successfully generated new server SSL certif
gb.validity = validity
gb.siteName = site name
gb.siteNameDescription = short, descriptive name of your server
gb.excludeFromActivity = exclude from activity page
gb.excludeFromActivity = exclude from activity page
gb.owners = owners

+ 3
- 3
src/com/gitblit/wicket/GitBlitWebApp_es.properties 查看文件

@@ -1,5 +1,5 @@
gb.repository = Repositorio
gb.repoAdministrators = Administradores del repositorio
gb.owner = Propietario
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.repoAdministratorsDescription = Administradores del repositorio puede editar la configuraci\u00F3n del repositorio
gb.ownerDescription = El propietario 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.repoAdministratorPermission = Administrador del repositorio
gb.ownerPermission = Propietario del repositorio
gb.administrator = Admin
gb.administratorPermission = Administrador de Gitblit
gb.team = Equipo

+ 3
- 3
src/com/gitblit/wicket/GitBlitWebApp_ja.properties 查看文件

@@ -1,5 +1,5 @@
gb.repository = \u30ea\u30dd\u30b8\u30c8\u30ea
gb.repoAdministrators = \u30EA\u30DD\u30B8\u30C8\u30EA\u7BA1\u7406\u8005
gb.owner = \u6240\u6709\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.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.ownerDescription = \u6240\u6709\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.errorOnlyAdminOrRepoAdminMayEditRepository = Only an administrator or a repository administrator may edit a repository
gb.errorOnlyAdminOrOwnerMayEditRepository = Only an administrator or the owner may edit a repository
gb.errorAdministrationDisabled = Administration is disabled
gb.lastNDays = last {0} days
gb.completeGravatarProfile = Complete profile on Gravatar.com

+ 4
- 4
src/com/gitblit/wicket/GitBlitWebApp_ko.properties 查看文件

@@ -1,5 +1,5 @@
gb.repository = \uC800\uC7A5\uC18C
gb.repoAdministrators = \uC800\uC7A5\uC18C \uAD00\uB9AC\uC790
gb.owner = \uC18C\uC720\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.repoAdministratorsDescription = \uC800\uC7A5\uC18C \uAD00\uB9AC\uC790 \uC800\uC7A5\uC18C \uC124\uC815\uC744 \uBCC0\uACBD\uD560 \uC218 \uC788\uC74C
gb.ownerDescription = \uC18C\uC720\uC790\uB294 \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.errorOnlyAdminOrRepoAdminMayEditRepository = \uAD00\uB9AC\uC790\uC640 \uC800\uC7A5\uC18C \uAD00\uB9AC\uC790\uB9CC \uC800\uC7A5\uC18C\uB97C \uC218\uC815\uD560 \uC218 \uC788\uC74C
gb.errorOnlyAdminOrOwnerMayEditRepository = \uAD00\uB9AC\uC790\uC640 \uC18C\uC720\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.repoAdministratorPermission = \uC800\uC7A5\uC18C \uAD00\uB9AC\uC790
gb.ownerPermission = \uC800\uC7A5\uC18C \uC624\uB108
gb.administrator = \uAD00\uB9AC\uC790
gb.administratorPermission = Gitblit \uAD00\uB9AC\uC790
gb.team = \uD300

+ 4
- 4
src/com/gitblit/wicket/GitBlitWebApp_nl.properties 查看文件

@@ -1,5 +1,5 @@
gb.repository = repositorie
gb.repoAdministrators = repository beheerders
gb.owner = eigenaar
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.repoAdministratorsDescription = repository beheerders mag repository instellingen wijzigen
gb.ownerDescription = de eigenaar 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 een repository beheerder kan een repositorie wijzigen
gb.errorOnlyAdminOrOwnerMayEditRepository = Alleen een beheerder of de eigenaar 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.repoAdministratorPermission = repository beheerder
gb.ownerPermission = repositorie eigenaar
gb.administrator = beheer
gb.administratorPermission = Gitblit beheerder
gb.team = team

+ 3
- 3
src/com/gitblit/wicket/GitBlitWebApp_pl.properties 查看文件

@@ -1,5 +1,5 @@
gb.repository = Repozytorium
gb.repoAdministrators = Administratorzy repozytorium
gb.owner = W\u0142a\u015Bciciel
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.repoAdministratorsDescription = Administrator repozytorium mo\u017Ce edytowa\u0107 ustawienia repozytorium
gb.ownerDescription = W\u0142a\u015Bciciel 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.errorOnlyAdminOrRepoAdminMayEditRepository = Tylko administrator lub administrator repozytorium mo\u017Ce edytowa\u0107 repozytorium.
gb.errorOnlyAdminOrOwnerMayEditRepository = Tylko administrator lub w\u0142a\u015Bciciel 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

+ 4
- 4
src/com/gitblit/wicket/GitBlitWebApp_pt_BR.properties 查看文件

@@ -1,5 +1,5 @@
gb.repository = repositório
gb.repoAdministrators = administradores do repositório
gb.owner = proprietá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.repoAdministratorsDescription = o administradores do repositório pode editar configurações do repositório
gb.ownerDescription = o proprietá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.errorOnlyAdminOrRepoAdminMayEditRepository = Somente umadministrador ou um administrador de repositório pode editar um repositório
gb.errorOnlyAdminOrOwnerMayEditRepository = Somente umadministrador 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.repoAdministratorPermission = administrador do repositório
gb.ownerPermission = proprietário do repositório
gb.administrator = administrador
gb.administratorPermission = administrador do Gitblit
gb.team = equipe

+ 1
- 1
src/com/gitblit/wicket/pages/EditRepositoryPage.html 查看文件

@@ -50,7 +50,7 @@
<div class="tab-pane" id="permissions">
<table class="plain">
<tbody class="settings">
<tr><th><wicket:message key="gb.repoAdministrators"></wicket:message></th><td class="edit"><span wicket:id="repoAdministrators" tabindex="15" /> &nbsp;<span class="help-inline"><wicket:message key="gb.repoAdministratorsDescription"></wicket:message></span></td></tr>
<tr><th><wicket:message key="gb.owners"></wicket:message></th><td class="edit"><span wicket:id="owners" tabindex="15" /> </td></tr>
<tr><th colspan="2"><hr/></th></tr>
<tr><th><wicket:message key="gb.accessRestriction"></wicket:message></th><td class="edit"><select class="span4" wicket:id="accessRestriction" tabindex="16" /></td></tr>
<tr><th colspan="2"><hr/></th></tr>

+ 15
- 17
src/com/gitblit/wicket/pages/EditRepositoryPage.java 查看文件

@@ -61,7 +61,6 @@ 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;
@@ -71,8 +70,6 @@ import com.gitblit.wicket.panels.RegistrantPermissionsPanel;
public class EditRepositoryPage extends RootSubPage {
private MultiConfigUtil multiConfigUtil = new MultiConfigUtil();
private final boolean isCreate;
private boolean isAdmin;
@@ -97,7 +94,7 @@ public class EditRepositoryPage extends RootSubPage {
// personal create permissions, inject personal repository path
model.name = user.getPersonalPath() + "/";
model.projectPath = user.getPersonalPath();
model.addRepoAdministrator(user.username);
model.addOwner(user.username);
// personal repositories are private by default
model.accessRestriction = AccessRestrictionType.VIEW;
model.authorizationControl = AuthorizationControl.NAMED;
@@ -167,11 +164,11 @@ 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<String>(admins), new CollectionModel<String>(
persons), new StringChoiceRenderer(), 10, true);
// owners palette
List<String> owners = new ArrayList<String>(repositoryModel.owners);
List<String> persons = GitBlit.self().getAllUsernames();
final Palette<String> ownersPalette = new Palette<String>("owners", new ListModel<String>(owners), new CollectionModel<String>(
persons), new StringChoiceRenderer(), 12, true);
// indexed local branches palette
List<String> allLocalBranches = new ArrayList<String>();
@@ -335,10 +332,11 @@ public class EditRepositoryPage extends RootSubPage {
}
repositoryModel.indexedBranches = indexedBranches;
repositoryModel.removeAllRepoAdministrators();
Iterator<String> repoAdmins = repoAdministratorsPalette.getSelectedChoices();
while (repoAdmins.hasNext()) {
repositoryModel.addRepoAdministrator(repoAdmins.next());
// owners
repositoryModel.owners.clear();
Iterator<String> owners = ownersPalette.getSelectedChoices();
while (owners.hasNext()) {
repositoryModel.addOwner(owners.next());
}
// pre-receive scripts
@@ -392,7 +390,7 @@ public class EditRepositoryPage extends RootSubPage {
// field names reflective match RepositoryModel fields
form.add(new TextField<String>("name").setEnabled(allowEditName));
form.add(new TextField<String>("description"));
form.add(repoAdministratorsPalette);
form.add(ownersPalette);
form.add(new CheckBox("allowForks").setEnabled(GitBlit.getBoolean(Keys.web.allowForking, true)));
DropDownChoice<AccessRestrictionType> accessRestriction = new DropDownChoice<AccessRestrictionType>("accessRestriction", Arrays
.asList(AccessRestrictionType.values()), new AccessRestrictionRenderer());
@@ -573,9 +571,9 @@ public class EditRepositoryPage extends RootSubPage {
isAdmin = true;
return;
} else {
if (!model.isRepoAdministrator(user.username)) {
// User is not an Admin nor RepoAdministrator
error(getString("gb.errorOnlyAdminOrRepoAdminMayEditRepository"), true);
if (!model.isOwner(user.username)) {
// User is not an Admin nor Owner
error(getString("gb.errorOnlyAdminOrOwnerMayEditRepository"), true);
}
}
}

+ 5
- 5
src/com/gitblit/wicket/pages/RepositoryPage.java 查看文件

@@ -79,7 +79,7 @@ public abstract class RepositoryPage extends BasePage {
private final Map<String, PageRegistration> registeredPages;
private boolean showAdmin;
private boolean isRepoAdministrator;
private boolean isOwner;
public RepositoryPage(PageParameters params) {
super(params);
@@ -183,10 +183,10 @@ public abstract class RepositoryPage extends BasePage {
} else {
showAdmin = GitBlit.getBoolean(Keys.web.allowAdministration, false);
}
isRepoAdministrator = GitBlitWebSession.get().isLoggedIn()
&& (model.isRepoAdministrator(GitBlitWebSession.get()
isOwner = GitBlitWebSession.get().isLoggedIn()
&& (model.isOwner(GitBlitWebSession.get()
.getUsername()));
if (showAdmin || isRepoAdministrator) {
if (showAdmin || isOwner) {
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 isRepoAdministrator;
return isOwner;
}
private class SearchForm extends SessionlessForm<Void> implements Serializable {

+ 1
- 1
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.isRepoAdministrator(user.username) || repositoryModel.isUsersPersonalRepository(user.username))) {
(repositoryModel.isOwner(user.username) || repositoryModel.isUsersPersonalRepository(user.username))) {
// exclude Owner or personal repositories
continue;
}

+ 6
- 2
src/com/gitblit/wicket/pages/SummaryPage.html 查看文件

@@ -16,7 +16,7 @@
<div class="hidden-phone" style="padding-bottom: 10px;">
<table class="plain">
<tr><th><wicket:message key="gb.description">[description]</wicket:message></th><td><span wicket:id="repositoryDescription">[repository description]</span></td></tr>
<tr><th><wicket:message key="gb.repoAdministrators">[owner]</wicket:message></th><td><span wicket:id="repositoryAdministrators">[repository owner]</span></td></tr>
<tr><th><wicket:message key="gb.owners">[owner]</wicket:message></th><td><span wicket:id="repositoryOwners"><span wicket:id="owner"></span><span wicket:id="comma"></span></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="branchStats">[branch stats]</span> <span class="link"><a wicket:id="metrics"><wicket:message key="gb.metrics">[metrics]</wicket:message></a></span></td></tr>
<tr><th style="vertical-align:top;"><wicket:message key="gb.repositoryUrl">[URL]</wicket:message>&nbsp;<img style="vertical-align: top;padding-left:3px;" wicket:id="accessRestrictionIcon" /></th><td><span wicket:id="repositoryCloneUrl">[repository clone url]</span><div wicket:id="otherUrls"></div></td></tr>
@@ -44,7 +44,11 @@
<div style="border:1px solid #ddd;border-radius: 0 0 3px 3px;padding: 20px;">
<div wicket:id="readmeContent" class="markdown"></div>
</div>
</wicket:fragment>
</wicket:fragment>
<wicket:fragment wicket:id="ownersFragment">
</wicket:fragment>
</wicket:extend>
</body>
</html>

+ 26
- 11
src/com/gitblit/wicket/pages/SummaryPage.java 查看文件

@@ -27,6 +27,9 @@ import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
import org.apache.wicket.markup.html.panel.Fragment;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.markup.repeater.data.DataView;
import org.apache.wicket.markup.repeater.data.ListDataProvider;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.wicketstuff.googlecharts.Chart;
@@ -49,7 +52,6 @@ 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;
@@ -60,8 +62,6 @@ import com.gitblit.wicket.panels.TagsPanel;
public class SummaryPage extends RepositoryPage {
private MultiConfigUtil multiConfigUtil = new MultiConfigUtil();
public SummaryPage(PageParameters params) {
super(params);
@@ -85,14 +85,29 @@ public class SummaryPage extends RepositoryPage {
// repository description
add(new Label("repositoryDescription", getRepositoryModel().description));
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));
}
// owner links
final List<String> owners = new ArrayList<String>(getRepositoryModel().owners);
ListDataProvider<String> ownersDp = new ListDataProvider<String>(owners);
DataView<String> ownersView = new DataView<String>("repositoryOwners", ownersDp) {
private static final long serialVersionUID = 1L;
int counter = 0;
public void populateItem(final Item<String> item) {
UserModel ownerModel = GitBlit.self().getUserModel(item.getModelObject());
if (ownerModel != null) {
item.add(new LinkPanel("owner", null, ownerModel.getDisplayName(), UserPage.class,
WicketUtils.newUsernameParameter(ownerModel.username)).setRenderBodyOnly(true));
} else {
item.add(new Label("owner").setVisible(false));
}
counter++;
item.add(new Label("comma", ",").setVisible(counter < owners.size()));
item.setRenderBodyOnly(true);
}
};
ownersView.setRenderBodyOnly(true);
add(ownersView);
add(WicketUtils.createTimestampLabel("repositoryLastChange",
JGitUtils.getLastChange(r), getTimeZone(), getTimeUtils()));
if (metricsTotal == null) {

+ 1
- 1
src/com/gitblit/wicket/panels/ProjectRepositoryPanel.html 查看文件

@@ -51,7 +51,7 @@
<img style="border:0px;vertical-align:middle;" src="feed_16x16.png"></img>
</a>
</div>
<span style="color: #999;font-style:italic;font-size:0.8em;" wicket:id="repositoryAdministrators">[owner]</span>
<span style="color: #999;font-style:italic;font-size:0.8em;" wicket:id="repositoryOwner">[owner]</span>
</div>
<div class="pageTitle" style="border:0px;">

+ 61
- 93
src/com/gitblit/wicket/panels/ProjectRepositoryPanel.java 查看文件

@@ -36,7 +36,6 @@ 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;
@@ -52,104 +51,94 @@ public class ProjectRepositoryPanel extends BasePanel {
private static final long serialVersionUID = 1L;
private MultiConfigUtil multiConfigUtil = new MultiConfigUtil();
public ProjectRepositoryPanel(String wicketId, Localizer localizer,
Component parent, final boolean isAdmin,
final RepositoryModel entry,
public ProjectRepositoryPanel(String wicketId, Localizer localizer, Component parent,
final boolean isAdmin, final RepositoryModel entry,
final Map<AccessRestrictionType, String> 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", "&nbsp;")
.setEscapeModelStrings(false);
swatch = new Label("repositorySwatch", "&nbsp;").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<Void>("tickets", TicketsPage.class, pp)
.setVisible(entry.useTickets));
add(new BookmarkablePageLink<Void>("docs", DocsPage.class, pp)
.setVisible(entry.useDocs));
add(new BookmarkablePageLink<Void>("tickets", TicketsPage.class, pp).setVisible(entry.useTickets));
add(new BookmarkablePageLink<Void>("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 (entry.getRepoAdministrators().size() < 1) {
add(new Label("repositoryAdministrators").setVisible(false));
if (ArrayUtils.isEmpty(entry.owners)) {
add(new Label("repositoryOwner").setVisible(false));
} else {
add(new Label("repositoryAdministrators",
multiConfigUtil.convertCollectionToSingleLineString(entry
.getRepoAdministrators())
+ " ("
+ localizer.getString("gb.repoAdministrators", parent) + ")"));
String owner = "";
for (String username : entry.owners) {
UserModel ownerModel = GitBlit.self().getUserModel(username);
if (ownerModel != null) {
owner = ownerModel.getDisplayName();
}
}
if (entry.owners.size() > 1) {
owner += ", ...";
}
Label ownerLabel = (new Label("repositoryOwner", owner + " (" +
localizer.getString("gb.owner", parent) + ")"));
WicketUtils.setHtmlTooltip(ownerLabel, ArrayUtils.toString(entry.owners));
add(ownerLabel);
}
UserModel user = GitBlitWebSession.get().getUser();
@@ -157,19 +146,15 @@ public class ProjectRepositoryPanel extends BasePanel {
user = UserModel.ANONYMOUS;
}
Fragment repositoryLinks;
boolean isRepoAdministrator = entry.isRepoAdministrator(user.username);
boolean showOwner = entry.isOwner(user.username);
// owner of personal repository gets admin powers
boolean showAdmin = isAdmin
|| entry.isUsersPersonalRepository(user.username);
if (showAdmin || isRepoAdministrator) {
repositoryLinks = new Fragment(
"repositoryLinks",
showAdmin ? "repositoryAdminLinks" : "repositoryOwnerLinks",
this);
repositoryLinks.add(new BookmarkablePageLink<Void>(
"editRepository", EditRepositoryPage.class, WicketUtils
.newRepositoryParameter(entry.name)));
boolean showAdmin = isAdmin || entry.isUsersPersonalRepository(user.username);
if (showAdmin || showOwner) {
repositoryLinks = new Fragment("repositoryLinks", showAdmin ? "repositoryAdminLinks"
: "repositoryOwnerLinks", this);
repositoryLinks.add(new BookmarkablePageLink<Void>("editRepository", EditRepositoryPage.class,
WicketUtils.newRepositoryParameter(entry.name)));
if (showAdmin) {
Link<Void> deleteLink = new Link<Void>("deleteRepository") {
@@ -180,41 +165,28 @@ 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<Void>("tree",
TreePage.class, WicketUtils.newRepositoryParameter(entry.name))
.setEnabled(entry.hasCommits));
repositoryLinks.add(new BookmarkablePageLink<Void>("tree", TreePage.class, WicketUtils
.newRepositoryParameter(entry.name)).setEnabled(entry.hasCommits));
repositoryLinks.add(new BookmarkablePageLink<Void>("log",
LogPage.class, WicketUtils.newRepositoryParameter(entry.name))
.setEnabled(entry.hasCommits));
repositoryLinks.add(new BookmarkablePageLink<Void>("log", LogPage.class, WicketUtils
.newRepositoryParameter(entry.name)).setEnabled(entry.hasCommits));
add(repositoryLinks);
@@ -226,20 +198,17 @@ 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<String> repositoryUrls = new ArrayList<String>();
if (gitServlet) {
@@ -248,8 +217,7 @@ 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));
}
}

+ 2
- 2
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.repoAdministrators"));
WicketUtils.setHtmlTooltip(owner, getString("gb.repoAdministratorPermission"));
Label owner = new Label("pType", getString("gb.owner"));
WicketUtils.setHtmlTooltip(owner, getString("gb.ownerPermission"));
WicketUtils.setCssClass(owner, "label label-info");
item.add(owner);
break;

+ 3
- 3
src/com/gitblit/wicket/panels/RepositoriesPanel.html 查看文件

@@ -57,7 +57,7 @@
<wicket:message key="gb.repository">Repository</wicket:message>
</th>
<th class="hidden-phone" wicket:id="orderByDescription"><wicket:message key="gb.description">Description</wicket:message></th>
<th class="hidden-tablet hidden-phone" wicket:id="orderByOwner"><wicket:message key="gb.repoAdministrators">Owner</wicket:message></th>
<th class="hidden-tablet hidden-phone" wicket:id="orderByOwner"><wicket:message key="gb.owner">Owner</wicket:message></th>
<th class="hidden-phone"></th>
<th wicket:id="orderByDate"><wicket:message key="gb.lastChange">Last Change</wicket:message></th>
<th class="hidden-phone"></th>
@@ -72,7 +72,7 @@
<wicket:message key="gb.repository">Repository</wicket:message>
</th>
<th class="hidden-phone" ><span><wicket:message key="gb.description">Description</wicket:message></span></th>
<th class="hidden-tablet hidden-phone"><span><wicket:message key="gb.repoAdministrators">Owner</wicket:message></span></th>
<th class="hidden-tablet hidden-phone"><span><wicket:message key="gb.owner">Owner</wicket:message></span></th>
<th class="hidden-phone"></th>
<th><wicket:message key="gb.lastChange">Last Change</wicket:message></th>
<th class="hidden-phone"></th>
@@ -88,7 +88,7 @@
<wicket:fragment wicket:id="repositoryRow">
<td class="left" style="padding-left:3px;" ><b><span class="repositorySwatch" wicket:id="repositorySwatch"></span></b> <span style="padding-left:3px;" wicket:id="repositoryName">[repository name]</span></td>
<td class="hidden-phone"><span class="list" wicket:id="repositoryDescription">[repository description]</span></td>
<td class="hidden-tablet hidden-phone author"><span wicket:id="repositoryAdministrators">[repository owner]</span></td>
<td class="hidden-tablet hidden-phone author"><span wicket:id="repositoryOwner">[repository owner]</span></td>
<td class="hidden-phone" style="text-align: right;padding-right:10px;"><img class="inlineIcon" wicket:id="forkIcon" /><img class="inlineIcon" wicket:id="ticketsIcon" /><img class="inlineIcon" wicket:id="docsIcon" /><img class="inlineIcon" wicket:id="frozenIcon" /><img class="inlineIcon" wicket:id="federatedIcon" /><img class="inlineIcon" wicket:id="accessRestrictionIcon" /></td>
<td><span wicket:id="repositoryLastChange">[last change]</span></td>
<td class="hidden-phone" style="text-align: right;padding-right:15px;"><span style="font-size:0.8em;" wicket:id="repositorySize">[repository size]</span></td>

+ 44
- 46
src/com/gitblit/wicket/panels/RepositoriesPanel.java 查看文件

@@ -49,7 +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.ArrayUtils;
import com.gitblit.utils.StringUtils;
import com.gitblit.wicket.GitBlitWebSession;
import com.gitblit.wicket.WicketUtils;
@@ -65,8 +65,6 @@ 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<RepositoryModel> models, boolean enableLinks,
final Map<AccessRestrictionType, String> accessRestrictionTranslations) {
@@ -290,7 +288,23 @@ public class RepositoriesPanel extends BasePanel {
row.add(WicketUtils.newBlankImage("accessRestrictionIcon"));
}
row.add(new Label("repositoryAdministrators", multiConfigUtil.convertCollectionToSingleLineString(entry.getRepoAdministrators())));
String owner = "";
if (!ArrayUtils.isEmpty(entry.owners)) {
// display first owner
for (String username : entry.owners) {
UserModel ownerModel = GitBlit.self().getUserModel(username);
if (ownerModel != null) {
owner = ownerModel.getDisplayName();
break;
}
}
if (entry.owners.size() > 1) {
owner += ", ...";
}
}
Label ownerLabel = new Label("repositoryOwner", owner);
WicketUtils.setHtmlTooltip(ownerLabel, ArrayUtils.toString(entry.owners));
row.add(ownerLabel);
String lastChange;
if (entry.lastChange.getTime() == 0) {
@@ -302,29 +316,42 @@ public class RepositoriesPanel extends BasePanel {
row.add(lastChangeLabel);
WicketUtils.setCssClass(lastChangeLabel, getTimeUtils().timeAgoCss(entry.lastChange));
boolean isRepoAdministrator = user != null && entry.isRepoAdministrator(user.username);
boolean myPersonalRepository = isRepoAdministrator && entry.isUsersPersonalRepository(user.username);
boolean showOwner = user != null && entry.isOwner(user.username);
boolean myPersonalRepository = showOwner && entry.isUsersPersonalRepository(user.username);
if (showAdmin || myPersonalRepository) {
Fragment repositoryLinks = new Fragment("repositoryLinks",
"repositoryAdminLinks", this);
repositoryLinks.add(new BookmarkablePageLink<Void>("editRepository",
EditRepositoryPage.class, WicketUtils
.newRepositoryParameter(entry.name)));
Link<Void> deleteLink = new DeleteLink(entry, dp);
Link<Void> deleteLink = new Link<Void>("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));
}
}
};
deleteLink.add(new JavascriptEventConfirmation("onclick", MessageFormat.format(
getString("gb.deleteRepository"), entry)));
repositoryLinks.add(deleteLink);
row.add(repositoryLinks);
} else if (isRepoAdministrator) {
} else if (showOwner) {
Fragment repositoryLinks = new Fragment("repositoryLinks",
"repositoryAdminLinks", this);
"repositoryOwnerLinks", this);
repositoryLinks.add(new BookmarkablePageLink<Void>("editRepository",
EditRepositoryPage.class, WicketUtils
.newRepositoryParameter(entry.name)));
Link<Void> 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"));
@@ -353,35 +380,6 @@ public class RepositoriesPanel extends BasePanel {
}
}
private class DeleteLink extends Link<Void> {
private RepositoryModel entry;
private IDataProvider<RepositoryModel> dp;
private static final long serialVersionUID = 1L;
public DeleteLink(RepositoryModel entry, IDataProvider<RepositoryModel> 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;
@@ -475,8 +473,6 @@ public class RepositoriesPanel extends BasePanel {
private List<RepositoryModel> list;
private MultiConfigUtil multiConfigUtil = new MultiConfigUtil();
protected SortableRepositoriesProvider(List<RepositoryModel> list) {
this.list = list;
setSort(SortBy.date.name(), false);
@@ -529,10 +525,12 @@ public class RepositoriesPanel extends BasePanel {
Collections.sort(list, new Comparator<RepositoryModel>() {
@Override
public int compare(RepositoryModel o1, RepositoryModel o2) {
String own1 = ArrayUtils.toString(o1.owners);
String own2 = ArrayUtils.toString(o2.owners);
if (asc) {
return multiConfigUtil.convertCollectionToSingleLineString(o1.getRepoAdministrators()).compareTo(multiConfigUtil.convertCollectionToSingleLineString(o2.getRepoAdministrators()));
return own1.compareTo(own2);
}
return multiConfigUtil.convertCollectionToSingleLineString(o2.getRepoAdministrators()).compareTo(multiConfigUtil.convertCollectionToSingleLineString(o1.getRepoAdministrators()));
return own2.compareTo(own1);
}
});
} else if (prop.equals(SortBy.description.name())) {

+ 1
- 1
tests/com/gitblit/tests/FederationTests.java 查看文件

@@ -72,7 +72,7 @@ public class FederationTests {
model.accessRestriction = AccessRestrictionType.VIEW;
model.description = "cloneable repository " + i;
model.lastChange = new Date();
model.addRepoAdministrator("adminuser");
model.addOwner("adminuser");
model.name = "repo" + i + ".git";
model.size = "5 MB";
model.hasCommits = true;

+ 3
- 5
tests/com/gitblit/tests/GitServletTest.java 查看文件

@@ -40,8 +40,8 @@ import com.gitblit.Keys;
import com.gitblit.models.PushLogEntry;
import com.gitblit.models.RepositoryModel;
import com.gitblit.models.UserModel;
import com.gitblit.utils.ArrayUtils;
import com.gitblit.utils.JGitUtils;
import com.gitblit.utils.MultiConfigUtil;
import com.gitblit.utils.PushLogUtils;
public class GitServletTest {
@@ -59,8 +59,6 @@ public class GitServletTest {
String password = GitBlitSuite.password;
private static final AtomicBoolean started = new AtomicBoolean(false);
private MultiConfigUtil multiConfigUtil = new MultiConfigUtil();
@BeforeClass
public static void startGitblit() throws Exception {
@@ -728,7 +726,7 @@ public class GitServletTest {
// confirm default personal repository permissions
RepositoryModel model = GitBlit.self().getRepositoryModel(MessageFormat.format("~{0}/ticgit.git", user.username));
assertEquals("Unexpected owner", user.username, multiConfigUtil.convertCollectionToSingleLineString(model.getRepoAdministrators()));
assertEquals("Unexpected owner", user.username, ArrayUtils.toString(model.owners));
assertEquals("Unexpected authorization control", AuthorizationControl.NAMED, model.authorizationControl);
assertEquals("Unexpected access restriction", AccessRestrictionType.VIEW, model.accessRestriction);
@@ -752,7 +750,7 @@ public class GitServletTest {
// confirm default project repository permissions
RepositoryModel model = GitBlit.self().getRepositoryModel("project/ticgit.git");
assertEquals("Unexpected owner", user.username, multiConfigUtil.convertCollectionToSingleLineString(model.getRepoAdministrators()));
assertEquals("Unexpected owner", user.username, ArrayUtils.toString(model.owners));
assertEquals("Unexpected authorization control", AuthorizationControl.fromName(GitBlit.getString(Keys.git.defaultAuthorizationControl, "NAMED")), model.authorizationControl);
assertEquals("Unexpected access restriction", AccessRestrictionType.fromName(GitBlit.getString(Keys.git.defaultAccessRestriction, "NONE")), model.accessRestriction);

+ 48
- 3
tests/com/gitblit/tests/PermissionsTest.java 查看文件

@@ -2327,7 +2327,7 @@ public class PermissionsTest extends Assert {
repository.accessRestriction = AccessRestrictionType.VIEW;

UserModel user = new UserModel("test");
repository.addRepoAdministrator(user.username);
repository.addOwner(user.username);

assertFalse("user SHOULD NOT HAVE a repository permission!", user.hasRepositoryPermission(repository.name));
assertTrue("owner CAN NOT view!", user.canView(repository));
@@ -2344,6 +2344,51 @@ public class PermissionsTest extends Assert {
assertTrue("owner CAN NOT edit!", user.canEdit(repository));
}
@Test
public void testMultipleOwners() throws Exception {
RepositoryModel repository = new RepositoryModel("myrepo.git", null, null, new Date());
repository.authorizationControl = AuthorizationControl.NAMED;
repository.accessRestriction = AccessRestrictionType.VIEW;

UserModel user = new UserModel("test");
repository.addOwner(user.username);
UserModel user2 = new UserModel("test2");
repository.addOwner(user2.username);

// first owner
assertFalse("user SHOULD NOT HAVE a repository permission!", user.hasRepositoryPermission(repository.name));
assertTrue("owner CAN NOT view!", user.canView(repository));
assertTrue("owner CAN NOT clone!", user.canClone(repository));
assertTrue("owner CAN NOT push!", user.canPush(repository));
assertTrue("owner CAN NOT create ref!", user.canCreateRef(repository));
assertTrue("owner CAN NOT delete ref!", user.canDeleteRef(repository));
assertTrue("owner CAN NOT rewind ref!", user.canRewindRef(repository));

assertTrue("owner CAN NOT fork!", user.canFork(repository));
assertFalse("owner CAN NOT delete!", user.canDelete(repository));
assertTrue("owner CAN NOT edit!", user.canEdit(repository));
// second owner
assertFalse("user SHOULD NOT HAVE a repository permission!", user2.hasRepositoryPermission(repository.name));
assertTrue("owner CAN NOT view!", user2.canView(repository));
assertTrue("owner CAN NOT clone!", user2.canClone(repository));
assertTrue("owner CAN NOT push!", user2.canPush(repository));
assertTrue("owner CAN NOT create ref!", user2.canCreateRef(repository));
assertTrue("owner CAN NOT delete ref!", user2.canDeleteRef(repository));
assertTrue("owner CAN NOT rewind ref!", user2.canRewindRef(repository));

assertTrue("owner CAN NOT fork!", user2.canFork(repository));
assertFalse("owner CAN NOT delete!", user2.canDelete(repository));
assertTrue("owner CAN NOT edit!", user2.canEdit(repository));
assertTrue(repository.isOwner(user.username));
assertTrue(repository.isOwner(user2.username));
}
@Test
public void testOwnerPersonalRepository() throws Exception {
RepositoryModel repository = new RepositoryModel("~test/myrepo.git", null, null, new Date());
@@ -2351,7 +2396,7 @@ public class PermissionsTest extends Assert {
repository.accessRestriction = AccessRestrictionType.VIEW;

UserModel user = new UserModel("test");
repository.addRepoAdministrator(user.username);
repository.addOwner(user.username);

assertFalse("user SHOULD NOT HAVE a repository permission!", user.hasRepositoryPermission(repository.name));
assertTrue("user CAN NOT view!", user.canView(repository));
@@ -2375,7 +2420,7 @@ public class PermissionsTest extends Assert {
repository.accessRestriction = AccessRestrictionType.VIEW;

UserModel user = new UserModel("visitor");
repository.addRepoAdministrator("test");
repository.addOwner("test");

assertFalse("user HAS a repository permission!", user.hasRepositoryPermission(repository.name));
assertFalse("user CAN view!", user.canView(repository));

+ 1
- 1
tests/com/gitblit/tests/RpcTests.java 查看文件

@@ -167,7 +167,7 @@ public class RpcTests {
RepositoryModel model = new RepositoryModel();
model.name = "garbagerepo.git";
model.description = "created by RpcUtils";
model.addRepoAdministrator("garbage");
model.addOwner("garbage");
model.accessRestriction = AccessRestrictionType.VIEW;
model.authorizationControl = AuthorizationControl.AUTHENTICATED;

Loading…
取消
儲存