import com.gitblit.utils.JGitUtils;\r
import com.gitblit.utils.JsonUtils;\r
import com.gitblit.utils.MetricUtils;\r
+import com.gitblit.utils.MultiConfigUtil;\r
import com.gitblit.utils.ObjectCache;\r
import com.gitblit.utils.StringUtils;\r
import com.gitblit.utils.TimeUtils;\r
private TimeZone timezone;\r
\r
private FileBasedConfig projectConfigs;\r
+ \r
+ private MultiConfigUtil multiConfigUtil = new MultiConfigUtil();\r
\r
public GitBlit() {\r
if (gitblit == null) {\r
// TODO reconsider ownership as a user property\r
// manually specify personal repository ownerships\r
for (RepositoryModel rm : repositoryListCache.values()) {\r
- if (rm.isUsersPersonalRepository(user.username) || rm.isOwner(user.username)) {\r
+ if (rm.isUsersPersonalRepository(user.username) || rm.isRepoAdministrator(user.username)) {\r
RegistrantAccessPermission rp = new RegistrantAccessPermission(rm.name, AccessPermission.REWIND,\r
PermissionType.OWNER, RegistrantType.REPOSITORY, null, false);\r
// user may be owner of a repository to which they've inherited\r
for (RepositoryModel model : getRepositoryModels(user)) {\r
if (model.isUsersPersonalRepository(username)) {\r
// personal repository\r
- model.owner = user.username;\r
+ model.addRepoAdministrator(user.username);\r
String oldRepositoryName = model.name;\r
model.name = "~" + user.username + model.name.substring(model.projectPath.length());\r
model.projectPath = "~" + user.username;\r
updateRepositoryModel(oldRepositoryName, model, false);\r
- } else if (model.isOwner(username)) {\r
+ } else if (model.isRepoAdministrator(username)) {\r
// common/shared repo\r
- model.owner = user.username;\r
+ model.addRepoAdministrator(user.username);\r
updateRepositoryModel(model.name, model, false);\r
}\r
}\r
\r
if (config != null) {\r
model.description = getConfig(config, "description", "");\r
- model.owner = getConfig(config, "owner", "");\r
+ model.addRepoAdministrators(multiConfigUtil.convertStringToSet(getConfig(config, "owner", "")));\r
model.useTickets = getConfig(config, "useTickets", false);\r
model.useDocs = getConfig(config, "useDocs", false);\r
model.allowForks = getConfig(config, "allowForks", true);\r
public void updateConfiguration(Repository r, RepositoryModel repository) {\r
StoredConfig config = r.getConfig();\r
config.setString(Constants.CONFIG_GITBLIT, null, "description", repository.description);\r
- config.setString(Constants.CONFIG_GITBLIT, null, "owner", repository.owner);\r
+ config.setString(Constants.CONFIG_GITBLIT, null, "owner", multiConfigUtil.convertCollectionToSingleLineString(repository.getRepoAdministrators()));\r
config.setBoolean(Constants.CONFIG_GITBLIT, null, "useTickets", repository.useTickets);\r
config.setBoolean(Constants.CONFIG_GITBLIT, null, "useDocs", repository.useDocs);\r
config.setBoolean(Constants.CONFIG_GITBLIT, null, "allowForks", repository.allowForks);\r
}\r
\r
// schedule lucene engine\r
- logger.info("Lucene executor is scheduled to process indexed branches every 2 minutes.");\r
- scheduledExecutor.scheduleAtFixedRate(luceneExecutor, 1, 2, TimeUnit.MINUTES);\r
- \r
+ boolean branchIndexingActivated = settings.getBoolean(\r
+ Keys.git.branchIndexingActivated, true);\r
+ logger.info("Branch indexing is "\r
+ + (branchIndexingActivated ? "" : "not") + " activated");\r
+ if (branchIndexingActivated) {\r
+ logger.info("Lucene executor is scheduled to process indexed branches every 2 minutes.");\r
+ scheduledExecutor.scheduleAtFixedRate(luceneExecutor, 1, 2,\r
+ TimeUnit.MINUTES);\r
+ }\r
// schedule gc engine\r
if (gcExecutor.isReady()) {\r
logger.info("GC executor is scheduled to scan repositories every 24 hours.");\r
\r
// create a Gitblit repository model for the clone\r
RepositoryModel cloneModel = repository.cloneAs(cloneName);\r
- // owner has REWIND/RW+ permissions\r
- cloneModel.owner = user.username;\r
+ // owner has REWIND/RW+ permissions \r
+ cloneModel.addRepoAdministrator(user.username);\r
updateRepositoryModel(cloneName, cloneModel, false);\r
\r
// add the owner of the source repository to the clone's access list\r
- if (!StringUtils.isEmpty(repository.owner)) {\r
- UserModel originOwner = getUserModel(repository.owner);\r
- if (originOwner != null) {\r
- originOwner.setRepositoryPermission(cloneName, AccessPermission.CLONE);\r
- updateUserModel(originOwner.username, originOwner, false);\r
+ Set<String> repoAdministrators = repository.getRepoAdministrators();\r
+ if (repoAdministrators != null) {\r
+ for (String repoAdministrator : repoAdministrators) {\r
+ if (!StringUtils.isEmpty(repoAdministrator)) {\r
+ UserModel originOwner = getUserModel(repoAdministrator);\r
+ if (originOwner != null) {\r
+ originOwner.setRepositoryPermission(cloneName, AccessPermission.CLONE);\r
+ updateUserModel(originOwner.username, originOwner, false);\r
+ }\r
+ }\r
}\r
- }\r
+ } \r
\r
// grant origin's user list clone permission to fork\r
List<String> users = getRepositoryUsers(repository);\r
// create repository\r
RepositoryModel model = new RepositoryModel();\r
model.name = repository;\r
- model.owner = user.username;\r
+ model.addRepoAdministrator(user.username);\r
model.projectPath = StringUtils.getFirstPathElement(repository);\r
if (model.isUsersPersonalRepository(user.username)) {\r
// personal repository, default to private for user\r
usersPalette = new RegistrantPermissionsPanel(RegistrantType.USER);\r
\r
JPanel northFieldsPanel = new JPanel(new GridLayout(0, 1, 0, 5));\r
- northFieldsPanel.add(newFieldPanel(Translation.get("gb.owner"), ownerField));\r
+ northFieldsPanel.add(newFieldPanel(Translation.get("gb.repoAdministrators"), ownerField));\r
northFieldsPanel.add(newFieldPanel(Translation.get("gb.accessRestriction"),\r
accessRestriction), BorderLayout.NORTH);\r
\r
\r
repository.name = rname;\r
repository.description = descriptionField.getText();\r
- repository.owner = ownerField.getSelectedItem() == null ? null\r
- : ownerField.getSelectedItem().toString();\r
+ repository.addRepoAdministrator(ownerField.getSelectedItem() == null ? null\r
+ : ownerField.getSelectedItem().toString());\r
repository.HEAD = headRefField.getSelectedItem() == null ? null\r
: headRefField.getSelectedItem().toString();\r
repository.gcPeriod = (Integer) gcPeriod.getSelectedItem();\r
List<String> restricted = new ArrayList<String>();\r
for (RepositoryModel repo : repositories) {\r
// exclude Owner or personal repositories\r
- if (!repo.isOwner(username) && !repo.isUsersPersonalRepository(username)) {\r
+ if (!repo.isRepoAdministrator(username) && !repo.isUsersPersonalRepository(username)) {\r
if (repo.accessRestriction.exceeds(AccessRestrictionType.NONE)\r
&& repo.authorizationControl.equals(AuthorizationControl.NAMED)) {\r
restricted.add(repo.name);\r
permission.mutable = false;\r
continue;\r
}\r
- boolean isOwner = rm.isOwner(username);\r
+ boolean isOwner = rm.isRepoAdministrator(username);\r
if (isOwner) {\r
permission.permissionType = PermissionType.OWNER;\r
permission.mutable = false;\r
}\r
\r
public boolean isOwner(RepositoryModel model) {\r
- return account != null && account.equalsIgnoreCase(model.owner);\r
+ return model.isRepoAdministrator(account);\r
}\r
\r
public String getURL(String action, String repository, String objectId) {\r
// TODO reconsider ownership as a user property\r
// manually specify personal repository ownerships\r
for (RepositoryModel rm : allRepositories) {\r
- if (rm.isUsersPersonalRepository(user.username) || rm.isOwner(user.username)) {\r
+ if (rm.isUsersPersonalRepository(user.username) || rm.isRepoAdministrator(user.username)) {\r
RegistrantAccessPermission rp = new RegistrantAccessPermission(rm.name, AccessPermission.REWIND,\r
PermissionType.OWNER, RegistrantType.REPOSITORY, null, false);\r
// user may be owner of a repository to which they've inherited\r
setToolTipText(Translation.get("gb.administratorPermission"));\r
break;\r
case OWNER:\r
- setText(Translation.get("gb.owner"));\r
- setToolTipText(Translation.get("gb.ownerPermission"));\r
+ setText(Translation.get("gb.repoAdministrators"));\r
+ setToolTipText(Translation.get("gb.repoAdministratorPermission"));\r
break;\r
case TEAM:\r
setText(ap.source == null ? Translation.get("gb.team") : ap.source);\r
import com.gitblit.models.RegistrantAccessPermission;\r
import com.gitblit.models.FeedModel;\r
import com.gitblit.models.RepositoryModel;\r
+import com.gitblit.utils.MultiConfigUtil;\r
import com.gitblit.utils.StringUtils;\r
\r
/**\r
private JTextField filterTextfield;\r
\r
private JButton clearCache;\r
+ \r
+ private MultiConfigUtil multiConfigUtil = new MultiConfigUtil();\r
\r
public RepositoriesPanel(GitblitClient gitblit) {\r
super();\r
dialog.setLocationRelativeTo(RepositoriesPanel.this);\r
List<String> usernames = gitblit.getUsernames();\r
List<RegistrantAccessPermission> members = gitblit.getUserAccessPermissions(repository);\r
- dialog.setUsers(repository.owner, usernames, members);\r
+ dialog.setUsers(multiConfigUtil.convertCollectionToSingleLineString(repository.getRepoAdministrators()), usernames, members);\r
dialog.setTeams(gitblit.getTeamnames(), gitblit.getTeamAccessPermissions(repository));\r
dialog.setRepositories(gitblit.getRepositories());\r
dialog.setFederationSets(gitblit.getFederationSets(), repository.federationSets);\r
case Description:\r
return Translation.get("gb.description");\r
case Owner:\r
- return Translation.get("gb.owner");\r
+ return Translation.get("gb.repoAdministrators");\r
case Last_Change:\r
return Translation.get("gb.lastChange");\r
case Size:\r
case Description:\r
return model.description;\r
case Owner:\r
- return model.owner;\r
+ return model.getRepoAdministrators();\r
case Indicators:\r
return model;\r
case Last_Change:\r
import java.util.Set;\r
import java.util.TreeSet;\r
\r
+import org.apache.wicket.markup.html.basic.MultiLineLabel;\r
+\r
import com.gitblit.Constants.AccessRestrictionType;\r
import com.gitblit.Constants.AuthorizationControl;\r
import com.gitblit.Constants.FederationStrategy;\r
import com.gitblit.utils.ArrayUtils;\r
+import com.gitblit.utils.MultiConfigUtil;\r
+import com.gitblit.utils.StringComparator;\r
import com.gitblit.utils.StringUtils;\r
\r
/**\r
* @author James Moger\r
* \r
*/\r
-public class RepositoryModel implements Serializable, Comparable<RepositoryModel> {\r
+public class RepositoryModel implements Serializable,\r
+ Comparable<RepositoryModel> {\r
\r
private static final long serialVersionUID = 1L;\r
\r
// field names are reflectively mapped in EditRepository page\r
public String name;\r
public String description;\r
- public String owner;\r
+ private Set<String> repoAdministrators = new TreeSet<String>(new StringComparator());\r
public Date lastChange;\r
public boolean hasCommits;\r
public boolean showRemoteBranches;\r
public String gcThreshold;\r
public int gcPeriod;\r
public int maxActivityCommits;\r
- \r
+\r
public transient boolean isCollectingGarbage;\r
public Date lastGC;\r
- \r
+\r
+ private MultiConfigUtil multiConfigUtil = new MultiConfigUtil();\r
+\r
public RepositoryModel() {\r
this("", "", "", new Date(0));\r
}\r
\r
- public RepositoryModel(String name, String description, String owner, Date lastchange) {\r
+ public RepositoryModel(String name, String description, String owner,\r
+ Date lastchange) {\r
this.name = name;\r
- this.description = description;\r
- this.owner = owner;\r
+ this.description = description; \r
+ this.addRepoAdministrator(owner);\r
this.lastChange = lastchange;\r
this.accessRestriction = AccessRestrictionType.NONE;\r
this.authorizationControl = AuthorizationControl.NAMED;\r
this.federationSets = new ArrayList<String>();\r
- this.federationStrategy = FederationStrategy.FEDERATE_THIS; \r
+ this.federationStrategy = FederationStrategy.FEDERATE_THIS;\r
this.projectPath = StringUtils.getFirstPathElement(name);\r
}\r
- \r
+\r
public List<String> getLocalBranches() {\r
if (ArrayUtils.isEmpty(availableRefs)) {\r
return new ArrayList<String>();\r
}\r
return localBranches;\r
}\r
- \r
+\r
public void addFork(String repository) {\r
if (forks == null) {\r
forks = new TreeSet<String>();\r
}\r
forks.add(repository);\r
}\r
- \r
+\r
public void removeFork(String repository) {\r
if (forks == null) {\r
return;\r
}\r
forks.remove(repository);\r
}\r
- \r
+\r
public void resetDisplayName() {\r
displayName = null;\r
}\r
- \r
+\r
@Override\r
public int hashCode() {\r
return name.hashCode();\r
}\r
- \r
+\r
@Override\r
public boolean equals(Object o) {\r
if (o instanceof RepositoryModel) {\r
public int compareTo(RepositoryModel o) {\r
return StringUtils.compareRepositoryNames(name, o.name);\r
}\r
- \r
+\r
public boolean isFork() {\r
return !StringUtils.isEmpty(originRepository);\r
}\r
- \r
- public boolean isOwner(String username) {\r
- return owner != null && username != null && owner.equalsIgnoreCase(username);\r
- }\r
- \r
+\r
public boolean isPersonalRepository() {\r
- return !StringUtils.isEmpty(projectPath) && projectPath.charAt(0) == '~';\r
+ return !StringUtils.isEmpty(projectPath)\r
+ && projectPath.charAt(0) == '~';\r
}\r
- \r
+\r
public boolean isUsersPersonalRepository(String username) {\r
- return !StringUtils.isEmpty(projectPath) && projectPath.equalsIgnoreCase("~" + username);\r
+ return !StringUtils.isEmpty(projectPath)\r
+ && projectPath.equalsIgnoreCase("~" + username);\r
}\r
- \r
+\r
public boolean allowAnonymousView() {\r
return !accessRestriction.atLeast(AccessRestrictionType.VIEW);\r
}\r
- \r
+\r
public RepositoryModel cloneAs(String cloneName) {\r
RepositoryModel clone = new RepositoryModel();\r
clone.originRepository = name;\r
clone.skipSummaryMetrics = skipSummaryMetrics;\r
return clone;\r
}\r
+\r
+ public void addRepoAdministrator(String repoAdministrator) {\r
+ if (repoAdministrator != null && repoAdministrator.trim().length() > 0) {\r
+ this.repoAdministrators.add(repoAdministrator.toLowerCase());\r
+ }\r
+ }\r
+\r
+ public void removeRepoAdministrator(String repoAdministrator) {\r
+ if (repoAdministrator != null && repoAdministrator.trim().length() > 0) {\r
+ this.repoAdministrators.remove(repoAdministrator.toLowerCase());\r
+ }\r
+ }\r
+\r
+ public void addRepoAdministrators(Set<String> repoAdministrators) {\r
+ if (repoAdministrators != null) {\r
+ for (String admin : repoAdministrators) {\r
+ this.addRepoAdministrator(admin);\r
+ }\r
+ }\r
+ }\r
+\r
+ public void removeRepoAdministrators(Set<String> repoAdministrators) {\r
+ if (repoAdministrators != null) {\r
+ for (String admin : repoAdministrators) {\r
+ this.removeRepoAdministrator(admin);\r
+ }\r
+ }\r
+ }\r
+\r
+ public void removeAllRepoAdministrators() {\r
+ this.repoAdministrators.clear();\r
+ }\r
+ \r
+ public Set<String> getRepoAdministrators() {\r
+ return this.repoAdministrators;\r
+ }\r
+ \r
+ public boolean isRepoAdministrator(String username) {\r
+ if (username == null || username.trim().length() == 0) {\r
+ return false;\r
+ }\r
+ return this.repoAdministrators.contains(username.toLowerCase());\r
+ }\r
}
\ No newline at end of file
@Deprecated\r
@Unused\r
public boolean canAccessRepository(RepositoryModel repository) {\r
- boolean isOwner = !StringUtils.isEmpty(repository.owner)\r
- && repository.owner.equals(username);\r
+ boolean isOwner = repository.isRepoAdministrator(username);\r
boolean allowAuthenticated = isAuthenticated && AuthorizationControl.AUTHENTICATED.equals(repository.authorizationControl);\r
return canAdmin() || isOwner || repositories.contains(repository.name.toLowerCase())\r
|| hasTeamAccess(repository.name) || allowAuthenticated;\r
}\r
\r
// repository owner - either specified owner or personal repository\r
- if (repository.isOwner(username) || repository.isUsersPersonalRepository(username)) {\r
+ if (repository.isRepoAdministrator(username) || repository.isUsersPersonalRepository(username)) {\r
ap.permissionType = PermissionType.OWNER;\r
ap.permission = AccessPermission.REWIND;\r
return ap;\r
// can not fork your own repository\r
return false;\r
}\r
- if (canAdmin() || repository.isOwner(username)) {\r
+ if (canAdmin() || repository.isRepoAdministrator(username)) {\r
return true;\r
}\r
if (!repository.allowForks) {\r
}\r
\r
public boolean canEdit(RepositoryModel model) {\r
- return canAdmin() || model.isUsersPersonalRepository(username) || model.isOwner(username);\r
+ return canAdmin() || model.isUsersPersonalRepository(username) || model.isRepoAdministrator(username);\r
}\r
\r
/**\r
--- /dev/null
+/*
+ * 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;
+ }
+}
--- /dev/null
+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);
+ }
+
+}
gb.repository = repository\r
-gb.owner = owner\r
+gb.repoAdministrators = repository administrators\r
gb.description = description\r
gb.lastChange = last change\r
gb.refs = refs\r
gb.showReadme = show readme\r
gb.showReadmeDescription = show a \"readme\" Markdown file on the summary page\r
gb.nameDescription = use '/' to group repositories. e.g. libraries/mycoollib.git\r
-gb.ownerDescription = the owner may edit repository settings\r
+gb.repoAdministratorsDescription = the repository administrators may edit repository settings\r
gb.blob = blob\r
gb.commitActivityTrend = commit activity trend\r
gb.commitActivityDOW = commit activity by day of week\r
gb.emailAddress = email address\r
gb.errorAdminLoginRequired = Administration requires a login\r
gb.errorOnlyAdminMayCreateRepository = Only an administrator may create a repository\r
-gb.errorOnlyAdminOrOwnerMayEditRepository = Only an administrator or the owner may edit a repository\r
+gb.errorOnlyAdminOrRepoAdminMayEditRepository = Only an administrator or a repository administrator may edit a repository\r
gb.errorAdministrationDisabled = Administration is disabled\r
gb.lastNDays = last {0} days\r
gb.completeGravatarProfile = Complete profile on Gravatar.com\r
gb.gcPeriodDescription = duration between garbage collections\r
gb.gcThreshold = GC threshold\r
gb.gcThresholdDescription = minimum total size of loose objects to trigger early garbage collection\r
-gb.ownerPermission = repository owner\r
+gb.repoAdministratorPermission = repository administrator\r
gb.administrator = admin\r
gb.administratorPermission = Gitblit administrator\r
gb.team = team\r
gb.repository = Repositorio\r
-gb.owner = Propietario\r
+gb.repoAdministrators = Administradores del repositorio\r
gb.description = Descripci\u00F3n\r
gb.lastChange = Actualizado\r
gb.refs = Refs\r
gb.showReadme = Ver l\u00E9eme\r
gb.showReadmeDescription = Mostrar el archivo \"l\u00E9eme\" de Markdown en la p\u00E1gina resumen\r
gb.nameDescription = Usa '/' para agrupar repositorios. ej. librerias/mylibreria.git\r
-gb.ownerDescription = El propietario puede editar la configuraci\u00F3n del repositorio\r
+gb.repoAdministratorsDescription = Administradores del repositorio puede editar la configuraci\u00F3n del repositorio\r
gb.blob = Objeto\r
gb.commitActivityTrend = Tendencia de actividad del repositorio\r
gb.commitActivityDOW = Actividad de consignas por d\u00EDa de la semana\r
gb.gcPeriodDescription = Duraci\u00F3n entre periodos de limpieza\r
gb.gcThreshold = L\u00EDmites para GC\r
gb.gcThresholdDescription = Tama\u00F1o m\u00EDnimo total de objetos sueltos para activar la recolecci\u00F3n inmediata de basura\r
-gb.ownerPermission = Propietario del repositorio\r
+gb.repoAdministratorPermission = Administrador del repositorio\r
gb.administrator = Admin\r
gb.administratorPermission = Administrador de Gitblit\r
gb.team = Equipo\r
gb.repository = \u30ea\u30dd\u30b8\u30c8\u30ea\r
-gb.owner = \u6240\u6709\u8005\r
+gb.repoAdministrators = \u30EA\u30DD\u30B8\u30C8\u30EA\u7BA1\u7406\u8005\r
gb.description = \u8aac\u660e\r
gb.lastChange = \u6700\u5f8c\u306e\u5909\u66f4\r
gb.refs = refs\r
gb.showReadme = readme\u8868\u793a\r
gb.showReadmeDescription = \"readme\" Markdown\u30d5\u30a1\u30a4\u30eb\u3092\u6982\u8981\u30da\u30fc\u30b8\u306b\u8868\u793a\u3059\u308b\r
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\r
-gb.ownerDescription = \u6240\u6709\u8005\u306f\u30ea\u30dd\u30b8\u30c8\u30ea\u306e\u8a2d\u5b9a\u3092\u5909\u66f4\u3067\u304d\u308b\r
+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\r
gb.blob = blob\r
gb.commitActivityTrend = commit activity trend\r
gb.commitActivityDOW = commit activity by day of week\r
gb.emailAddress = email address\r
gb.errorAdminLoginRequired = Administration requires a login\r
gb.errorOnlyAdminMayCreateRepository = Only an administrator may create a repository\r
-gb.errorOnlyAdminOrOwnerMayEditRepository = Only an administrator or the owner may edit a repository\r
+gb.errorOnlyAdminOrRepoAdminMayEditRepository = Only an administrator or a repository administrator may edit a repository\r
gb.errorAdministrationDisabled = Administration is disabled\r
gb.lastNDays = last {0} days\r
gb.completeGravatarProfile = Complete profile on Gravatar.com\r
gb.repository = \uC800\uC7A5\uC18C
-gb.owner = \uC18C\uC720\uC790
+gb.repoAdministrators = \uC800\uC7A5\uC18C \uAD00\uB9AC\uC790
gb.description = \uC124\uBA85
gb.lastChange = \uCD5C\uADFC \uBCC0\uACBD
gb.refs = refs
gb.showReadme = \uB9AC\uB4DC\uBBF8(readme) \uBCF4\uAE30
gb.showReadmeDescription = \uC694\uC57D\uD398\uC774\uC9C0\uC5D0\uC11C \"readme\" \uB9C8\uD06C\uB2E4\uC6B4 \uD30C\uC77C \uBCF4\uAE30
gb.nameDescription = \uC800\uC7A5\uC18C\uB97C \uADF8\uB8F9\uC73C\uB85C \uBB36\uC73C\uB824\uBA74 '/' \uB97C \uC0AC\uC6A9. \uC608) libraries/reponame.git
-gb.ownerDescription = \uC18C\uC720\uC790\uB294 \uC800\uC7A5\uC18C \uC124\uC815\uC744 \uBCC0\uACBD\uD560 \uC218 \uC788\uC74C
+gb.repoAdministratorsDescription = \uC800\uC7A5\uC18C \uAD00\uB9AC\uC790 \uC800\uC7A5\uC18C \uC124\uC815\uC744 \uBCC0\uACBD\uD560 \uC218 \uC788\uC74C
gb.blob = blob
gb.commitActivityTrend = \uCEE4\uBC0B \uD65C\uB3D9 \uD2B8\uB79C\uB4DC
gb.commitActivityDOW = 1\uC8FC\uC77C\uC758 \uC77C\uB2E8\uC704 \uCEE4\uBC0B \uD65C\uB3D9
gb.emailAddress = \uC774\uBA54\uC77C \uC8FC\uC18C
gb.errorAdminLoginRequired = \uAD00\uB9AC\uB97C \uC704\uD574\uC11C\uB294 \uB85C\uADF8\uC778\uC774 \uD544\uC694
gb.errorOnlyAdminMayCreateRepository = \uAD00\uB9AC\uC790\uB9CC \uC800\uC7A5\uC18C\uB97C \uB9CC\uB4E4\uC218 \uC788\uC74C
-gb.errorOnlyAdminOrOwnerMayEditRepository = \uAD00\uB9AC\uC790\uC640 \uC18C\uC720\uC790\uB9CC \uC800\uC7A5\uC18C\uB97C \uC218\uC815\uD560 \uC218 \uC788\uC74C
+gb.errorOnlyAdminOrRepoAdminMayEditRepository = \uAD00\uB9AC\uC790\uC640 \uC800\uC7A5\uC18C \uAD00\uB9AC\uC790\uB9CC \uC800\uC7A5\uC18C\uB97C \uC218\uC815\uD560 \uC218 \uC788\uC74C
gb.errorAdministrationDisabled = \uAD00\uB9AC\uAE30\uB2A5 \uBE44\uD65C\uC131\uD654\uB428
gb.lastNDays = {0} \uC77C\uC804
gb.completeGravatarProfile = Gravatar.com \uC5D0 \uD504\uB85C\uD30C\uC77C \uC0DD\uC131\uB428
gb.gcPeriodDescription = \uAC00\uBE44\uC9C0 \uD074\uB809\uC158\uAC04\uC758 \uC2DC\uAC04 \uAC04\uACA9
gb.gcThreshold = GC \uAE30\uC900\uC810
gb.gcThresholdDescription = \uC870\uAE30 \uAC00\uBE44\uC9C0 \uCEEC\uB809\uC158\uC744 \uBC1C\uC0DD\uC2DC\uD0A4\uAE30 \uC704\uD55C \uC624\uBE0C\uC81D\uD2B8\uB4E4\uC758 \uCD5C\uC18C \uC804\uCCB4 \uD06C\uAE30
-gb.ownerPermission = \uC800\uC7A5\uC18C \uC624\uB108
+gb.repoAdministratorPermission = \uC800\uC7A5\uC18C \uAD00\uB9AC\uC790
gb.administrator = \uAD00\uB9AC\uC790
gb.administratorPermission = Gitblit \uAD00\uB9AC\uC790
gb.team = \uD300
gb.repository = repositorie\r
-gb.owner = eigenaar\r
+gb.repoAdministrators = repository beheerders\r
gb.description = omschrijving\r
gb.lastChange = laatste wijziging\r
gb.refs = refs\r
gb.showReadme = toon readme\r
gb.showReadmeDescription = toon een \"readme\" Markdown bestand in de samenvattingspagina\r
gb.nameDescription = gebruik '/' voor het groeperen van repositories. bijv. libraries/mycoollib.git\r
-gb.ownerDescription = de eigenaar mag repository instellingen wijzigen\r
+gb.repoAdministratorsDescription = repository beheerders mag repository instellingen wijzigen\r
gb.blob = blob\r
gb.commitActivityTrend = commit activiteit trend\r
gb.commitActivityDOW = commit activiteit per dag van de week\r
gb.emailAddress = emailadres\r
gb.errorAdminLoginRequired = Aanmelden vereist voor beheerwerk\r
gb.errorOnlyAdminMayCreateRepository = Alleen een beheerder kan een repositorie maken\r
-gb.errorOnlyAdminOrOwnerMayEditRepository = Alleen een beheerder of de eigenaar kan een repositorie wijzigen\r
+gb.errorOnlyAdminOrOwnerMayEditRepository = Alleen een beheerder of een repository beheerder kan een repositorie wijzigen\r
gb.errorAdministrationDisabled = Beheer is uitgeschakeld\r
gb.lastNDays = laatste {0} dagen\r
gb.completeGravatarProfile = Completeer profiel op Gravatar.com\r
gb.gcPeriodDescription = tijdsduur tussen opruimacties\r
gb.gcThreshold = opruim drempel\r
gb.gcThresholdDescription = minimum totaalomvang van losse objecten voor het starten van opruimactie\r
-gb.ownerPermission = repositorie eigenaar\r
+gb.repoAdministratorPermission = repository beheerder\r
gb.administrator = beheer\r
gb.administratorPermission = Gitblit beheerder\r
gb.team = team\r
gb.repository = Repozytorium
-gb.owner = W\u0142a\u015Bciciel
+gb.repoAdministrators = Administratorzy repozytorium
gb.description = Opis
gb.lastChange = Ostatnia zmiana
gb.refs = Refs
gb.showReadme = Poka\u017C readme
gb.showReadmeDescription = Poka\u017C sparsowany \"readme\" na stronie podsumowania
gb.nameDescription = u\u017Cyj '/' do grupowania repozytori\u00F3w, np. libraries/server-lib.git
-gb.ownerDescription = W\u0142a\u015Bciciel mo\u017Ce edytowa\u0107 ustawienia repozytorium
+gb.repoAdministratorsDescription = Administrator repozytorium mo\u017Ce edytowa\u0107 ustawienia repozytorium
gb.blob = blob
gb.commitActivityTrend = Aktywno\u015B\u0107 zmian
gb.commitActivityDOW = Aktywno\u015B\u0107 zmian wed\u0142ug dnia tygodnia
gb.emailAddress = Adres email
gb.errorAdminLoginRequired = Administracja wymaga zalogowania
gb.errorOnlyAdminMayCreateRepository = Tylko administrator mo\u017Ce utworzy\u0107 repozytorium
-gb.errorOnlyAdminOrOwnerMayEditRepository = Tylko administrator lub w\u0142a\u015Bciciel mo\u017Ce edytowa\u0107 repozytorium.
+gb.errorOnlyAdminOrRepoAdminMayEditRepository = Tylko administrator lub administrator repozytorium mo\u017Ce edytowa\u0107 repozytorium.
gb.errorAdministrationDisabled = Administracja jest wy\u0142\u0105czona
gb.lastNDays = Ostatnich {0} dni
gb.completeGravatarProfile = Pe\u0142ny profil na Gravatar.com
gb.repository = repositório\r
-gb.owner = proprietário\r
+gb.repoAdministrators = administradores do repositório\r
gb.description = descrição\r
gb.lastChange = última alteração\r
gb.refs = refs\r
gb.showReadme = mostrar readme\r
gb.showReadmeDescription = mostrar um arquivo \"leia-me\" na página de resumo\r
gb.nameDescription = usar '/' para agrupar repositórios. e.g. libraries/mycoollib.git\r
-gb.ownerDescription = o proprietário pode editar configurações do repositório\r
+gb.repoAdministratorsDescription = o administradores do repositório pode editar configurações do repositório\r
gb.blob = blob\r
gb.commitActivityTrend = tendência dos commits\r
gb.commitActivityDOW = commits diários\r
gb.emailAddress = e-mail\r
gb.errorAdminLoginRequired = Administração requer um login\r
gb.errorOnlyAdminMayCreateRepository = Somente umadministrador pode criar um repositório\r
-gb.errorOnlyAdminOrOwnerMayEditRepository = Somente umadministrador pode editar um repositório\r
+gb.errorOnlyAdminOrRepoAdminMayEditRepository = Somente umadministrador ou um administrador de repositório pode editar um repositório\r
gb.errorAdministrationDisabled = Administração está desabilitada\r
gb.lastNDays = últimos {0} dias\r
gb.completeGravatarProfile = Profile completo em Gravatar.com\r
gb.gcPeriodDescription = duração entre as coletas de lixo\r
gb.gcThreshold = limite do GC \r
gb.gcThresholdDescription = tamanho total mÃnimo de objetos \"soltos\" que ativam a coleta de lixo\r
-gb.ownerPermission = proprietário do repositório\r
+gb.repoAdministratorPermission = administrador do repositório\r
gb.administrator = administrador\r
gb.administratorPermission = administrador do Gitblit\r
gb.team = equipe\r
<div class="tab-pane" id="permissions">\r
<table class="plain">\r
<tbody class="settings">\r
- <tr><th><wicket:message key="gb.owner"></wicket:message></th><td class="edit"><select class="span2" wicket:id="owner" tabindex="15" /> <span class="help-inline"><wicket:message key="gb.ownerDescription"></wicket:message></span></td></tr>\r
+ <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>\r
<tr><th colspan="2"><hr/></th></tr>\r
<tr><th><wicket:message key="gb.accessRestriction"></wicket:message></th><td class="edit"><select class="span4" wicket:id="accessRestriction" tabindex="16" /></td></tr>\r
<tr><th colspan="2"><hr/></th></tr>\r
import com.gitblit.models.RepositoryModel;\r
import com.gitblit.models.UserModel;\r
import com.gitblit.utils.ArrayUtils;\r
+import com.gitblit.utils.MultiConfigUtil;\r
import com.gitblit.utils.StringUtils;\r
import com.gitblit.wicket.GitBlitWebSession;\r
import com.gitblit.wicket.StringChoiceRenderer;\r
\r
public class EditRepositoryPage extends RootSubPage {\r
\r
+ private MultiConfigUtil multiConfigUtil = new MultiConfigUtil();\r
+ \r
private final boolean isCreate;\r
\r
private boolean isAdmin;\r
// personal create permissions, inject personal repository path\r
model.name = user.getPersonalPath() + "/";\r
model.projectPath = user.getPersonalPath();\r
- model.owner = user.username;\r
+ model.addRepoAdministrator(user.username);\r
// personal repositories are private by default\r
model.accessRestriction = AccessRestrictionType.VIEW;\r
model.authorizationControl = AuthorizationControl.NAMED;\r
final RegistrantPermissionsPanel teamsPalette = new RegistrantPermissionsPanel("teams", \r
RegistrantType.TEAM, GitBlit.self().getAllTeamnames(), repositoryTeams, getAccessPermissions());\r
\r
+ // repo administrators palette\r
+ List admins = multiConfigUtil.convertCollectionToList(repositoryModel.getRepoAdministrators());\r
+ List persons = GitBlit.self().getAllUsernames();\r
+ final Palette repoAdministratorsPalette = new Palette("repoAdministrators", new ListModel<String>(admins), new CollectionModel<String>(\r
+ persons), new StringChoiceRenderer(), 10, true);\r
+ \r
// indexed local branches palette\r
List<String> allLocalBranches = new ArrayList<String>();\r
allLocalBranches.add(Constants.DEFAULT_BRANCH);\r
}\r
repositoryModel.indexedBranches = indexedBranches;\r
\r
+ repositoryModel.removeAllRepoAdministrators();\r
+ Iterator<String> repoAdmins = repoAdministratorsPalette.getSelectedChoices();\r
+ while (repoAdmins.hasNext()) {\r
+ repositoryModel.addRepoAdministrator(repoAdmins.next());\r
+ }\r
+ \r
// pre-receive scripts\r
List<String> preReceiveScripts = new ArrayList<String>();\r
Iterator<String> pres = preReceivePalette.getSelectedChoices();\r
// field names reflective match RepositoryModel fields\r
form.add(new TextField<String>("name").setEnabled(allowEditName));\r
form.add(new TextField<String>("description"));\r
- form.add(new DropDownChoice<String>("owner", GitBlit.self().getAllUsernames())\r
- .setEnabled(GitBlitWebSession.get().canAdmin() && !repositoryModel.isPersonalRepository()));\r
+ form.add(repoAdministratorsPalette);\r
form.add(new CheckBox("allowForks").setEnabled(GitBlit.getBoolean(Keys.web.allowForking, true)));\r
DropDownChoice<AccessRestrictionType> accessRestriction = new DropDownChoice<AccessRestrictionType>("accessRestriction", Arrays\r
.asList(AccessRestrictionType.values()), new AccessRestrictionRenderer());\r
isAdmin = true;\r
return;\r
} else {\r
- if (!model.owner.equalsIgnoreCase(user.username)) {\r
- // User is not an Admin nor Owner\r
- error(getString("gb.errorOnlyAdminOrOwnerMayEditRepository"), true);\r
+ if (!model.isRepoAdministrator(user.username)) {\r
+ // User is not an Admin nor RepoAdministrator\r
+ error(getString("gb.errorOnlyAdminOrRepoAdminMayEditRepository"), true);\r
}\r
}\r
}\r
\r
private final Map<String, PageRegistration> registeredPages;\r
private boolean showAdmin;\r
- private boolean isOwner;\r
+ private boolean isRepoAdministrator;\r
\r
public RepositoryPage(PageParameters params) {\r
super(params);\r
} else {\r
showAdmin = GitBlit.getBoolean(Keys.web.allowAdministration, false);\r
}\r
- isOwner = GitBlitWebSession.get().isLoggedIn()\r
- && (model.owner != null && model.owner.equalsIgnoreCase(GitBlitWebSession.get()\r
+ isRepoAdministrator = GitBlitWebSession.get().isLoggedIn()\r
+ && (model.isRepoAdministrator(GitBlitWebSession.get()\r
.getUsername()));\r
- if (showAdmin || isOwner) {\r
+ if (showAdmin || isRepoAdministrator) {\r
pages.put("edit", new PageRegistration("gb.edit", EditRepositoryPage.class, params));\r
}\r
return pages;\r
}\r
\r
public boolean isOwner() {\r
- return isOwner;\r
+ return isRepoAdministrator;\r
}\r
\r
private class SearchForm extends SessionlessForm<Void> implements Serializable {\r
if (repositoryModel.accessRestriction.exceeds(AccessRestrictionType.NONE)\r
&& repositoryModel.authorizationControl.equals(AuthorizationControl.NAMED)) {\r
if (user != null &&\r
- (repositoryModel.isOwner(user.username) || repositoryModel.isUsersPersonalRepository(user.username))) {\r
+ (repositoryModel.isRepoAdministrator(user.username) || repositoryModel.isUsersPersonalRepository(user.username))) {\r
// exclude Owner or personal repositories\r
continue;\r
}\r
<div class="hidden-phone" style="padding-bottom: 10px;"> \r
<table class="plain">\r
<tr><th><wicket:message key="gb.description">[description]</wicket:message></th><td><span wicket:id="repositoryDescription">[repository description]</span></td></tr>\r
- <tr><th><wicket:message key="gb.owner">[owner]</wicket:message></th><td><span wicket:id="repositoryOwner">[repository owner]</span></td></tr>\r
+ <tr><th><wicket:message key="gb.repoAdministrators">[owner]</wicket:message></th><td><span wicket:id="repositoryAdministrators">[repository owner]</span></td></tr>\r
<tr><th><wicket:message key="gb.lastChange">[last change]</wicket:message></th><td><span wicket:id="repositoryLastChange">[repository last change]</span></td></tr>\r
<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>\r
<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>\r
import com.gitblit.utils.ArrayUtils;\r
import com.gitblit.utils.JGitUtils;\r
import com.gitblit.utils.MarkdownUtils;\r
+import com.gitblit.utils.MultiConfigUtil;\r
import com.gitblit.utils.StringUtils;\r
import com.gitblit.wicket.WicketUtils;\r
import com.gitblit.wicket.panels.BranchesPanel;\r
\r
public class SummaryPage extends RepositoryPage {\r
\r
+ private MultiConfigUtil multiConfigUtil = new MultiConfigUtil();\r
+ \r
public SummaryPage(PageParameters params) {\r
super(params);\r
\r
\r
// repository description\r
add(new Label("repositoryDescription", getRepositoryModel().description));\r
- String owner = getRepositoryModel().owner;\r
- if (StringUtils.isEmpty(owner)) {\r
- add(new Label("repositoryOwner").setVisible(false));\r
- } else {\r
- UserModel ownerModel = GitBlit.self().getUserModel(owner);\r
- if (ownerModel != null) {\r
- add(new LinkPanel("repositoryOwner", null, ownerModel.getDisplayName(), UserPage.class, WicketUtils.newUsernameParameter(owner)));\r
- } else {\r
- add(new Label("repositoryOwner", owner));\r
- }\r
+ String repoAdministrators = multiConfigUtil.convertCollectionToSingleLineString(getRepositoryModel().getRepoAdministrators());\r
+ if (StringUtils.isEmpty(repoAdministrators)) {\r
+ add(new Label("repositoryAdministrators").setVisible(false));\r
+ } else { \r
+ //TODO reimplement link panel for each username\r
+ add(new Label("repositoryAdministrators", repoAdministrators)); \r
}\r
\r
add(WicketUtils.createTimestampLabel("repositoryLastChange",\r
<img style="border:0px;vertical-align:middle;" src="feed_16x16.png"></img>\r
</a>\r
</div>\r
- <span style="color: #999;font-style:italic;font-size:0.8em;" wicket:id="repositoryOwner">[owner]</span>\r
+ <span style="color: #999;font-style:italic;font-size:0.8em;" wicket:id="repositoryAdministrators">[owner]</span>\r
</div> \r
\r
<div class="pageTitle" style="border:0px;">\r
import com.gitblit.models.RepositoryModel;\r
import com.gitblit.models.UserModel;\r
import com.gitblit.utils.ArrayUtils;\r
+import com.gitblit.utils.MultiConfigUtil;\r
import com.gitblit.utils.StringUtils;\r
import com.gitblit.wicket.GitBlitWebSession;\r
import com.gitblit.wicket.WicketUtils;\r
\r
private static final long serialVersionUID = 1L;\r
\r
- public ProjectRepositoryPanel(String wicketId, Localizer localizer, Component parent,\r
- final boolean isAdmin, final RepositoryModel entry,\r
+ private MultiConfigUtil multiConfigUtil = new MultiConfigUtil();\r
+\r
+ public ProjectRepositoryPanel(String wicketId, Localizer localizer,\r
+ Component parent, final boolean isAdmin,\r
+ final RepositoryModel entry,\r
final Map<AccessRestrictionType, String> accessRestrictions) {\r
super(wicketId);\r
\r
- final boolean showSwatch = GitBlit.getBoolean(Keys.web.repositoryListSwatches, true);\r
- final boolean gitServlet = GitBlit.getBoolean(Keys.git.enableGitServlet, true);\r
- final boolean showSize = GitBlit.getBoolean(Keys.web.showRepositorySizes, true);\r
+ final boolean showSwatch = GitBlit.getBoolean(\r
+ Keys.web.repositoryListSwatches, true);\r
+ final boolean gitServlet = GitBlit.getBoolean(\r
+ Keys.git.enableGitServlet, true);\r
+ final boolean showSize = GitBlit.getBoolean(\r
+ Keys.web.showRepositorySizes, true);\r
\r
// repository swatch\r
Component swatch;\r
if (entry.isBare) {\r
- swatch = new Label("repositorySwatch", " ").setEscapeModelStrings(false);\r
+ swatch = new Label("repositorySwatch", " ")\r
+ .setEscapeModelStrings(false);\r
} else {\r
swatch = new Label("repositorySwatch", "!");\r
- WicketUtils.setHtmlTooltip(swatch, localizer.getString("gb.workingCopyWarning", parent));\r
+ WicketUtils.setHtmlTooltip(swatch,\r
+ localizer.getString("gb.workingCopyWarning", parent));\r
}\r
WicketUtils.setCssBackground(swatch, entry.toString());\r
add(swatch);\r
swatch.setVisible(showSwatch);\r
\r
PageParameters pp = WicketUtils.newRepositoryParameter(entry.name);\r
- add(new LinkPanel("repositoryName", "list", StringUtils.getRelativePath(entry.projectPath,\r
- StringUtils.stripDotGit(entry.name)), SummaryPage.class, pp));\r
- add(new Label("repositoryDescription", entry.description).setVisible(!StringUtils\r
- .isEmpty(entry.description)));\r
+ add(new LinkPanel("repositoryName", "list",\r
+ StringUtils.getRelativePath(entry.projectPath,\r
+ StringUtils.stripDotGit(entry.name)),\r
+ SummaryPage.class, pp));\r
+ add(new Label("repositoryDescription", entry.description)\r
+ .setVisible(!StringUtils.isEmpty(entry.description)));\r
\r
if (StringUtils.isEmpty(entry.originRepository)) {\r
add(new Label("originRepository").setVisible(false));\r
} else {\r
- Fragment forkFrag = new Fragment("originRepository", "originFragment", this);\r
- forkFrag.add(new LinkPanel("originRepository", null, StringUtils.stripDotGit(entry.originRepository), \r
- SummaryPage.class, WicketUtils.newRepositoryParameter(entry.originRepository)));\r
+ Fragment forkFrag = new Fragment("originRepository",\r
+ "originFragment", this);\r
+ forkFrag.add(new LinkPanel("originRepository", null, StringUtils\r
+ .stripDotGit(entry.originRepository), SummaryPage.class,\r
+ WicketUtils.newRepositoryParameter(entry.originRepository)));\r
add(forkFrag);\r
}\r
\r
- add(new BookmarkablePageLink<Void>("tickets", TicketsPage.class, pp).setVisible(entry.useTickets));\r
- add(new BookmarkablePageLink<Void>("docs", DocsPage.class, pp).setVisible(entry.useDocs));\r
+ add(new BookmarkablePageLink<Void>("tickets", TicketsPage.class, pp)\r
+ .setVisible(entry.useTickets));\r
+ add(new BookmarkablePageLink<Void>("docs", DocsPage.class, pp)\r
+ .setVisible(entry.useDocs));\r
\r
if (entry.isFrozen) {\r
- add(WicketUtils.newImage("frozenIcon", "cold_16x16.png", localizer.getString("gb.isFrozen", parent)));\r
+ add(WicketUtils.newImage("frozenIcon", "cold_16x16.png",\r
+ localizer.getString("gb.isFrozen", parent)));\r
} else {\r
add(WicketUtils.newClearPixel("frozenIcon").setVisible(false));\r
}\r
\r
if (entry.isFederated) {\r
- add(WicketUtils.newImage("federatedIcon", "federated_16x16.png", localizer.getString("gb.isFederated", parent)));\r
+ add(WicketUtils.newImage("federatedIcon", "federated_16x16.png",\r
+ localizer.getString("gb.isFederated", parent)));\r
} else {\r
add(WicketUtils.newClearPixel("federatedIcon").setVisible(false));\r
}\r
switch (entry.accessRestriction) {\r
case NONE:\r
- add(WicketUtils.newBlankImage("accessRestrictionIcon").setVisible(false));\r
+ add(WicketUtils.newBlankImage("accessRestrictionIcon").setVisible(\r
+ false));\r
break;\r
case PUSH:\r
- add(WicketUtils.newImage("accessRestrictionIcon", "lock_go_16x16.png",\r
+ add(WicketUtils.newImage("accessRestrictionIcon",\r
+ "lock_go_16x16.png",\r
accessRestrictions.get(entry.accessRestriction)));\r
break;\r
case CLONE:\r
- add(WicketUtils.newImage("accessRestrictionIcon", "lock_pull_16x16.png",\r
+ add(WicketUtils.newImage("accessRestrictionIcon",\r
+ "lock_pull_16x16.png",\r
accessRestrictions.get(entry.accessRestriction)));\r
break;\r
case VIEW:\r
- add(WicketUtils.newImage("accessRestrictionIcon", "shield_16x16.png",\r
+ add(WicketUtils.newImage("accessRestrictionIcon",\r
+ "shield_16x16.png",\r
accessRestrictions.get(entry.accessRestriction)));\r
break;\r
default:\r
add(WicketUtils.newBlankImage("accessRestrictionIcon"));\r
}\r
\r
- if (StringUtils.isEmpty(entry.owner)) {\r
- add(new Label("repositoryOwner").setVisible(false));\r
+ if (entry.getRepoAdministrators().size() < 1) {\r
+ add(new Label("repositoryAdministrators").setVisible(false));\r
} else {\r
- UserModel ownerModel = GitBlit.self().getUserModel(entry.owner);\r
- String owner = entry.owner;\r
- if (ownerModel != null) {\r
- owner = ownerModel.getDisplayName();\r
- }\r
- add(new Label("repositoryOwner", owner + " (" +\r
- localizer.getString("gb.owner", parent) + ")"));\r
+ add(new Label("repositoryAdministrators",\r
+ multiConfigUtil.convertCollectionToSingleLineString(entry\r
+ .getRepoAdministrators())\r
+ + " ("\r
+ + localizer.getString("gb.repoAdministrators", parent) + ")"));\r
}\r
\r
UserModel user = GitBlitWebSession.get().getUser();\r
user = UserModel.ANONYMOUS;\r
}\r
Fragment repositoryLinks;\r
- boolean showOwner = entry.isOwner(user.username);\r
+ boolean isRepoAdministrator = entry.isRepoAdministrator(user.username);\r
// owner of personal repository gets admin powers\r
- boolean showAdmin = isAdmin || entry.isUsersPersonalRepository(user.username);\r
-\r
- if (showAdmin || showOwner) {\r
- repositoryLinks = new Fragment("repositoryLinks", showAdmin ? "repositoryAdminLinks"\r
- : "repositoryOwnerLinks", this);\r
- repositoryLinks.add(new BookmarkablePageLink<Void>("editRepository", EditRepositoryPage.class,\r
- WicketUtils.newRepositoryParameter(entry.name)));\r
+ boolean showAdmin = isAdmin\r
+ || entry.isUsersPersonalRepository(user.username);\r
+\r
+ if (showAdmin || isRepoAdministrator) {\r
+ repositoryLinks = new Fragment(\r
+ "repositoryLinks",\r
+ showAdmin ? "repositoryAdminLinks" : "repositoryOwnerLinks",\r
+ this);\r
+ repositoryLinks.add(new BookmarkablePageLink<Void>(\r
+ "editRepository", EditRepositoryPage.class, WicketUtils\r
+ .newRepositoryParameter(entry.name)));\r
if (showAdmin) {\r
Link<Void> deleteLink = new Link<Void>("deleteRepository") {\r
\r
if (GitBlit.self().deleteRepositoryModel(entry)) {\r
// redirect to the owning page\r
if (entry.isPersonalRepository()) {\r
- setResponsePage(getPage().getClass(), WicketUtils.newUsernameParameter(entry.projectPath.substring(1)));\r
+ setResponsePage(\r
+ getPage().getClass(),\r
+ WicketUtils\r
+ .newUsernameParameter(entry.projectPath\r
+ .substring(1)));\r
} else {\r
- setResponsePage(getPage().getClass(), WicketUtils.newProjectParameter(entry.projectPath));\r
+ setResponsePage(\r
+ getPage().getClass(),\r
+ WicketUtils\r
+ .newProjectParameter(entry.projectPath));\r
}\r
} else {\r
- error(MessageFormat.format(getString("gb.repositoryDeleteFailed"), entry));\r
+ error(MessageFormat.format(\r
+ getString("gb.repositoryDeleteFailed"),\r
+ entry));\r
}\r
}\r
};\r
- deleteLink.add(new JavascriptEventConfirmation("onclick", MessageFormat.format(\r
- localizer.getString("gb.deleteRepository", parent), entry)));\r
+ deleteLink.add(new JavascriptEventConfirmation("onclick",\r
+ MessageFormat.format(localizer.getString(\r
+ "gb.deleteRepository", parent), entry)));\r
repositoryLinks.add(deleteLink);\r
}\r
} else {\r
- repositoryLinks = new Fragment("repositoryLinks", "repositoryUserLinks", this);\r
+ repositoryLinks = new Fragment("repositoryLinks",\r
+ "repositoryUserLinks", this);\r
}\r
\r
- repositoryLinks.add(new BookmarkablePageLink<Void>("tree", TreePage.class, WicketUtils\r
- .newRepositoryParameter(entry.name)).setEnabled(entry.hasCommits));\r
+ repositoryLinks.add(new BookmarkablePageLink<Void>("tree",\r
+ TreePage.class, WicketUtils.newRepositoryParameter(entry.name))\r
+ .setEnabled(entry.hasCommits));\r
\r
- repositoryLinks.add(new BookmarkablePageLink<Void>("log", LogPage.class, WicketUtils\r
- .newRepositoryParameter(entry.name)).setEnabled(entry.hasCommits));\r
+ repositoryLinks.add(new BookmarkablePageLink<Void>("log",\r
+ LogPage.class, WicketUtils.newRepositoryParameter(entry.name))\r
+ .setEnabled(entry.hasCommits));\r
\r
add(repositoryLinks);\r
\r
}\r
Label lastChangeLabel = new Label("repositoryLastChange", lastChange);\r
add(lastChangeLabel);\r
- WicketUtils.setCssClass(lastChangeLabel, getTimeUtils().timeAgoCss(entry.lastChange));\r
+ WicketUtils.setCssClass(lastChangeLabel,\r
+ getTimeUtils().timeAgoCss(entry.lastChange));\r
\r
if (entry.hasCommits) {\r
// Existing repository\r
add(new Label("repositorySize", entry.size).setVisible(showSize));\r
} else {\r
// New repository\r
- add(new Label("repositorySize", localizer.getString("gb.empty", parent)).setEscapeModelStrings(false));\r
+ add(new Label("repositorySize", localizer.getString("gb.empty",\r
+ parent)).setEscapeModelStrings(false));\r
}\r
\r
- add(new ExternalLink("syndication", SyndicationServlet.asLink("", entry.name, null, 0)));\r
+ add(new ExternalLink("syndication", SyndicationServlet.asLink("",\r
+ entry.name, null, 0)));\r
\r
List<String> repositoryUrls = new ArrayList<String>();\r
if (gitServlet) {\r
}\r
repositoryUrls.addAll(GitBlit.self().getOtherCloneUrls(entry.name));\r
\r
- String primaryUrl = ArrayUtils.isEmpty(repositoryUrls) ? "" : repositoryUrls.remove(0);\r
+ String primaryUrl = ArrayUtils.isEmpty(repositoryUrls) ? ""\r
+ : repositoryUrls.remove(0);\r
add(new RepositoryUrlPanel("repositoryCloneUrl", primaryUrl));\r
}\r
}\r
item.add(administrator);
break;
case OWNER:
- Label owner = new Label("pType", getString("gb.owner"));
- WicketUtils.setHtmlTooltip(owner, getString("gb.ownerPermission"));
+ Label owner = new Label("pType", getString("gb.repoAdministrators"));
+ WicketUtils.setHtmlTooltip(owner, getString("gb.repoAdministratorPermission"));
WicketUtils.setCssClass(owner, "label label-info");
item.add(owner);
break;
<wicket:message key="gb.repository">Repository</wicket:message>\r
</th>\r
<th class="hidden-phone" wicket:id="orderByDescription"><wicket:message key="gb.description">Description</wicket:message></th>\r
- <th class="hidden-tablet hidden-phone" wicket:id="orderByOwner"><wicket:message key="gb.owner">Owner</wicket:message></th>\r
+ <th class="hidden-tablet hidden-phone" wicket:id="orderByOwner"><wicket:message key="gb.repoAdministrators">Owner</wicket:message></th>\r
<th class="hidden-phone"></th>\r
<th wicket:id="orderByDate"><wicket:message key="gb.lastChange">Last Change</wicket:message></th>\r
<th class="hidden-phone"></th>\r
<wicket:message key="gb.repository">Repository</wicket:message>\r
</th>\r
<th class="hidden-phone" ><span><wicket:message key="gb.description">Description</wicket:message></span></th>\r
- <th class="hidden-tablet hidden-phone"><span><wicket:message key="gb.owner">Owner</wicket:message></span></th>\r
+ <th class="hidden-tablet hidden-phone"><span><wicket:message key="gb.repoAdministrators">Owner</wicket:message></span></th>\r
<th class="hidden-phone"></th>\r
<th><wicket:message key="gb.lastChange">Last Change</wicket:message></th>\r
<th class="hidden-phone"></th>\r
<wicket:fragment wicket:id="repositoryRow">\r
<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>\r
<td class="hidden-phone"><span class="list" wicket:id="repositoryDescription">[repository description]</span></td>\r
- <td class="hidden-tablet hidden-phone author"><span wicket:id="repositoryOwner">[repository owner]</span></td>\r
+ <td class="hidden-tablet hidden-phone author"><span wicket:id="repositoryAdministrators">[repository owner]</span></td>\r
<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>\r
<td><span wicket:id="repositoryLastChange">[last change]</span></td>\r
<td class="hidden-phone" style="text-align: right;padding-right:15px;"><span style="font-size:0.8em;" wicket:id="repositorySize">[repository size]</span></td>\r
import com.gitblit.models.ProjectModel;\r
import com.gitblit.models.RepositoryModel;\r
import com.gitblit.models.UserModel;\r
+import com.gitblit.utils.MultiConfigUtil;\r
import com.gitblit.utils.StringUtils;\r
import com.gitblit.wicket.GitBlitWebSession;\r
import com.gitblit.wicket.WicketUtils;\r
\r
private static final long serialVersionUID = 1L;\r
\r
+ private MultiConfigUtil multiConfigUtil = new MultiConfigUtil();\r
+ \r
public RepositoriesPanel(String wicketId, final boolean showAdmin, final boolean showManagement,\r
List<RepositoryModel> models, boolean enableLinks,\r
final Map<AccessRestrictionType, String> accessRestrictionTranslations) {\r
row.add(WicketUtils.newBlankImage("accessRestrictionIcon"));\r
}\r
\r
- String owner = entry.owner;\r
- if (!StringUtils.isEmpty(owner)) {\r
- UserModel ownerModel = GitBlit.self().getUserModel(owner);\r
- if (ownerModel != null) {\r
- owner = ownerModel.getDisplayName();\r
- }\r
- }\r
- row.add(new Label("repositoryOwner", owner));\r
+ row.add(new Label("repositoryAdministrators", multiConfigUtil.convertCollectionToSingleLineString(entry.getRepoAdministrators())));\r
\r
String lastChange;\r
if (entry.lastChange.getTime() == 0) {\r
row.add(lastChangeLabel);\r
WicketUtils.setCssClass(lastChangeLabel, getTimeUtils().timeAgoCss(entry.lastChange));\r
\r
- boolean showOwner = user != null && entry.isOwner(user.username);\r
- boolean myPersonalRepository = showOwner && entry.isUsersPersonalRepository(user.username);\r
+ boolean isRepoAdministrator = user != null && entry.isRepoAdministrator(user.username);\r
+ boolean myPersonalRepository = isRepoAdministrator && entry.isUsersPersonalRepository(user.username);\r
if (showAdmin || myPersonalRepository) {\r
Fragment repositoryLinks = new Fragment("repositoryLinks",\r
"repositoryAdminLinks", this);\r
repositoryLinks.add(new BookmarkablePageLink<Void>("editRepository",\r
EditRepositoryPage.class, WicketUtils\r
.newRepositoryParameter(entry.name)));\r
- Link<Void> deleteLink = new Link<Void>("deleteRepository") {\r
-\r
- private static final long serialVersionUID = 1L;\r
-\r
- @Override\r
- public void onClick() {\r
- if (GitBlit.self().deleteRepositoryModel(entry)) {\r
- if (dp instanceof SortableRepositoriesProvider) {\r
- info(MessageFormat.format(getString("gb.repositoryDeleted"), entry));\r
- ((SortableRepositoriesProvider) dp).remove(entry);\r
- } else {\r
- setResponsePage(getPage().getClass(), getPage().getPageParameters());\r
- }\r
- } else {\r
- error(MessageFormat.format(getString("gb.repositoryDeleteFailed"), entry));\r
- }\r
- }\r
- };\r
+ Link<Void> deleteLink = new DeleteLink(entry, dp);\r
deleteLink.add(new JavascriptEventConfirmation("onclick", MessageFormat.format(\r
getString("gb.deleteRepository"), entry)));\r
repositoryLinks.add(deleteLink);\r
row.add(repositoryLinks);\r
- } else if (showOwner) {\r
+ } else if (isRepoAdministrator) {\r
Fragment repositoryLinks = new Fragment("repositoryLinks",\r
- "repositoryOwnerLinks", this);\r
+ "repositoryAdminLinks", this);\r
repositoryLinks.add(new BookmarkablePageLink<Void>("editRepository",\r
EditRepositoryPage.class, WicketUtils\r
.newRepositoryParameter(entry.name)));\r
+ Link<Void> deleteLink = new DeleteLink(entry, dp);\r
+ deleteLink.add(new JavascriptEventConfirmation("onclick", MessageFormat.format(\r
+ getString("gb.deleteRepository"), entry)));\r
+ repositoryLinks.add(deleteLink);\r
row.add(repositoryLinks);\r
} else {\r
row.add(new Label("repositoryLinks"));\r
}\r
}\r
\r
+ private class DeleteLink extends Link<Void> {\r
+ private RepositoryModel entry;\r
+\r
+ private IDataProvider<RepositoryModel> dp;\r
+ \r
+ private static final long serialVersionUID = 1L;\r
+\r
+ public DeleteLink(RepositoryModel entry, IDataProvider<RepositoryModel> dp) {\r
+ super("deleteRepository");\r
+ this.entry=entry;\r
+ this.dp=dp;\r
+ }\r
+ \r
+ @Override\r
+ public void onClick() {\r
+ if (GitBlit.self().deleteRepositoryModel(entry)) {\r
+ if (dp instanceof SortableRepositoriesProvider) {\r
+ info(MessageFormat.format(getString("gb.repositoryDeleted"), entry));\r
+ ((SortableRepositoriesProvider) dp).remove(entry);\r
+ } else {\r
+ setResponsePage(getPage().getClass(), getPage().getPageParameters());\r
+ }\r
+ } else {\r
+ error(MessageFormat.format(getString("gb.repositoryDeleteFailed"), entry));\r
+ }\r
+ }\r
+ \r
+ }\r
+ \r
private static class GroupRepositoryModel extends RepositoryModel {\r
\r
private static final long serialVersionUID = 1L;\r
\r
private List<RepositoryModel> list;\r
\r
+ private MultiConfigUtil multiConfigUtil = new MultiConfigUtil();\r
+ \r
protected SortableRepositoriesProvider(List<RepositoryModel> list) {\r
this.list = list;\r
setSort(SortBy.date.name(), false);\r
@Override\r
public int compare(RepositoryModel o1, RepositoryModel o2) {\r
if (asc) {\r
- return o1.owner.compareTo(o2.owner);\r
+ return multiConfigUtil.convertCollectionToSingleLineString(o1.getRepoAdministrators()).compareTo(multiConfigUtil.convertCollectionToSingleLineString(o2.getRepoAdministrators()));\r
}\r
- return o2.owner.compareTo(o1.owner);\r
+ return multiConfigUtil.convertCollectionToSingleLineString(o2.getRepoAdministrators()).compareTo(multiConfigUtil.convertCollectionToSingleLineString(o1.getRepoAdministrators()));\r
}\r
});\r
} else if (prop.equals(SortBy.description.name())) {\r
model.accessRestriction = AccessRestrictionType.VIEW;\r
model.description = "cloneable repository " + i;\r
model.lastChange = new Date();\r
- model.owner = "adminuser";\r
+ model.addRepoAdministrator("adminuser");\r
model.name = "repo" + i + ".git";\r
model.size = "5 MB";\r
model.hasCommits = true;\r
import com.gitblit.models.RepositoryModel;\r
import com.gitblit.models.UserModel;\r
import com.gitblit.utils.JGitUtils;\r
+import com.gitblit.utils.MultiConfigUtil;\r
import com.gitblit.utils.PushLogUtils;\r
\r
public class GitServletTest {\r
String password = GitBlitSuite.password;\r
\r
private static final AtomicBoolean started = new AtomicBoolean(false);\r
+ \r
+ private MultiConfigUtil multiConfigUtil = new MultiConfigUtil();\r
\r
@BeforeClass\r
public static void startGitblit() throws Exception {\r
\r
// confirm default personal repository permissions\r
RepositoryModel model = GitBlit.self().getRepositoryModel(MessageFormat.format("~{0}/ticgit.git", user.username));\r
- assertEquals("Unexpected owner", user.username, model.owner);\r
+ assertEquals("Unexpected owner", user.username, multiConfigUtil.convertCollectionToSingleLineString(model.getRepoAdministrators()));\r
assertEquals("Unexpected authorization control", AuthorizationControl.NAMED, model.authorizationControl);\r
assertEquals("Unexpected access restriction", AccessRestrictionType.VIEW, model.accessRestriction);\r
\r
\r
// confirm default project repository permissions\r
RepositoryModel model = GitBlit.self().getRepositoryModel("project/ticgit.git");\r
- assertEquals("Unexpected owner", user.username, model.owner);\r
+ assertEquals("Unexpected owner", user.username, multiConfigUtil.convertCollectionToSingleLineString(model.getRepoAdministrators()));\r
assertEquals("Unexpected authorization control", AuthorizationControl.fromName(GitBlit.getString(Keys.git.defaultAuthorizationControl, "NAMED")), model.authorizationControl);\r
assertEquals("Unexpected access restriction", AccessRestrictionType.fromName(GitBlit.getString(Keys.git.defaultAccessRestriction, "NONE")), model.accessRestriction);\r
\r
repository.accessRestriction = AccessRestrictionType.VIEW;
UserModel user = new UserModel("test");
- repository.owner = user.username;
+ repository.addRepoAdministrator(user.username);
assertFalse("user SHOULD NOT HAVE a repository permission!", user.hasRepositoryPermission(repository.name));
assertTrue("owner CAN NOT view!", user.canView(repository));
repository.accessRestriction = AccessRestrictionType.VIEW;
UserModel user = new UserModel("test");
- repository.owner = user.username;
+ repository.addRepoAdministrator(user.username);
assertFalse("user SHOULD NOT HAVE a repository permission!", user.hasRepositoryPermission(repository.name));
assertTrue("user CAN NOT view!", user.canView(repository));
repository.accessRestriction = AccessRestrictionType.VIEW;
UserModel user = new UserModel("visitor");
- repository.owner = "test";
+ repository.addRepoAdministrator("test");
assertFalse("user HAS a repository permission!", user.hasRepositoryPermission(repository.name));
assertFalse("user CAN view!", user.canView(repository));
RepositoryModel model = new RepositoryModel();\r
model.name = "garbagerepo.git";\r
model.description = "created by RpcUtils";\r
- model.owner = "garbage";\r
+ model.addRepoAdministrator("garbage");\r
model.accessRestriction = AccessRestrictionType.VIEW;\r
model.authorizationControl = AuthorizationControl.AUTHENTICATED;\r
\r