diff --git a/gitop.core/src/main/java/com/pmease/gitop/core/entitymanager/GroupManager.java b/gitop.core/src/main/java/com/pmease/gitop/core/entitymanager/GroupManager.java index 1c7c07750f..e4fb66bc03 100644 --- a/gitop.core/src/main/java/com/pmease/gitop/core/entitymanager/GroupManager.java +++ b/gitop.core/src/main/java/com/pmease/gitop/core/entitymanager/GroupManager.java @@ -5,11 +5,11 @@ import java.util.Collection; import com.google.inject.ImplementedBy; import com.pmease.commons.persistence.dao.GenericDao; import com.pmease.gitop.core.entitymanager.impl.DefaultGroupManager; -import com.pmease.gitop.core.model.Group; +import com.pmease.gitop.core.model.Team; @ImplementedBy(DefaultGroupManager.class) -public interface GroupManager extends GenericDao { +public interface GroupManager extends GenericDao { - Collection getGroups(Long userId); + Collection getGroups(Long userId); } diff --git a/gitop.core/src/main/java/com/pmease/gitop/core/entitymanager/impl/DefaultGroupManager.java b/gitop.core/src/main/java/com/pmease/gitop/core/entitymanager/impl/DefaultGroupManager.java index 51f4818172..537a034969 100644 --- a/gitop.core/src/main/java/com/pmease/gitop/core/entitymanager/impl/DefaultGroupManager.java +++ b/gitop.core/src/main/java/com/pmease/gitop/core/entitymanager/impl/DefaultGroupManager.java @@ -13,11 +13,11 @@ import com.pmease.commons.persistence.dao.DefaultGenericDao; import com.pmease.commons.persistence.dao.GeneralDao; import com.pmease.gitop.core.entitymanager.GroupManager; import com.pmease.gitop.core.entitymanager.UserManager; -import com.pmease.gitop.core.model.Group; -import com.pmease.gitop.core.model.Membership; +import com.pmease.gitop.core.model.Team; +import com.pmease.gitop.core.model.TeamMembership; @Singleton -public class DefaultGroupManager extends DefaultGenericDao implements GroupManager { +public class DefaultGroupManager extends DefaultGenericDao implements GroupManager { private final UserManager userManager; @@ -28,9 +28,9 @@ public class DefaultGroupManager extends DefaultGenericDao implements Gro @Transactional @Override - public Collection getGroups(Long userId) { - Collection groups = new ArrayList(); - for (Membership membership: userManager.load(userId).getMemberships()) + public Collection getGroups(Long userId) { + Collection groups = new ArrayList(); + for (TeamMembership membership: userManager.load(userId).getMemberships()) groups.add(membership.getGroup()); return groups; diff --git a/gitop.core/src/main/java/com/pmease/gitop/core/model/Group.java b/gitop.core/src/main/java/com/pmease/gitop/core/model/Group.java deleted file mode 100644 index 4374fd466b..0000000000 --- a/gitop.core/src/main/java/com/pmease/gitop/core/model/Group.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.pmease.gitop.core.model; - -import java.util.Collection; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.OneToMany; - -import org.apache.shiro.authz.Permission; - -import com.pmease.commons.persistence.AbstractEntity; - -@Entity -@org.hibernate.annotations.Cache( - usage=org.hibernate.annotations.CacheConcurrencyStrategy.READ_WRITE) -@SuppressWarnings("serial") -public class Group extends AbstractEntity implements Permission { - - @Column(nullable=false, unique=true) - private String name; - - private String description; - - @OneToMany(mappedBy="group") - private Collection memberships; - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - @Override - public boolean implies(Permission permission) { - return false; - } - -} diff --git a/gitop.core/src/main/java/com/pmease/gitop/core/model/InvolvedBranch.java b/gitop.core/src/main/java/com/pmease/gitop/core/model/InvolvedBranch.java index 5209822273..915b9e98dd 100644 --- a/gitop.core/src/main/java/com/pmease/gitop/core/model/InvolvedBranch.java +++ b/gitop.core/src/main/java/com/pmease/gitop/core/model/InvolvedBranch.java @@ -21,14 +21,22 @@ import com.pmease.commons.persistence.AbstractEntity; @SuppressWarnings("serial") public class InvolvedBranch extends AbstractEntity { - @Column(nullable=false) - private String name; - @ManyToOne(fetch=FetchType.EAGER) @org.hibernate.annotations.Fetch(FetchMode.SELECT) @JoinColumn(nullable=false) private Repository repository; + @Column(nullable=false) + private String name; + + public Repository getRepository() { + return repository; + } + + public void setRepository(Repository repository) { + this.repository = repository; + } + public String getName() { return name; } @@ -37,12 +45,4 @@ public class InvolvedBranch extends AbstractEntity { this.name = name; } - public Repository getRepository() { - return repository; - } - - public void setRepository(Repository repository) { - this.repository = repository; - } - } diff --git a/gitop.core/src/main/java/com/pmease/gitop/core/model/Repository.java b/gitop.core/src/main/java/com/pmease/gitop/core/model/Repository.java index 14751fadd2..377cdd1c61 100644 --- a/gitop.core/src/main/java/com/pmease/gitop/core/model/Repository.java +++ b/gitop.core/src/main/java/com/pmease/gitop/core/model/Repository.java @@ -12,29 +12,41 @@ import org.hibernate.annotations.FetchMode; import com.pmease.commons.persistence.AbstractEntity; import com.pmease.gitop.core.model.gatekeeper.GateKeeper; +import com.pmease.gitop.core.model.permission.object.ProtectedObject; +import com.pmease.gitop.core.model.permission.object.RepositoryBelonging; +import com.pmease.gitop.core.model.permission.object.UserBelonging; @Entity @org.hibernate.annotations.Cache( usage=org.hibernate.annotations.CacheConcurrencyStrategy.READ_WRITE) @Table(uniqueConstraints={ - @UniqueConstraint(columnNames={"user", "name"}) + @UniqueConstraint(columnNames={"owner", "name"}) }) @SuppressWarnings("serial") -public class Repository extends AbstractEntity { +public class Repository extends AbstractEntity implements UserBelonging { + @ManyToOne(fetch=FetchType.EAGER) + @org.hibernate.annotations.Fetch(FetchMode.SELECT) + @JoinColumn(nullable=false) + private User owner; + @Column(nullable=false) private String name; private String description; - @ManyToOne(fetch=FetchType.EAGER) - @org.hibernate.annotations.Fetch(FetchMode.SELECT) - @JoinColumn(nullable=false) - private User user; - @Column(nullable=true) private GateKeeper gateKeeper; + @Override + public User getOwner() { + return owner; + } + + public void setOwner(User owner) { + this.owner = owner; + } + public String getName() { return name; } @@ -51,14 +63,6 @@ public class Repository extends AbstractEntity { this.description = description; } - public User getUser() { - return user; - } - - public void setUser(User user) { - this.user = user; - } - public GateKeeper getGateKeeper() { return gateKeeper; } @@ -67,4 +71,17 @@ public class Repository extends AbstractEntity { this.gateKeeper = gateKeeper; } + @Override + public boolean has(ProtectedObject object) { + if (object instanceof Repository) { + Repository repository = (Repository) object; + return repository.getId().equals(getId()); + } else if (object instanceof RepositoryBelonging) { + RepositoryBelonging repositoryBelonging = (RepositoryBelonging) object; + return repositoryBelonging.getOwner().getId().equals(getId()); + } else { + return false; + } + } + } diff --git a/gitop.core/src/main/java/com/pmease/gitop/core/model/UserLevelPermissionByGroup.java b/gitop.core/src/main/java/com/pmease/gitop/core/model/RepositoryAuthorization.java similarity index 51% rename from gitop.core/src/main/java/com/pmease/gitop/core/model/UserLevelPermissionByGroup.java rename to gitop.core/src/main/java/com/pmease/gitop/core/model/RepositoryAuthorization.java index 01003c60b8..44a59df829 100644 --- a/gitop.core/src/main/java/com/pmease/gitop/core/model/UserLevelPermissionByGroup.java +++ b/gitop.core/src/main/java/com/pmease/gitop/core/model/RepositoryAuthorization.java @@ -1,5 +1,6 @@ package com.pmease.gitop.core.model; +import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.JoinColumn; @@ -10,40 +11,52 @@ import javax.persistence.UniqueConstraint; import org.hibernate.annotations.FetchMode; import com.pmease.commons.persistence.AbstractEntity; +import com.pmease.gitop.core.model.permission.RepositoryOperation; @SuppressWarnings("serial") @Entity @Table(uniqueConstraints={ - @UniqueConstraint(columnNames={"who", "what"}) + @UniqueConstraint(columnNames={"subject", "object"}) }) @org.hibernate.annotations.Cache( usage=org.hibernate.annotations.CacheConcurrencyStrategy.READ_WRITE) -public class UserLevelPermissionByGroup extends AbstractEntity { +public class RepositoryAuthorization extends AbstractEntity { @ManyToOne(fetch=FetchType.EAGER) @org.hibernate.annotations.Fetch(FetchMode.SELECT) @JoinColumn(nullable=false) - private Group who; + private Team subject; @ManyToOne(fetch=FetchType.EAGER) @org.hibernate.annotations.Fetch(FetchMode.SELECT) @JoinColumn(nullable=false) - private User what; + private Repository object; - public Group getWho() { - return who; + @Column(nullable=false) + private RepositoryOperation operation; + + public Team getSubject() { + return subject; } - public void setWho(Group who) { - this.who = who; + public void setSubject(Team subject) { + this.subject = subject; } - public User getWhat() { - return what; + public Repository getObject() { + return object; } - public void setWhat(User what) { - this.what = what; + public void setObject(Repository object) { + this.object = object; + } + + public RepositoryOperation getOperation() { + return operation; + } + + public void setOperation(RepositoryOperation operation) { + this.operation = operation; } } diff --git a/gitop.core/src/main/java/com/pmease/gitop/core/model/RepositoryLevelPermissionByGroup.java b/gitop.core/src/main/java/com/pmease/gitop/core/model/RepositoryLevelPermissionByGroup.java deleted file mode 100644 index f4fb1c9343..0000000000 --- a/gitop.core/src/main/java/com/pmease/gitop/core/model/RepositoryLevelPermissionByGroup.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.pmease.gitop.core.model; - -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.Table; -import javax.persistence.UniqueConstraint; - -import org.hibernate.annotations.FetchMode; - -import com.pmease.commons.persistence.AbstractEntity; - -@SuppressWarnings("serial") -@Entity -@Table(uniqueConstraints={ - @UniqueConstraint(columnNames={"who", "what"}) -}) -@org.hibernate.annotations.Cache( - usage=org.hibernate.annotations.CacheConcurrencyStrategy.READ_WRITE) -public class RepositoryLevelPermissionByGroup extends AbstractEntity { - - @ManyToOne(fetch=FetchType.EAGER) - @org.hibernate.annotations.Fetch(FetchMode.SELECT) - @JoinColumn(nullable=false) - private Group who; - - @ManyToOne(fetch=FetchType.EAGER) - @org.hibernate.annotations.Fetch(FetchMode.SELECT) - @JoinColumn(nullable=false) - private Repository what; - - public Group getWho() { - return who; - } - - public void setWho(Group who) { - this.who = who; - } - - public Repository getWhat() { - return what; - } - - public void setWhat(Repository what) { - this.what = what; - } - -} diff --git a/gitop.core/src/main/java/com/pmease/gitop/core/model/RepositoryLevelPermissionByUser.java b/gitop.core/src/main/java/com/pmease/gitop/core/model/RepositoryLevelPermissionByUser.java deleted file mode 100644 index 20d3bc9a57..0000000000 --- a/gitop.core/src/main/java/com/pmease/gitop/core/model/RepositoryLevelPermissionByUser.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.pmease.gitop.core.model; - -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.Table; -import javax.persistence.UniqueConstraint; - -import org.hibernate.annotations.FetchMode; - -import com.pmease.commons.persistence.AbstractEntity; - -@SuppressWarnings("serial") -@Entity -@Table(uniqueConstraints={ - @UniqueConstraint(columnNames={"who", "what"}) -}) -@org.hibernate.annotations.Cache( - usage=org.hibernate.annotations.CacheConcurrencyStrategy.READ_WRITE) -public class RepositoryLevelPermissionByUser extends AbstractEntity { - - @ManyToOne(fetch=FetchType.EAGER) - @org.hibernate.annotations.Fetch(FetchMode.SELECT) - @JoinColumn(nullable=false) - private User who; - - @ManyToOne(fetch=FetchType.EAGER) - @org.hibernate.annotations.Fetch(FetchMode.SELECT) - @JoinColumn(nullable=false) - private Repository what; - - public User getWho() { - return who; - } - - public void setWho(User who) { - this.who = who; - } - - public Repository getWhat() { - return what; - } - - public void setWhat(Repository what) { - this.what = what; - } - -} diff --git a/gitop.core/src/main/java/com/pmease/gitop/core/model/Role.java b/gitop.core/src/main/java/com/pmease/gitop/core/model/Role.java new file mode 100644 index 0000000000..f9b7eff604 --- /dev/null +++ b/gitop.core/src/main/java/com/pmease/gitop/core/model/Role.java @@ -0,0 +1,81 @@ +package com.pmease.gitop.core.model; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.OneToMany; + +import org.apache.shiro.authz.Permission; + +import com.pmease.commons.persistence.AbstractEntity; +import com.pmease.gitop.core.model.permission.ObjectPermission; +import com.pmease.gitop.core.model.permission.object.SystemObject; +import com.pmease.gitop.core.model.permission.operation.PrivilegedOperation; + +@Entity +@org.hibernate.annotations.Cache( + usage=org.hibernate.annotations.CacheConcurrencyStrategy.READ_WRITE) +@SuppressWarnings("serial") +public class Role extends AbstractEntity implements Permission { + + @Column(nullable=false, unique=true) + private String name; + + private String description; + + @Column(nullable=false) + private List operations = new ArrayList(); + + @OneToMany(mappedBy="role") + private Collection memberships; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public Collection getMemberships() { + return memberships; + } + + public void setMemberships(Collection memberships) { + this.memberships = memberships; + } + + public List getOperations() { + return operations; + } + + public void setOperations(List operations) { + this.operations = operations; + } + + @Override + public boolean implies(Permission permission) { + if (permission instanceof ObjectPermission) { + ObjectPermission objectPermission = (ObjectPermission) permission; + if (new SystemObject().has(objectPermission.getObject())) { + for (PrivilegedOperation each: getOperations()) { + if (each.can(objectPermission.getOperation())) + return true; + } + } + } + return false; + } + +} diff --git a/gitop.core/src/main/java/com/pmease/gitop/core/model/UserLevelPermissionByUser.java b/gitop.core/src/main/java/com/pmease/gitop/core/model/RoleMembership.java similarity index 70% rename from gitop.core/src/main/java/com/pmease/gitop/core/model/UserLevelPermissionByUser.java rename to gitop.core/src/main/java/com/pmease/gitop/core/model/RoleMembership.java index 2dc152ed8d..a92f67ef8d 100644 --- a/gitop.core/src/main/java/com/pmease/gitop/core/model/UserLevelPermissionByUser.java +++ b/gitop.core/src/main/java/com/pmease/gitop/core/model/RoleMembership.java @@ -14,36 +14,36 @@ import com.pmease.commons.persistence.AbstractEntity; @SuppressWarnings("serial") @Entity @Table(uniqueConstraints={ - @UniqueConstraint(columnNames={"who", "what"}) + @UniqueConstraint(columnNames={"user", "role"}) }) @org.hibernate.annotations.Cache( usage=org.hibernate.annotations.CacheConcurrencyStrategy.READ_WRITE) -public class UserLevelPermissionByUser extends AbstractEntity { +public class RoleMembership extends AbstractEntity { @ManyToOne(fetch=FetchType.EAGER) @org.hibernate.annotations.Fetch(FetchMode.SELECT) @JoinColumn(nullable=false) - private User who; - - @ManyToOne(fetch=FetchType.EAGER) - @org.hibernate.annotations.Fetch(FetchMode.SELECT) - @JoinColumn(nullable=false) - private User what; + private User user; - public User getWhat() { - return what; + @ManyToOne(fetch=FetchType.EAGER) + @org.hibernate.annotations.Fetch(FetchMode.SELECT) + @JoinColumn(nullable=false) + private Role role; + + public User getUser() { + return user; } - public void setWhat(User what) { - this.what = what; + public void setUser(User user) { + this.user = user; } - public User getWho() { - return who; + public Role getRole() { + return role; } - public void setWho(User who) { - this.who = who; + public void setRole(Role role) { + this.role = role; } } diff --git a/gitop.core/src/main/java/com/pmease/gitop/core/model/Team.java b/gitop.core/src/main/java/com/pmease/gitop/core/model/Team.java new file mode 100644 index 0000000000..e2f45462c7 --- /dev/null +++ b/gitop.core/src/main/java/com/pmease/gitop/core/model/Team.java @@ -0,0 +1,110 @@ +package com.pmease.gitop.core.model; + +import java.util.Collection; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.UniqueConstraint; + +import org.apache.shiro.authz.Permission; + +import com.pmease.commons.persistence.AbstractEntity; +import com.pmease.gitop.core.model.permission.ObjectPermission; +import com.pmease.gitop.core.model.permission.operation.PrivilegedOperation; + +@Entity +@org.hibernate.annotations.Cache( + usage=org.hibernate.annotations.CacheConcurrencyStrategy.READ_WRITE) +@Table(uniqueConstraints={ + @UniqueConstraint(columnNames={"owner", "name"}) +}) +@SuppressWarnings("serial") +public class Team extends AbstractEntity implements Permission { + + private User owner; + + @Column(nullable=false, unique=true) + private String name; + + private String description; + + private PrivilegedOperation operation; + + @OneToMany(mappedBy="team") + private Collection memberships; + + @OneToMany(mappedBy="subject") + private Collection repositoryAuthorizations; + + public User getOwner() { + return owner; + } + + public void setOwner(User owner) { + this.owner = owner; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public PrivilegedOperation getOperation() { + return operation; + } + + public void setOperation(PrivilegedOperation operation) { + this.operation = operation; + } + + public Collection getMemberships() { + return memberships; + } + + public void setMemberships(Collection memberships) { + this.memberships = memberships; + } + + public Collection getRepositoryAuthorizations() { + return repositoryAuthorizations; + } + + public void setRepositoryAuthorizations( + Collection repositoryAuthorizations) { + this.repositoryAuthorizations = repositoryAuthorizations; + } + + @Override + public boolean implies(Permission permission) { + if (permission instanceof ObjectPermission) { + ObjectPermission objectPermission = (ObjectPermission) permission; + + for (RepositoryAuthorization each: getRepositoryAuthorizations()) { + PrivilegedOperation operation = each.getOperation().operationOf( + objectPermission.getObject(), each.getObject()); + + if (operation != null) + return operation.can(objectPermission.getOperation()); + } + + if (getOwner().has(objectPermission.getObject())) + return getOperation().can(objectPermission.getOperation()); + } + + return false; + } + +} diff --git a/gitop.core/src/main/java/com/pmease/gitop/core/model/Membership.java b/gitop.core/src/main/java/com/pmease/gitop/core/model/TeamMembership.java similarity index 87% rename from gitop.core/src/main/java/com/pmease/gitop/core/model/Membership.java rename to gitop.core/src/main/java/com/pmease/gitop/core/model/TeamMembership.java index 602e46ba2d..422cf8f6b1 100644 --- a/gitop.core/src/main/java/com/pmease/gitop/core/model/Membership.java +++ b/gitop.core/src/main/java/com/pmease/gitop/core/model/TeamMembership.java @@ -18,7 +18,7 @@ import com.pmease.commons.persistence.AbstractEntity; }) @org.hibernate.annotations.Cache( usage=org.hibernate.annotations.CacheConcurrencyStrategy.READ_WRITE) -public class Membership extends AbstractEntity { +public class TeamMembership extends AbstractEntity { @ManyToOne(fetch=FetchType.EAGER) @org.hibernate.annotations.Fetch(FetchMode.SELECT) @@ -28,7 +28,7 @@ public class Membership extends AbstractEntity { @ManyToOne(fetch=FetchType.EAGER) @org.hibernate.annotations.Fetch(FetchMode.SELECT) @JoinColumn(nullable=false) - private Group group; + private Team group; public User getUser() { return user; @@ -38,11 +38,11 @@ public class Membership extends AbstractEntity { this.user = user; } - public Group getGroup() { + public Team getGroup() { return group; } - public void setGroup(Group group) { + public void setGroup(Team group) { this.group = group; } diff --git a/gitop.core/src/main/java/com/pmease/gitop/core/model/User.java b/gitop.core/src/main/java/com/pmease/gitop/core/model/User.java index be871a191c..f270503ee0 100644 --- a/gitop.core/src/main/java/com/pmease/gitop/core/model/User.java +++ b/gitop.core/src/main/java/com/pmease/gitop/core/model/User.java @@ -5,7 +5,11 @@ import java.util.Collection; import javax.persistence.Entity; import javax.persistence.OneToMany; +import org.apache.shiro.authz.Permission; + import com.pmease.commons.security.AbstractUser; +import com.pmease.gitop.core.model.permission.object.ProtectedObject; +import com.pmease.gitop.core.model.permission.object.UserBelonging; /** * This class represents either a project or an user in the system. @@ -21,28 +25,73 @@ import com.pmease.commons.security.AbstractUser; @Entity @org.hibernate.annotations.Cache( usage=org.hibernate.annotations.CacheConcurrencyStrategy.READ_WRITE) -public class User extends AbstractUser { +public class User extends AbstractUser implements ProtectedObject, Permission { @OneToMany(mappedBy="user") - private Collection memberships; + private Collection memberships; @OneToMany(mappedBy="user") - private Collection mergeRequests; + private Collection mergeRequests; + + @OneToMany(mappedBy="owner") + private Collection repositories; - public Collection getMemberships() { + @OneToMany(mappedBy="owner") + private Collection teams; + + public Collection getMemberships() { return memberships; } - public void setMemberships(Collection memberships) { + public void setMemberships(Collection memberships) { this.memberships = memberships; } - public Collection getMergeRequests() { + public Collection getRepositories() { + return repositories; + } + + public void setRepositories(Collection repositories) { + this.repositories = repositories; + } + + public Collection getTeams() { + return teams; + } + + public void setTeams(Collection teams) { + this.teams = teams; + } + + public Collection getMergeRequests() { return mergeRequests; } - public void setMergeRequests(Collection mergeRequests) { + public void setMergeRequests(Collection mergeRequests) { this.mergeRequests = mergeRequests; } + @Override + public boolean has(ProtectedObject object) { + if (object instanceof User) { + User user = (User) object; + return user.getId().equals(getId()); + } else if (object instanceof UserBelonging) { + UserBelonging userBelonging = (UserBelonging) object; + return userBelonging.getOwner().getId().equals(getId()); + } else { + return false; + } + } + + @Override + public boolean implies(Permission permission) { + for (TeamMembership each: getMemberships()) { + if (each.getGroup().implies(permission)) + return true; + } + + return false; + } + } diff --git a/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/BranchPermission.java b/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/BranchPermission.java new file mode 100644 index 0000000000..b6e959c91c --- /dev/null +++ b/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/BranchPermission.java @@ -0,0 +1,27 @@ +package com.pmease.gitop.core.model.permission; + +import com.pmease.gitop.core.model.permission.operation.PrivilegedOperation; + +public class BranchPermission { + + private String branchNames; + + private PrivilegedOperation branchOperation; + + public String getBranchNames() { + return branchNames; + } + + public void setBranchNames(String branchNames) { + this.branchNames = branchNames; + } + + public PrivilegedOperation getBranchOperation() { + return branchOperation; + } + + public void setBranchOperation(PrivilegedOperation branchOperation) { + this.branchOperation = branchOperation; + } + +} diff --git a/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/ObjectPermission.java b/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/ObjectPermission.java new file mode 100644 index 0000000000..84061ac8f5 --- /dev/null +++ b/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/ObjectPermission.java @@ -0,0 +1,52 @@ +package com.pmease.gitop.core.model.permission; + +import org.apache.shiro.authz.Permission; + +import com.pmease.gitop.core.model.permission.object.ProtectedObject; +import com.pmease.gitop.core.model.permission.operation.PrivilegedOperation; + +/** + * This class represents permissions to operate an account and its belongings. + * + * @author robin + * + */ +public class ObjectPermission implements Permission { + + private ProtectedObject object; + + private PrivilegedOperation operation; + + public ObjectPermission(ProtectedObject object, PrivilegedOperation operation) { + this.object = object; + this.operation = operation; + } + + public ProtectedObject getObject() { + return object; + } + + public PrivilegedOperation getOperation() { + return operation; + } + + public void setOperation(PrivilegedOperation operation) { + this.operation = operation; + } + + public void setObject(ProtectedObject object) { + this.object = object; + } + + @Override + public boolean implies(Permission permission) { + if (permission instanceof ObjectPermission) { + ObjectPermission objectPermission = (ObjectPermission) permission; + return getObject().has(objectPermission.getObject()) + && getOperation().can(objectPermission.getOperation()); + } else { + return false; + } + } + +} diff --git a/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/RepositoryOperation.java b/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/RepositoryOperation.java new file mode 100644 index 0000000000..c90e46b315 --- /dev/null +++ b/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/RepositoryOperation.java @@ -0,0 +1,45 @@ +package com.pmease.gitop.core.model.permission; + +import java.util.ArrayList; +import java.util.List; + +import com.pmease.gitop.core.model.Repository; +import com.pmease.gitop.core.model.permission.object.ProtectedBranches; +import com.pmease.gitop.core.model.permission.object.ProtectedObject; +import com.pmease.gitop.core.model.permission.operation.PrivilegedOperation; + +public class RepositoryOperation { + + private PrivilegedOperation repositoryLevel; + + private List branchLevel = new ArrayList(); + + public PrivilegedOperation getRepositoryWide() { + return repositoryLevel; + } + + public void setRepositoryLevel(PrivilegedOperation repositoryLevel) { + this.repositoryLevel = repositoryLevel; + } + + public List getBranchLevel() { + return branchLevel; + } + + public void setBranchLevel(List branchLevel) { + this.branchLevel = branchLevel; + } + + public PrivilegedOperation operationOf(ProtectedObject object, Repository repository) { + for (BranchPermission each: getBranchLevel()) { + if (new ProtectedBranches(repository, each.getBranchNames()).has(object)) + return each.getBranchOperation(); + } + + if (repository.has(object)) + return getRepositoryWide(); + else + return null; + } + +} diff --git a/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/object/ProtectedBranches.java b/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/object/ProtectedBranches.java new file mode 100644 index 0000000000..a9db8dfecb --- /dev/null +++ b/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/object/ProtectedBranches.java @@ -0,0 +1,36 @@ +package com.pmease.gitop.core.model.permission.object; + +import com.pmease.commons.util.pattern.WildcardUtils; +import com.pmease.gitop.core.model.Repository; + +public class ProtectedBranches implements RepositoryBelonging { + + private final Repository repository; + + private final String branchNames; + + public ProtectedBranches(Repository repository, String branchNames) { + this.repository = repository; + this.branchNames = branchNames; + } + + public String getBranchNames() { + return branchNames; + } + + @Override + public boolean has(ProtectedObject object) { + if (object instanceof ProtectedBranches) { + ProtectedBranches branches = (ProtectedBranches) object; + return WildcardUtils.matchPath(getBranchNames(), branches.getBranchNames()); + } else { + return false; + } + } + + @Override + public Repository getOwner() { + return repository; + } + +} diff --git a/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/object/ProtectedObject.java b/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/object/ProtectedObject.java new file mode 100644 index 0000000000..aa7b77bab2 --- /dev/null +++ b/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/object/ProtectedObject.java @@ -0,0 +1,5 @@ +package com.pmease.gitop.core.model.permission.object; + +public interface ProtectedObject { + boolean has(ProtectedObject object); +} diff --git a/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/object/RepositoryBelonging.java b/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/object/RepositoryBelonging.java new file mode 100644 index 0000000000..77d8fe4bfb --- /dev/null +++ b/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/object/RepositoryBelonging.java @@ -0,0 +1,7 @@ +package com.pmease.gitop.core.model.permission.object; + +import com.pmease.gitop.core.model.Repository; + +public interface RepositoryBelonging extends ProtectedObject { + Repository getOwner(); +} diff --git a/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/object/SystemObject.java b/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/object/SystemObject.java new file mode 100644 index 0000000000..7c85bfe9f0 --- /dev/null +++ b/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/object/SystemObject.java @@ -0,0 +1,10 @@ +package com.pmease.gitop.core.model.permission.object; + +public class SystemObject implements ProtectedObject { + + @Override + public boolean has(ProtectedObject object) { + return true; + } + +} diff --git a/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/object/UserBelonging.java b/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/object/UserBelonging.java new file mode 100644 index 0000000000..0fe9bdfff5 --- /dev/null +++ b/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/object/UserBelonging.java @@ -0,0 +1,7 @@ +package com.pmease.gitop.core.model.permission.object; + +import com.pmease.gitop.core.model.User; + +public interface UserBelonging extends ProtectedObject { + User getOwner(); +} diff --git a/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/operation/Administration.java b/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/operation/Administration.java new file mode 100644 index 0000000000..3472c2bbd6 --- /dev/null +++ b/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/operation/Administration.java @@ -0,0 +1,10 @@ +package com.pmease.gitop.core.model.permission.operation; + +public class Administration implements PrivilegedOperation { + + @Override + public boolean can(PrivilegedOperation operation) { + return true; + } + +} diff --git a/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/operation/CreateAssessment.java b/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/operation/CreateAssessment.java new file mode 100644 index 0000000000..078ae7b0f3 --- /dev/null +++ b/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/operation/CreateAssessment.java @@ -0,0 +1,10 @@ +package com.pmease.gitop.core.model.permission.operation; + +public class CreateAssessment implements PrivilegedOperation { + + @Override + public boolean can(PrivilegedOperation operation) { + return operation instanceof CreateAssessment; + } + +} diff --git a/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/operation/CreateComment.java b/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/operation/CreateComment.java new file mode 100644 index 0000000000..8218e98de3 --- /dev/null +++ b/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/operation/CreateComment.java @@ -0,0 +1,10 @@ +package com.pmease.gitop.core.model.permission.operation; + +public class CreateComment implements PrivilegedOperation { + + @Override + public boolean can(PrivilegedOperation operation) { + return operation instanceof CreateComment; + } + +} diff --git a/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/operation/CreateMergeRequest.java b/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/operation/CreateMergeRequest.java new file mode 100644 index 0000000000..f2910658a5 --- /dev/null +++ b/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/operation/CreateMergeRequest.java @@ -0,0 +1,10 @@ +package com.pmease.gitop.core.model.permission.operation; + +public class CreateMergeRequest implements PrivilegedOperation { + + @Override + public boolean can(PrivilegedOperation operation) { + return operation instanceof CreateMergeRequest; + } + +} diff --git a/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/operation/CreateRepository.java b/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/operation/CreateRepository.java new file mode 100644 index 0000000000..44e039609d --- /dev/null +++ b/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/operation/CreateRepository.java @@ -0,0 +1,10 @@ +package com.pmease.gitop.core.model.permission.operation; + +public class CreateRepository implements PrivilegedOperation { + + @Override + public boolean can(PrivilegedOperation operation) { + return operation instanceof CreateRepository; + } + +} diff --git a/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/PrivilegedOperation.java b/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/operation/PrivilegedOperation.java similarity index 60% rename from gitop.core/src/main/java/com/pmease/gitop/core/model/permission/PrivilegedOperation.java rename to gitop.core/src/main/java/com/pmease/gitop/core/model/permission/operation/PrivilegedOperation.java index 6b2781209e..273b047e0e 100644 --- a/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/PrivilegedOperation.java +++ b/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/operation/PrivilegedOperation.java @@ -1,4 +1,4 @@ -package com.pmease.gitop.core.model.permission; +package com.pmease.gitop.core.model.permission.operation; public interface PrivilegedOperation { boolean can(PrivilegedOperation operation); diff --git a/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/operation/Read.java b/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/operation/Read.java new file mode 100644 index 0000000000..e404918ca1 --- /dev/null +++ b/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/operation/Read.java @@ -0,0 +1,10 @@ +package com.pmease.gitop.core.model.permission.operation; + +public class Read implements PrivilegedOperation { + + @Override + public boolean can(PrivilegedOperation operation) { + return operation instanceof Read; + } + +} diff --git a/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/operation/SystemOperation.java b/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/operation/SystemOperation.java new file mode 100644 index 0000000000..5fe33d6a4f --- /dev/null +++ b/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/operation/SystemOperation.java @@ -0,0 +1,60 @@ +package com.pmease.gitop.core.model.permission.operation; + +public enum SystemOperation implements PrivilegedOperation { + ADMINISTRATION { + + @Override + public boolean can(PrivilegedOperation operation) { + return true; + } + + }, + CREATE_ASSESSMENT { + + @Override + public boolean can(PrivilegedOperation operation) { + return operation == CREATE_ASSESSMENT; + } + + }, + CREATE_COMMENT { + + @Override + public boolean can(PrivilegedOperation operation) { + return operation == CREATE_COMMENT; + } + + }, + CREATE_MERGE_REQUEST { + + @Override + public boolean can(PrivilegedOperation operation) { + return operation == CREATE_MERGE_REQUEST; + } + + }, + CREATE_REPOSITORY { + + @Override + public boolean can(PrivilegedOperation operation) { + return operation == CREATE_REPOSITORY; + } + + }, + READ_ALL_REPOSITORIES { + + @Override + public boolean can(PrivilegedOperation operation) { + return operation == READ_ALL_REPOSITORIES; + } + + }, + WRITE_ALL_REPOSITORIES { + + @Override + public boolean can(PrivilegedOperation operation) { + return READ_ALL_REPOSITORIES.can(operation); + } + + } +} diff --git a/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/operation/Write.java b/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/operation/Write.java new file mode 100644 index 0000000000..5d8e96a648 --- /dev/null +++ b/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/operation/Write.java @@ -0,0 +1,10 @@ +package com.pmease.gitop.core.model.permission.operation; + +public class Write implements PrivilegedOperation{ + + @Override + public boolean can(PrivilegedOperation operation) { + return operation instanceof Write || new Read().can(operation); + } + +} diff --git a/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/operation/WriteToBranch.java b/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/operation/WriteToBranch.java new file mode 100644 index 0000000000..4ecb075fd9 --- /dev/null +++ b/gitop.core/src/main/java/com/pmease/gitop/core/model/permission/operation/WriteToBranch.java @@ -0,0 +1,27 @@ +package com.pmease.gitop.core.model.permission.operation; + +import com.pmease.commons.util.pattern.WildcardUtils; + +public class WriteToBranch implements PrivilegedOperation { + + private String filePaths = "**"; + + public String getFilePaths() { + return filePaths; + } + + public void setFilePaths(String filePaths) { + this.filePaths = filePaths; + } + + @Override + public boolean can(PrivilegedOperation operation) { + if (operation instanceof WriteToBranch) { + WriteToBranch writeToBranch = (WriteToBranch) operation; + return WildcardUtils.matchPath(getFilePaths(), writeToBranch.getFilePaths()); + } else { + return new Read().can(operation); + } + } + +}