From 6651a8e96bdc51b0c558b88e1c77fcfbed1837da Mon Sep 17 00:00:00 2001 From: James Moger Date: Sun, 8 Jun 2014 10:30:39 -0400 Subject: Move repository ownership to the UserModel and prepare for project ownership --- .../java/com/gitblit/manager/GitblitManager.java | 50 +++++++++---------- .../java/com/gitblit/manager/IUserManager.java | 32 +++++++++++++ .../java/com/gitblit/manager/ProjectManager.java | 10 ++-- .../com/gitblit/manager/RepositoryManager.java | 32 +++++++------ src/main/java/com/gitblit/manager/UserManager.java | 56 ++++++++++++++++++++++ 5 files changed, 133 insertions(+), 47 deletions(-) (limited to 'src/main/java/com/gitblit/manager') diff --git a/src/main/java/com/gitblit/manager/GitblitManager.java b/src/main/java/com/gitblit/manager/GitblitManager.java index 98ad33e7..54ed0ed2 100644 --- a/src/main/java/com/gitblit/manager/GitblitManager.java +++ b/src/main/java/com/gitblit/manager/GitblitManager.java @@ -62,6 +62,7 @@ import com.gitblit.models.ForkModel; import com.gitblit.models.GitClientApplication; import com.gitblit.models.Mailing; import com.gitblit.models.Metric; +import com.gitblit.models.Owner; import com.gitblit.models.PluginRegistry.InstallState; import com.gitblit.models.PluginRegistry.PluginRegistration; import com.gitblit.models.PluginRegistry.PluginRelease; @@ -78,7 +79,6 @@ import com.gitblit.models.UserModel; import com.gitblit.tickets.ITicketService; import com.gitblit.transport.ssh.IPublicKeyManager; import com.gitblit.transport.ssh.SshKey; -import com.gitblit.utils.ArrayUtils; import com.gitblit.utils.HttpUtils; import com.gitblit.utils.JsonUtils; import com.gitblit.utils.ObjectCache; @@ -176,7 +176,7 @@ public class GitblitManager implements IGitblit { */ @Override public RepositoryModel fork(RepositoryModel repository, UserModel user) throws GitBlitException { - String cloneName = MessageFormat.format("{0}/{1}.git", user.getPersonalPath(), 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}", repositoryManager.getRepositoriesFolder().getAbsolutePath(), repository.name); // clone the repository @@ -214,18 +214,20 @@ public class GitblitManager implements IGitblit { // create a Gitblit repository model for the clone RepositoryModel cloneModel = repository.cloneAs(cloneName); - // owner has REWIND/RW+ permissions - cloneModel.addOwner(user.username); repositoryManager.updateRepositoryModel(cloneName, cloneModel, false); - // add the owner of the source repository to the clone's access list - if (!ArrayUtils.isEmpty(repository.owners)) { - for (String owner : repository.owners) { - UserModel originOwner = userManager.getUserModel(owner); - if (originOwner != null && !originOwner.canClone(cloneModel)) { + // owner has REWIND/RW+ permissions + user.own(cloneModel); + reviseUser(user.username, user); + + // add the owners of the source repository to the clone's access list + for (Owner owner : getOwners(repository)) { + if (owner instanceof UserModel) { + UserModel userOwner = (UserModel) owner; + if (!userOwner.canClone(cloneModel)) { // origin owner can't yet clone fork, grant explicit clone access - originOwner.setRepositoryPermission(cloneName, AccessPermission.CLONE); - reviseUser(originOwner.username, originOwner); + userOwner.setRepositoryPermission(cloneName, AccessPermission.CLONE); + reviseUser(userOwner.username, userOwner); } } } @@ -325,22 +327,6 @@ public class GitblitManager implements IGitblit { user.username)); } - // rename repositories and owner fields for all repositories - for (RepositoryModel model : repositoryManager.getRepositoryModels(user)) { - if (model.isUsersPersonalRepository(username)) { - // personal repository - model.addOwner(user.username); - String oldRepositoryName = model.name; - model.name = user.getPersonalPath() + model.name.substring(model.projectPath.length()); - model.projectPath = user.getPersonalPath(); - repositoryManager.updateRepositoryModel(oldRepositoryName, model, false); - } else if (model.isOwner(username)) { - // common/shared repo - model.addOwner(user.username); - repositoryManager.updateRepositoryModel(model.name, model, false); - } - } - // rename the user's ssh public keystore getPublicKeyManager().renameUser(username, user.username); } @@ -880,6 +866,16 @@ public class GitblitManager implements IGitblit { return userManager.deleteTeam(teamname); } + @Override + public List getOwners(RepositoryModel repository) { + return userManager.getOwners(repository); + } + + @Override + public boolean setOwners(RepositoryModel repository, List owners) { + return userManager.setOwners(repository, owners); + } + /* * REPOSITORY MANAGER */ diff --git a/src/main/java/com/gitblit/manager/IUserManager.java b/src/main/java/com/gitblit/manager/IUserManager.java index b7ea9c46..8f969007 100644 --- a/src/main/java/com/gitblit/manager/IUserManager.java +++ b/src/main/java/com/gitblit/manager/IUserManager.java @@ -15,7 +15,11 @@ */ package com.gitblit.manager; +import java.util.List; + import com.gitblit.IUserService; +import com.gitblit.models.Owner; +import com.gitblit.models.RepositoryModel; public interface IUserManager extends IManager, IUserService { @@ -28,4 +32,32 @@ public interface IUserManager extends IManager, IUserService { */ boolean isInternalAccount(String username); + /** + * Returns the list of repository owners. + * + * @param repository + * @return a list of owners + * @since 1.6.0 + */ + List getOwners(RepositoryModel repository); + + /** + * Sets the repository owners. + * + * @param repository + * @param a list of owners + * @return true if successful + * @since 1.6.0 + */ + boolean setOwners(RepositoryModel repository, List owners); + +// /** +// * Returns the list of project owners. +// * +// * @param project +// * @return a list of owners +// * @since 1.6.0 +// */ +// List getOwners(ProjectModel project); +// } \ No newline at end of file diff --git a/src/main/java/com/gitblit/manager/ProjectManager.java b/src/main/java/com/gitblit/manager/ProjectManager.java index b30f4f17..0eb0b110 100644 --- a/src/main/java/com/gitblit/manager/ProjectManager.java +++ b/src/main/java/com/gitblit/manager/ProjectManager.java @@ -298,14 +298,14 @@ public class ProjectManager implements IProjectManager { // exclude personal repositories continue; } - if (!projects.containsKey(repository.projectPath)) { - ProjectModel project = getProjectModel(repository.projectPath); + if (!projects.containsKey(repository.getProject())) { + ProjectModel project = getProjectModel(repository.getProject()); if (project == null) { logger.warn(MessageFormat.format("excluding project \"{0}\" from project list because it is empty!", - repository.projectPath)); + repository.getProject())); continue; } - projects.put(repository.projectPath, project); + projects.put(repository.getProject(), project); // clear the repo list in the project because that is the system // list, not the user-accessible list and start building the // user-accessible list @@ -315,7 +315,7 @@ public class ProjectManager implements IProjectManager { } else { // update the user-accessible list // this is used for repository count - ProjectModel project = projects.get(repository.projectPath); + ProjectModel project = projects.get(repository.getProject()); project.repositories.add(repository.name); if (project.lastChange.before(repository.lastChange)) { project.lastChange = repository.lastChange; diff --git a/src/main/java/com/gitblit/manager/RepositoryManager.java b/src/main/java/com/gitblit/manager/RepositoryManager.java index e0721c7c..29a63eaa 100644 --- a/src/main/java/com/gitblit/manager/RepositoryManager.java +++ b/src/main/java/com/gitblit/manager/RepositoryManager.java @@ -277,10 +277,9 @@ public class RepositoryManager implements IRepositoryManager { } } - // TODO reconsider ownership as a user property // manually specify personal repository ownerships for (RepositoryModel rm : repositoryListCache.values()) { - if (rm.isUsersPersonalRepository(user.username) || rm.isOwner(user.username)) { + if (user.isOwner(rm)) { 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 @@ -791,20 +790,23 @@ public class RepositoryManager implements IRepositoryManager { if (r == null) { return null; } - RepositoryModel model = new RepositoryModel(); - model.isBare = r.isBare(); + + String name; File basePath = getRepositoriesFolder(); - if (model.isBare) { - model.name = com.gitblit.utils.FileUtils.getRelativePath(basePath, r.getDirectory()); + if (r.isBare()) { + name = com.gitblit.utils.FileUtils.getRelativePath(basePath, r.getDirectory()); } else { - model.name = com.gitblit.utils.FileUtils.getRelativePath(basePath, r.getDirectory().getParentFile()); + name = com.gitblit.utils.FileUtils.getRelativePath(basePath, r.getDirectory().getParentFile()); } - if (StringUtils.isEmpty(model.name)) { + + if (StringUtils.isEmpty(name)) { // Repository is NOT located relative to the base folder because it // is symlinked. Use the provided repository name. - model.name = repositoryName; + name = repositoryName; } - model.projectPath = StringUtils.getFirstPathElement(repositoryName); + + RepositoryModel model = new RepositoryModel(name); + model.isBare = r.isBare(); StoredConfig config = r.getConfig(); boolean hasOrigin = false; @@ -823,7 +825,7 @@ public class RepositoryManager implements IRepositoryManager { } model.description = getConfig(config, "description", ""); model.originRepository = getConfig(config, "originRepository", null); - model.addOwners(ArrayUtils.fromString(getConfig(config, "owner", ""))); +// model.addOwners(ArrayUtils.fromString(getConfig(config, "owner", ""))); model.acceptNewPatchsets = getConfig(config, "acceptNewPatchsets", true); model.acceptNewTickets = getConfig(config, "acceptNewTickets", true); model.requireApproval = getConfig(config, "requireApproval", settings.getBoolean(Keys.tickets.requireApproval, false)); @@ -968,10 +970,9 @@ public class RepositoryManager implements IRepositoryManager { if (StringUtils.isEmpty(origin)) { return null; } - String userProject = ModelUtils.getPersonalPath(username); + String userPath = ModelUtils.getPersonalPath(username); if (settings.getBoolean(Keys.git.cacheRepositoryList, true)) { String originKey = origin.toLowerCase(); - String userPath = userProject + "/"; // collect all origin nodes in fork network Set roots = new HashSet(); @@ -1009,6 +1010,7 @@ public class RepositoryManager implements IRepositoryManager { } } else { // not caching + String userProject = ModelUtils.getPersonalProject(username); File subfolder = new File(getRepositoriesFolder(), userProject); List repositories = JGitUtils.getRepositoryList(subfolder, settings.getBoolean(Keys.git.onlyAccessBareRepositories, false), @@ -1016,7 +1018,7 @@ public class RepositoryManager implements IRepositoryManager { settings.getInteger(Keys.git.searchRecursionDepth, -1), settings.getStrings(Keys.git.searchExclusions)); for (String repository : repositories) { - RepositoryModel model = getRepositoryModel(userProject + "/" + repository); + RepositoryModel model = getRepositoryModel(userPath + repository); if (model.originRepository != null && model.originRepository.equalsIgnoreCase(origin)) { // user has a fork return model.name; @@ -1450,7 +1452,7 @@ public class RepositoryManager implements IRepositoryManager { StoredConfig config = r.getConfig(); config.setString(Constants.CONFIG_GITBLIT, null, "description", repository.description); config.setString(Constants.CONFIG_GITBLIT, null, "originRepository", repository.originRepository); - config.setString(Constants.CONFIG_GITBLIT, null, "owner", ArrayUtils.toString(repository.owners)); +// config.setString(Constants.CONFIG_GITBLIT, null, "owner", ArrayUtils.toString(repository.owners)); config.setBoolean(Constants.CONFIG_GITBLIT, null, "acceptNewPatchsets", repository.acceptNewPatchsets); config.setBoolean(Constants.CONFIG_GITBLIT, null, "acceptNewTickets", repository.acceptNewTickets); if (settings.getBoolean(Keys.tickets.requireApproval, false) == repository.requireApproval) { diff --git a/src/main/java/com/gitblit/manager/UserManager.java b/src/main/java/com/gitblit/manager/UserManager.java index 2b82ffb6..617c81b4 100644 --- a/src/main/java/com/gitblit/manager/UserManager.java +++ b/src/main/java/com/gitblit/manager/UserManager.java @@ -33,6 +33,8 @@ import com.gitblit.IStoredSettings; import com.gitblit.IUserService; import com.gitblit.Keys; import com.gitblit.extensions.UserTeamLifeCycleListener; +import com.gitblit.models.Owner; +import com.gitblit.models.RepositoryModel; import com.gitblit.models.TeamModel; import com.gitblit.models.UserModel; import com.gitblit.utils.StringUtils; @@ -491,6 +493,60 @@ public class UserManager implements IUserManager { return userService.deleteRepositoryRole(role); } + /** + * Returns the list of owners for the repository. + * + * @param repository + * @return a list of owners + */ + @Override + public List getOwners(RepositoryModel repository) { + List list = new ArrayList<>(); + for (UserModel user : getAllUsers()) { + if (user.isOwner(repository)) { + list.add(user); + } + } + return list; + } + + /** + * Set the repository owners. + * + * @param repository + * @param a list of owners + * @return true if successful + */ + @Override + public boolean setOwners(RepositoryModel repository, List owners) { + List oldOwners = getOwners(repository); + List users = new ArrayList<>(); + + // identify new owners and filter-out continued owners + for (Owner owner : owners) { + if (!oldOwners.remove(owner)) { + // new owner + owner.own(repository); + if (owner instanceof UserModel) { + users.add((UserModel) owner); + } + } + } + + // the remaining oldOwners are now former owners + for (Owner formerOwner : oldOwners) { + formerOwner.disown(repository); + + if (formerOwner instanceof UserModel) { + users.add((UserModel) formerOwner); + } + } + + updateUserModels(users); + + return true; + } + protected void callCreateUserListeners(UserModel user) { if (pluginManager == null || user == null) { return; -- cgit v1.2.3