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 --- src/main/java/com/gitblit/models/Owner.java | 90 ++++++++++++++++++++++ .../java/com/gitblit/models/RepositoryModel.java | 80 ++++++++----------- src/main/java/com/gitblit/models/UserModel.java | 68 ++++++++++++---- 3 files changed, 174 insertions(+), 64 deletions(-) create mode 100644 src/main/java/com/gitblit/models/Owner.java (limited to 'src/main/java/com/gitblit/models') diff --git a/src/main/java/com/gitblit/models/Owner.java b/src/main/java/com/gitblit/models/Owner.java new file mode 100644 index 00000000..c05a596a --- /dev/null +++ b/src/main/java/com/gitblit/models/Owner.java @@ -0,0 +1,90 @@ +/* + * Copyright 2014 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.models; + +import java.io.Serializable; +import java.util.Set; +import java.util.TreeSet; + +import com.gitblit.utils.StringUtils; + +/** + * The owner class defines the ownership method contract for an object. + * + * @author James Moger + * + */ +public abstract class Owner implements Serializable { + + private static final long serialVersionUID = 1L; + + public final Set ownedPaths = new TreeSet(); + + public abstract String getId(); + + public abstract String getDisplayName(); + + public abstract String getPersonalPath(); + + public boolean isOwner(String path) { + if (StringUtils.isEmpty(path)) { + return false; + } + + String personalPath = getPersonalPath(); + if (personalPath != null && path.startsWith(personalPath)) { + return true; + } + + if (ownedPaths == null) { + return false; + } + + if (ownedPaths.contains(path.toLowerCase())) { + // exact path match + return true; + } + + for (String ownedPath : ownedPaths) { + if (StringUtils.matchesIgnoreCase(path, ownedPath)) { + // regex match + return true; + } + } + + return false; + } + + public void own(String path) { + ownedPaths.add(path.toLowerCase()); + } + + public void disown(String path) { + ownedPaths.remove(path.toLowerCase()); + } + + public boolean isOwner(RepositoryModel repository) { + return isOwner(repository.name); + } + + public void own(RepositoryModel repository) { + own(repository.name); + } + + public void disown(RepositoryModel repository) { + disown(repository.name); + } +} diff --git a/src/main/java/com/gitblit/models/RepositoryModel.java b/src/main/java/com/gitblit/models/RepositoryModel.java index a81c622a..78e9728b 100644 --- a/src/main/java/com/gitblit/models/RepositoryModel.java +++ b/src/main/java/com/gitblit/models/RepositoryModel.java @@ -17,7 +17,6 @@ package com.gitblit.models; import java.io.Serializable; import java.util.ArrayList; -import java.util.Collection; import java.util.Date; import java.util.List; import java.util.Map; @@ -46,7 +45,6 @@ public class RepositoryModel implements Serializable, Comparable owners; public Date lastChange; public String lastChangeAuthor; public boolean hasCommits; @@ -74,7 +72,7 @@ public class RepositoryModel implements Serializable, Comparable postReceiveScripts; public List mailingLists; public Map customFields; - public String projectPath; + private String projectPath; private String displayName; public boolean allowForks; public Set forks; @@ -95,11 +93,17 @@ public class RepositoryModel implements Serializable, Comparable(); this.federationStrategy = FederationStrategy.FEDERATE_THIS; this.projectPath = StringUtils.getFirstPathElement(name); - this.owners = new ArrayList(); this.isBare = true; this.acceptNewTickets = true; this.acceptNewPatchsets = true; - - addOwner(owner); } public List getLocalBranches() { @@ -180,19 +181,31 @@ public class RepositoryModel implements Serializable, Comparable usernames) { - if (!ArrayUtils.isEmpty(usernames)) { - for (String username : usernames) { - addOwner(username); - } - } - } - - public void removeOwners(Collection usernames) { - if (!ArrayUtils.isEmpty(owners)) { - for (String username : usernames) { - removeOwner(username); - } - } - } } diff --git a/src/main/java/com/gitblit/models/UserModel.java b/src/main/java/com/gitblit/models/UserModel.java index e1522748..a70f8524 100644 --- a/src/main/java/com/gitblit/models/UserModel.java +++ b/src/main/java/com/gitblit/models/UserModel.java @@ -46,7 +46,7 @@ import com.gitblit.utils.StringUtils; * @author James Moger * */ -public class UserModel implements Principal, Serializable, Comparable { +public class UserModel extends Owner implements Principal, Serializable, Comparable { private static final long serialVersionUID = 1L; @@ -94,6 +94,11 @@ public class UserModel implements Principal, Serializable, Comparable this.userPreferences = new UserPreferences(this.username); } + @Override + public String getId() { + return username; + } + public boolean isLocalAccount() { return !Constants.EXTERNAL_ACCOUNT.equals(password) || accountType == null @@ -279,7 +284,7 @@ public class UserModel implements Principal, Serializable, Comparable } // repository owner - either specified owner or personal repository - if (repository.isOwner(username) || repository.isUsersPersonalRepository(username)) { + if (isOwner(repository)) { ap.permissionType = PermissionType.OWNER; if (AccessPermission.REWIND.atMost(maxPermission)) { ap.permission = AccessPermission.REWIND; @@ -423,11 +428,11 @@ public class UserModel implements Principal, Serializable, Comparable } public boolean canFork(RepositoryModel repository) { - if (repository.isUsersPersonalRepository(username)) { + if (isMyPersonalRepository(repository.name)) { // can not fork your own repository return false; } - if (canAdmin() || repository.isOwner(username)) { + if (canAdmin() || isOwner(repository)) { return true; } if (!repository.allowForks) { @@ -440,11 +445,13 @@ public class UserModel implements Principal, Serializable, Comparable } public boolean canDelete(RepositoryModel model) { - return canAdmin() || model.isUsersPersonalRepository(username); + return canAdmin() + || isMyPersonalRepository(model.name) + || (!model.isPersonalRepository() && isOwner(model)); } public boolean canEdit(RepositoryModel model) { - return canAdmin() || model.isUsersPersonalRepository(username) || model.isOwner(username); + return canAdmin() || isOwner(model); } public boolean canEdit(TicketModel ticket, RepositoryModel repository) { @@ -544,15 +551,22 @@ public class UserModel implements Principal, Serializable, Comparable return true; } if (canCreate()) { - String projectPath = StringUtils.getFirstPathElement(repository); - if (!StringUtils.isEmpty(projectPath) && projectPath.equalsIgnoreCase(getPersonalPath())) { - // personal repository - return true; - } + String projectPath = StringUtils.getFirstPathElement(repository) + "/"; + return isOwner(projectPath); } return false; } +// /** +// * Returns true if the user is allowed to administer the specified project +// * +// * @param project +// * @return true if the user can administer the project +// */ +// public boolean canAdmin(ProjectModel project) { +// return canAdmin() || isOwner(project); +// } +// /** * Returns true if the user is allowed to administer the specified repository * @@ -560,7 +574,7 @@ public class UserModel implements Principal, Serializable, Comparable * @return true if the user can administer the repository */ public boolean canAdmin(RepositoryModel repo) { - return canAdmin() || repo.isOwner(username) || isMyPersonalRepository(repo.name); + return canAdmin() || isOwner(repo); } public boolean isAuthenticated() { @@ -593,6 +607,7 @@ public class UserModel implements Principal, Serializable, Comparable return username; } + @Override public String getDisplayName() { if (StringUtils.isEmpty(displayName)) { return username; @@ -600,6 +615,7 @@ public class UserModel implements Principal, Serializable, Comparable return displayName; } + @Override public String getPersonalPath() { return ModelUtils.getPersonalPath(username); } @@ -657,7 +673,31 @@ public class UserModel implements Principal, Serializable, Comparable } public boolean isMyPersonalRepository(String repository) { - String projectPath = StringUtils.getFirstPathElement(repository); - return !StringUtils.isEmpty(projectPath) && projectPath.equalsIgnoreCase(getPersonalPath()); + return repository.startsWith(getPersonalPath()); } + + @Override + public boolean isOwner(RepositoryModel repository) { + return isMyPersonalRepository(repository.name) + || isOwner(repository.name); + } +// public boolean isOwner(ProjectModel project) { +// return isOwner(project.name + "/"); +//} +// +// public void own(ProjectModel project) { +// if (StringUtils.isEmpty(project.name)) { +// own("/"); +// } else { +// own(project.name.toLowerCase() + "/"); +// } +// } +// +// public void disown(ProjectModel project) { +// if (StringUtils.isEmpty(project.name)) { +// disown("/"); +// } else { +// disown(project.name.toLowerCase() + "/"); +// } +// } } -- cgit v1.2.3