@@ -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); |
@@ -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 |
@@ -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); | |||
} | |||
@@ -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; |
@@ -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 |
@@ -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)); |
@@ -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); |
@@ -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); |
@@ -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: |
@@ -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()); | |||
} | |||
} |
@@ -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); | |||
} | |||
/** |
@@ -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; | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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" /> <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> |
@@ -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); | |||
} | |||
} | |||
} |
@@ -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 { |
@@ -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; | |||
} |
@@ -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> <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> |
@@ -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) { |
@@ -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;"> |
@@ -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", " ") | |||
.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<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)); | |||
} | |||
} |
@@ -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; |
@@ -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> |
@@ -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())) { |
@@ -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; |
@@ -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); | |||
@@ -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)); |
@@ -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; | |||