@@ -163,6 +163,17 @@ git.defaultAccessRestriction = NONE | |||
# SINCE 1.1.0 | |||
git.defaultAuthorizationControl = NAMED | |||
# The prefix for a users personal repository directory. | |||
# Personal user repositories are created in this directory, named by the user name | |||
# prefixed with the userRepositoeryPrefix. For eaxmple, a user 'john' would have his | |||
# personal repositories in the directory '~john'. | |||
# Cannot be an empty string. Also, absolute paths are changed to relative paths by | |||
# removing the first directory separator. | |||
# | |||
# RESTART REQUIRED | |||
# SINCE 1.3.2 | |||
git.userRepositoryPrefix = "~" | |||
# The default incremental push tag prefix. Tag prefix applied to a repository | |||
# that has automatic push tags enabled and does not specify a custom tag prefix. | |||
# |
@@ -125,6 +125,7 @@ import com.gitblit.utils.JGitUtils; | |||
import com.gitblit.utils.JGitUtils.LastChange; | |||
import com.gitblit.utils.JsonUtils; | |||
import com.gitblit.utils.MetricUtils; | |||
import com.gitblit.utils.ModelUtils; | |||
import com.gitblit.utils.ObjectCache; | |||
import com.gitblit.utils.StringUtils; | |||
import com.gitblit.utils.TimeUtils; | |||
@@ -1243,8 +1244,8 @@ public class GitBlit implements ServletContextListener { | |||
// personal repository | |||
model.addOwner(user.username); | |||
String oldRepositoryName = model.name; | |||
model.name = "~" + user.username + model.name.substring(model.projectPath.length()); | |||
model.projectPath = "~" + user.username; | |||
model.name = user.getPersonalPath() + model.name.substring(model.projectPath.length()); | |||
model.projectPath = user.getPersonalPath(); | |||
updateRepositoryModel(oldRepositoryName, model, false); | |||
} else if (model.isOwner(username)) { | |||
// common/shared repo | |||
@@ -1853,8 +1854,8 @@ public class GitBlit implements ServletContextListener { | |||
ProjectModel project = configs.get(name.toLowerCase()); | |||
if (project == null) { | |||
project = new ProjectModel(name); | |||
if (name.length() > 0 && name.charAt(0) == '~') { | |||
UserModel user = getUserModel(name.substring(1)); | |||
if (ModelUtils.isPersonalRepository(name)) { | |||
UserModel user = getUserModel(ModelUtils.getUserNameFromRepoPath(name)); | |||
if (user != null) { | |||
project.title = user.getDisplayName(); | |||
project.description = "personal repositories"; | |||
@@ -2126,7 +2127,7 @@ public class GitBlit implements ServletContextListener { | |||
* @return the name of the user's fork, null otherwise | |||
*/ | |||
public String getFork(String username, String origin) { | |||
String userProject = "~" + username.toLowerCase(); | |||
String userProject = ModelUtils.getPersonalPath(username); | |||
if (settings.getBoolean(Keys.git.cacheRepositoryList, true)) { | |||
String userPath = userProject + "/"; | |||
@@ -3439,6 +3440,9 @@ public class GitBlit implements ServletContextListener { | |||
luceneExecutor = new LuceneExecutor(settings, repositoriesFolder); | |||
gcExecutor = new GCExecutor(settings); | |||
// initialize utilities | |||
ModelUtils.setUserRepoPrefix(settings); | |||
// calculate repository list settings checksum for future config changes | |||
repositoryListSettingsChecksum.set(getRepositoryListSettingsChecksum()); | |||
@@ -3818,7 +3822,7 @@ public class GitBlit implements ServletContextListener { | |||
* @throws GitBlitException | |||
*/ | |||
public RepositoryModel fork(RepositoryModel repository, UserModel user) throws GitBlitException { | |||
String cloneName = MessageFormat.format("~{0}/{1}.git", user.username, StringUtils.stripDotGit(StringUtils.getLastPathElement(repository.name))); | |||
String cloneName = MessageFormat.format("{0}/{1}.git", user.getPersonalPath(), StringUtils.stripDotGit(StringUtils.getLastPathElement(repository.name))); | |||
String fromUrl = MessageFormat.format("file://{0}/{1}", repositoriesFolder.getAbsolutePath(), repository.name); | |||
// clone the repository |
@@ -51,6 +51,7 @@ import com.gitblit.models.RegistrantAccessPermission; | |||
import com.gitblit.models.RepositoryModel; | |||
import com.gitblit.models.ServerSettings; | |||
import com.gitblit.models.TeamModel; | |||
import com.gitblit.utils.ModelUtils; | |||
import com.gitblit.utils.StringUtils; | |||
public class EditTeamDialog extends JDialog { | |||
@@ -177,7 +178,7 @@ public class EditTeamDialog extends JDialog { | |||
postReceivePalette = new JPalette<String>(true); | |||
postReceiveInherited = new JLabel(); | |||
JPanel postReceivePanel = new JPanel(new BorderLayout(5, 5)); | |||
postReceivePanel.add(postReceivePalette, BorderLayout.CENTER); | |||
postReceivePanel.add(postReceivePalette, BorderLayout.CENTER); | |||
postReceivePanel.add(postReceiveInherited, BorderLayout.WEST); | |||
JTabbedPane panel = new JTabbedPane(JTabbedPane.TOP); | |||
@@ -323,7 +324,7 @@ public class EditTeamDialog extends JDialog { | |||
// repositories | |||
list.add(".*"); | |||
// all repositories excluding personal repositories | |||
list.add("[^~].*"); | |||
if (ModelUtils.getUserRepoPrefix().length() == 1) list.add("[^" + ModelUtils.getUserRepoPrefix() +"].*"); | |||
String lastProject = null; | |||
for (String repo : restricted) { | |||
String projectPath = StringUtils.getFirstPathElement(repo); |
@@ -57,6 +57,7 @@ import com.gitblit.models.RepositoryModel; | |||
import com.gitblit.models.ServerSettings; | |||
import com.gitblit.models.TeamModel; | |||
import com.gitblit.models.UserModel; | |||
import com.gitblit.utils.ModelUtils; | |||
import com.gitblit.utils.StringUtils; | |||
public class EditUserDialog extends JDialog { | |||
@@ -403,7 +404,7 @@ public class EditUserDialog extends JDialog { | |||
// repositories | |||
list.add(".*"); | |||
// all repositories excluding personal repositories | |||
list.add("[^~].*"); | |||
if (ModelUtils.getUserRepoPrefix().length() == 1) list.add("[^" + ModelUtils.getUserRepoPrefix() +"].*"); | |||
String lastProject = null; | |||
for (String repo : restricted) { | |||
String projectPath = StringUtils.getFirstPathElement(repo).toLowerCase(); |
@@ -21,6 +21,7 @@ import java.util.Date; | |||
import java.util.HashSet; | |||
import java.util.Set; | |||
import com.gitblit.utils.ModelUtils; | |||
import com.gitblit.utils.StringUtils; | |||
/** | |||
@@ -57,7 +58,7 @@ public class ProjectModel implements Serializable, Comparable<ProjectModel> { | |||
} | |||
public boolean isUserProject() { | |||
return name.charAt(0) == '~'; | |||
return ModelUtils.isPersonalRepository(name); | |||
} | |||
public boolean hasRepository(String name) { |
@@ -28,6 +28,7 @@ import com.gitblit.Constants.AccessRestrictionType; | |||
import com.gitblit.Constants.AuthorizationControl; | |||
import com.gitblit.Constants.FederationStrategy; | |||
import com.gitblit.utils.ArrayUtils; | |||
import com.gitblit.utils.ModelUtils; | |||
import com.gitblit.utils.StringUtils; | |||
/** | |||
@@ -177,11 +178,11 @@ public class RepositoryModel implements Serializable, Comparable<RepositoryModel | |||
} | |||
public boolean isPersonalRepository() { | |||
return !StringUtils.isEmpty(projectPath) && projectPath.charAt(0) == '~'; | |||
return !StringUtils.isEmpty(projectPath) && ModelUtils.isPersonalRepository(projectPath); | |||
} | |||
public boolean isUsersPersonalRepository(String username) { | |||
return !StringUtils.isEmpty(projectPath) && projectPath.equalsIgnoreCase("~" + username); | |||
return !StringUtils.isEmpty(projectPath) && ModelUtils.isUsersPersonalRepository(username, projectPath); | |||
} | |||
public boolean allowAnonymousView() { |
@@ -35,6 +35,7 @@ import com.gitblit.Constants.PermissionType; | |||
import com.gitblit.Constants.RegistrantType; | |||
import com.gitblit.Constants.Unused; | |||
import com.gitblit.utils.ArrayUtils; | |||
import com.gitblit.utils.ModelUtils; | |||
import com.gitblit.utils.StringUtils; | |||
/** | |||
@@ -567,7 +568,7 @@ public class UserModel implements Principal, Serializable, Comparable<UserModel> | |||
} | |||
if (canCreate) { | |||
String projectPath = StringUtils.getFirstPathElement(repository); | |||
if (!StringUtils.isEmpty(projectPath) && projectPath.equalsIgnoreCase("~" + username)) { | |||
if (!StringUtils.isEmpty(projectPath) && projectPath.equalsIgnoreCase(getPersonalPath())) { | |||
// personal repository | |||
return true; | |||
} | |||
@@ -609,7 +610,7 @@ public class UserModel implements Principal, Serializable, Comparable<UserModel> | |||
} | |||
public String getPersonalPath() { | |||
return "~" + username; | |||
return ModelUtils.getPersonalPath(username); | |||
} | |||
public UserPreferences getPreferences() { | |||
@@ -675,6 +676,6 @@ public class UserModel implements Principal, Serializable, Comparable<UserModel> | |||
public boolean isMyPersonalRepository(String repository) { | |||
String projectPath = StringUtils.getFirstPathElement(repository); | |||
return !StringUtils.isEmpty(projectPath) && projectPath.equalsIgnoreCase("~" + username); | |||
return !StringUtils.isEmpty(projectPath) && projectPath.equalsIgnoreCase(getPersonalPath()); | |||
} | |||
} |
@@ -0,0 +1,107 @@ | |||
package com.gitblit.utils; | |||
import com.gitblit.IStoredSettings; | |||
import com.gitblit.Keys; | |||
/** | |||
* Utility functions for model classes that do not fit in any other category. | |||
* | |||
* @author Florian Zschocke | |||
*/ | |||
public class ModelUtils | |||
{ | |||
/** | |||
* Default value for the prefix for user repository directories. | |||
*/ | |||
private static final String DEFAULT_USER_REPO_PREFIX = "~"; | |||
private static String userRepoPrefix = DEFAULT_USER_REPO_PREFIX; | |||
/** | |||
* Set the user repository prefix from configuration settings. | |||
* @param settings | |||
*/ | |||
public static void setUserRepoPrefix(IStoredSettings settings) | |||
{ | |||
String newPrefix = DEFAULT_USER_REPO_PREFIX; | |||
if (settings != null) { | |||
String prefix = settings.getString(Keys.git.userRepositoryPrefix, DEFAULT_USER_REPO_PREFIX); | |||
if (prefix != null && !prefix.trim().isEmpty()) { | |||
if (prefix.charAt(0) == '/') prefix = prefix.substring(1); | |||
newPrefix = prefix; | |||
} | |||
} | |||
userRepoPrefix = newPrefix; | |||
} | |||
/** | |||
* Get the active user repository project prefix. | |||
*/ | |||
public static String getUserRepoPrefix() | |||
{ | |||
return userRepoPrefix; | |||
} | |||
/** | |||
* Get the user project name for a user. | |||
* | |||
* @param username name of user | |||
* @return the active user repository project prefix concatenated with the user name | |||
*/ | |||
public static String getPersonalPath(String username) | |||
{ | |||
return userRepoPrefix + username.toLowerCase(); | |||
} | |||
/** | |||
* Test if a repository path is for a personal repository. | |||
* | |||
* @param name | |||
* A project name, a relative path to a repository. | |||
* @return true, if the name starts with the active user repository project prefix. False, otherwise. | |||
*/ | |||
public static boolean isPersonalRepository(String name) | |||
{ | |||
if ( name.startsWith(getUserRepoPrefix()) ) return true; | |||
return false; | |||
} | |||
/** | |||
* Test if a repository path is for a personal repository of a specific user. | |||
* | |||
* @param username | |||
* Name of a user | |||
* @param name | |||
* A project name, a relative path to a repository. | |||
* @return true, if the name starts with the active user repository project prefix. False, otherwise. | |||
*/ | |||
public static boolean isUsersPersonalRepository(String username, String name) | |||
{ | |||
if ( name.equalsIgnoreCase(getPersonalPath(username)) ) return true; | |||
return false; | |||
} | |||
/** | |||
* Exrtract a user's name from a personal repository path. | |||
* | |||
* @param path | |||
* A project name, a relative path to a repository. | |||
* @return If the path does not point to a personal repository, an empty string is returned. | |||
* Otherwise the name of the user the personal repository belongs to is returned. | |||
*/ | |||
public static String getUserNameFromRepoPath(String path) | |||
{ | |||
if ( !isPersonalRepository(path) ) return ""; | |||
return path.substring(getUserRepoPrefix().length()); | |||
} | |||
} |
@@ -51,6 +51,7 @@ import com.gitblit.Keys; | |||
import com.gitblit.models.RepositoryModel; | |||
import com.gitblit.models.TeamModel; | |||
import com.gitblit.models.UserModel; | |||
import com.gitblit.utils.ModelUtils; | |||
import com.gitblit.utils.StringUtils; | |||
import com.gitblit.wicket.GitBlitWebSession; | |||
import com.gitblit.wicket.PageRegistration; | |||
@@ -393,7 +394,7 @@ public abstract class RootPage extends BasePage { | |||
String userName = WicketUtils.getUsername(params); | |||
if (StringUtils.isEmpty(projectName)) { | |||
if (!StringUtils.isEmpty(userName)) { | |||
projectName = "~" + userName; | |||
projectName = ModelUtils.getPersonalPath(userName); | |||
} | |||
} | |||
String repositoryName = WicketUtils.getRepositoryName(params); |
@@ -27,6 +27,7 @@ import com.gitblit.Constants.AuthorizationControl; | |||
import com.gitblit.GitBlit; | |||
import com.gitblit.models.RepositoryModel; | |||
import com.gitblit.models.UserModel; | |||
import com.gitblit.utils.ModelUtils; | |||
import com.gitblit.utils.StringUtils; | |||
/** | |||
@@ -80,7 +81,7 @@ public abstract class RootSubPage extends RootPage { | |||
// all repositories | |||
repos.add(".*"); | |||
// all repositories excluding personal repositories | |||
repos.add("[^~].*"); | |||
if (ModelUtils.getUserRepoPrefix().length() == 1) repos.add("[^" + ModelUtils.getUserRepoPrefix() +"].*"); | |||
} | |||
for (String repo : GitBlit.self().getRepositoryList()) { |
@@ -84,7 +84,7 @@ public class UserPage extends RootPage { | |||
user = new UserModel(userName); | |||
} | |||
String projectName = "~" + userName; | |||
String projectName = user.getPersonalPath(); | |||
ProjectModel project = GitBlit.self().getProjectModel(projectName); | |||
if (project == null) { |
@@ -50,6 +50,7 @@ import com.gitblit.models.ProjectModel; | |||
import com.gitblit.models.RepositoryModel; | |||
import com.gitblit.models.UserModel; | |||
import com.gitblit.utils.ArrayUtils; | |||
import com.gitblit.utils.ModelUtils; | |||
import com.gitblit.utils.StringUtils; | |||
import com.gitblit.wicket.GitBlitWebSession; | |||
import com.gitblit.wicket.WicketUtils; | |||
@@ -169,9 +170,9 @@ public class RepositoriesPanel extends BasePanel { | |||
item.add(row); | |||
String name = groupRow.name; | |||
if (name.charAt(0) == '~') { | |||
if (name.startsWith(ModelUtils.getUserRepoPrefix())) { | |||
// user page | |||
String username = name.substring(1); | |||
String username = ModelUtils.getUserNameFromRepoPath(name); | |||
UserModel user = GitBlit.self().getUserModel(username); | |||
row.add(new LinkPanel("groupName", null, (user == null ? username : user.getDisplayName()) + " (" + groupRow.count + ")", UserPage.class, WicketUtils.newUsernameParameter(username))); | |||
row.add(new Label("groupDescription", getString("gb.personalRepositories"))); |
@@ -0,0 +1,167 @@ | |||
package com.gitblit.tests; | |||
import static org.junit.Assert.assertEquals; | |||
import static org.junit.Assert.assertFalse; | |||
import static org.junit.Assert.assertTrue; | |||
import java.util.HashMap; | |||
import java.util.Map; | |||
import org.junit.After; | |||
import org.junit.Test; | |||
import com.gitblit.Keys; | |||
import com.gitblit.tests.mock.MemorySettings; | |||
import com.gitblit.utils.ModelUtils; | |||
public class ModelUtilsTest { | |||
private static final String DEFAULT_USER_REPO_PREFIX = "~"; | |||
private static final Map<String, Object> backingMap = new HashMap<String, Object>(); | |||
private static final MemorySettings ms = new MemorySettings(backingMap); | |||
private static void setPrefix(String prefix) | |||
{ | |||
backingMap.put(Keys.git.userRepositoryPrefix, prefix); | |||
} | |||
private static void setRepoPrefix(String prefix) | |||
{ | |||
backingMap.put(Keys.git.userRepositoryPrefix, prefix); | |||
ModelUtils.setUserRepoPrefix(ms); | |||
} | |||
@After | |||
public void resetPrefix() | |||
{ | |||
setRepoPrefix(DEFAULT_USER_REPO_PREFIX); | |||
} | |||
@Test | |||
public void testGetUserRepoPrefix() | |||
{ | |||
assertEquals(DEFAULT_USER_REPO_PREFIX, ModelUtils.getUserRepoPrefix()); | |||
} | |||
@Test | |||
public void testSetUserRepoPrefix() | |||
{ | |||
assertEquals(DEFAULT_USER_REPO_PREFIX, ModelUtils.getUserRepoPrefix()); | |||
setPrefix("@"); | |||
ModelUtils.setUserRepoPrefix(ms); | |||
assertEquals("@", ModelUtils.getUserRepoPrefix()); | |||
backingMap.remove(Keys.git.userRepositoryPrefix); | |||
ModelUtils.setUserRepoPrefix(ms); | |||
assertEquals(DEFAULT_USER_REPO_PREFIX, ModelUtils.getUserRepoPrefix()); | |||
setPrefix("user/"); | |||
ModelUtils.setUserRepoPrefix(ms); | |||
assertEquals("user/", ModelUtils.getUserRepoPrefix()); | |||
setPrefix(""); | |||
ModelUtils.setUserRepoPrefix(ms); | |||
assertEquals(DEFAULT_USER_REPO_PREFIX, ModelUtils.getUserRepoPrefix()); | |||
setPrefix("u_"); | |||
ModelUtils.setUserRepoPrefix(ms); | |||
assertEquals("u_", ModelUtils.getUserRepoPrefix()); | |||
ModelUtils.setUserRepoPrefix(null); | |||
assertEquals(DEFAULT_USER_REPO_PREFIX, ModelUtils.getUserRepoPrefix()); | |||
setPrefix("/somedir/otherdir/"); | |||
ModelUtils.setUserRepoPrefix(ms); | |||
assertEquals("somedir/otherdir/", ModelUtils.getUserRepoPrefix()); | |||
setPrefix(DEFAULT_USER_REPO_PREFIX); | |||
ModelUtils.setUserRepoPrefix(ms); | |||
assertEquals(DEFAULT_USER_REPO_PREFIX, ModelUtils.getUserRepoPrefix()); | |||
} | |||
@Test | |||
public void testGetPersonalPath() | |||
{ | |||
String username = "rob"; | |||
assertEquals(DEFAULT_USER_REPO_PREFIX+username.toLowerCase(), ModelUtils.getPersonalPath(username)); | |||
username = "James"; | |||
assertEquals(DEFAULT_USER_REPO_PREFIX+username.toLowerCase(), ModelUtils.getPersonalPath(username)); | |||
setRepoPrefix("usr/"); | |||
username = "noMan"; | |||
assertEquals("usr/"+username.toLowerCase(), ModelUtils.getPersonalPath(username)); | |||
} | |||
@Test | |||
public void testIsPersonalRepository() | |||
{ | |||
String reponame = DEFAULT_USER_REPO_PREFIX + "one"; | |||
assertTrue(ModelUtils.isPersonalRepository(reponame)); | |||
reponame = "none"; | |||
assertFalse(ModelUtils.isPersonalRepository(reponame)); | |||
setRepoPrefix("@@"); | |||
reponame = "@@two"; | |||
assertTrue(ModelUtils.isPersonalRepository(reponame)); | |||
setRepoPrefix("users/"); | |||
reponame = "users/three"; | |||
assertTrue(ModelUtils.isPersonalRepository(reponame)); | |||
reponame = "project/four"; | |||
assertFalse(ModelUtils.isPersonalRepository(reponame)); | |||
} | |||
@Test | |||
public void testIsUsersPersonalRepository() | |||
{ | |||
String reponame = DEFAULT_USER_REPO_PREFIX + "lynn"; | |||
assertTrue(ModelUtils.isUsersPersonalRepository("lynn", reponame)); | |||
reponame = "prjB"; | |||
assertFalse(ModelUtils.isUsersPersonalRepository("lynn", reponame)); | |||
setRepoPrefix("@@"); | |||
reponame = "@@newton"; | |||
assertTrue(ModelUtils.isUsersPersonalRepository("newton", reponame)); | |||
assertFalse(ModelUtils.isUsersPersonalRepository("hertz", reponame)); | |||
setRepoPrefix("users/"); | |||
reponame = "users/fee"; | |||
assertTrue(ModelUtils.isUsersPersonalRepository("fee", reponame)); | |||
assertFalse(ModelUtils.isUsersPersonalRepository("gnome", reponame)); | |||
reponame = "project/nsbl"; | |||
assertFalse(ModelUtils.isUsersPersonalRepository("fee", reponame)); | |||
} | |||
@Test | |||
public void testGetUserNameFromRepoPath() | |||
{ | |||
String reponame = DEFAULT_USER_REPO_PREFIX + "lynn"; | |||
assertEquals("lynn", ModelUtils.getUserNameFromRepoPath(reponame)); | |||
setRepoPrefix("@@"); | |||
reponame = "@@newton"; | |||
assertEquals("newton", ModelUtils.getUserNameFromRepoPath(reponame)); | |||
setRepoPrefix("users/"); | |||
reponame = "users/fee"; | |||
assertEquals("fee", ModelUtils.getUserNameFromRepoPath(reponame)); | |||
} | |||
} |