Team and role refactoring and testing.

This commit is contained in:
robin shine 2013-08-17 22:54:39 +08:00
parent 8bee5be88b
commit 9a79414fa3
26 changed files with 771 additions and 187 deletions

View File

@ -82,6 +82,11 @@ public class DefaultGenericDao<T extends AbstractEntity> implements GenericDao<T
return (List<T>) generalDao.search(detachedCriteria, firstResult, maxResults);
}
@Override
public List<T> search(Criterion[] criterions) {
return search(criterions, null, 0, 0);
}
@Override
public Object find(Criterion[] criterions) {

View File

@ -77,6 +77,16 @@ public interface GenericDao<T extends AbstractEntity> {
*/
List<T> search(@Nullable Criterion[] criterions, @Nullable Order[] orders, int firstResult, int maxResults);
/**
* Search entity with specified criterions.
*
* @param criterions
* Hibernate criterions to be used for search. Use null if no criterions.
* @return
* list of entity matching specified criterions.
*/
List<T> search(@Nullable Criterion[] criterions);
/**
* This method expects to find a single entity with specified criteria
*

View File

@ -63,6 +63,7 @@ public abstract class AbstractRealm<T extends AbstractUser> extends AuthorizingR
/**
* Get assigned permissions of user of specified identifier.
* <p>
* @param userId
* Identifier of user to get permissions of. Value of <tt>0</tt> means anonymous user
* @return
@ -72,6 +73,7 @@ public abstract class AbstractRealm<T extends AbstractUser> extends AuthorizingR
/**
* Retrieve {@link AuthenticationInfo} of specified token.
* <p>
* @param token
* The token used to retrieve associated {@link AuthenticationInfo}
* @return

View File

@ -11,26 +11,49 @@ import org.apache.shiro.authz.Permission;
import com.pmease.commons.persistence.dao.GeneralDao;
import com.pmease.commons.security.AbstractRealm;
import com.pmease.gitop.core.entitymanager.GroupManager;
import com.pmease.gitop.core.entitymanager.RoleManager;
import com.pmease.gitop.core.entitymanager.TeamManager;
import com.pmease.gitop.core.entitymanager.UserManager;
import com.pmease.gitop.core.model.RoleMembership;
import com.pmease.gitop.core.model.TeamMembership;
import com.pmease.gitop.core.model.User;
@Singleton
public class UserRealm extends AbstractRealm<User> {
private final GroupManager groupManager;
private final UserManager userManager;
private final RoleManager roleManager;
private final TeamManager teamManager;
@Inject
public UserRealm(GeneralDao generalDao, CredentialsMatcher credentialsMatcher, GroupManager groupManager) {
public UserRealm(GeneralDao generalDao, CredentialsMatcher credentialsMatcher,
UserManager userManager, RoleManager roleManager, TeamManager teamManager) {
super(generalDao, credentialsMatcher);
this.groupManager = groupManager;
this.userManager = userManager;
this.roleManager = roleManager;
this.teamManager = teamManager;
}
@Override
protected Collection<Permission> permissionsOf(Long accountId) {
protected Collection<Permission> permissionsOf(Long userId) {
Collection<Permission> permissions = new ArrayList<Permission>();
permissions.addAll(groupManager.getGroups(accountId));
if (userId != 0L) {
User user = userManager.load(userId);
for (RoleMembership membership: user.getRoleMemberships())
permissions.add(membership.getRole());
for (TeamMembership membership: user.getTeamMemberships())
permissions.add(membership.getTeam());
} else {
permissions.addAll(roleManager.getAnonymousRoles());
permissions.addAll(teamManager.getAnonymousTeams());
}
return permissions;
}

View File

@ -1,15 +0,0 @@
package com.pmease.gitop.core.entitymanager;
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.Team;
@ImplementedBy(DefaultGroupManager.class)
public interface GroupManager extends GenericDao<Team> {
Collection<Team> getGroups(Long userId);
}

View File

@ -0,0 +1,16 @@
package com.pmease.gitop.core.entitymanager;
import java.util.Collection;
import com.google.inject.ImplementedBy;
import com.pmease.commons.persistence.dao.GenericDao;
import com.pmease.gitop.core.entitymanager.impl.DefaultRoleManager;
import com.pmease.gitop.core.model.Role;
@ImplementedBy(DefaultRoleManager.class)
public interface RoleManager extends GenericDao<Role> {
Collection<Role> getAnonymousRoles();
Collection<Role> getRegisterRoles();
}

View File

@ -0,0 +1,17 @@
package com.pmease.gitop.core.entitymanager;
import java.util.Collection;
import com.google.inject.ImplementedBy;
import com.pmease.commons.persistence.dao.GenericDao;
import com.pmease.gitop.core.entitymanager.impl.DefaultTeamManager;
import com.pmease.gitop.core.model.Team;
@ImplementedBy(DefaultTeamManager.class)
public interface TeamManager extends GenericDao<Team> {
Collection<Team> getAnonymousTeams();
Collection<Team> getRegisterTeams();
}

View File

@ -1,39 +0,0 @@
package com.pmease.gitop.core.entitymanager.impl;
import java.util.ArrayList;
import java.util.Collection;
import javax.inject.Provider;
import javax.inject.Singleton;
import org.hibernate.Session;
import com.pmease.commons.persistence.Transactional;
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.Team;
import com.pmease.gitop.core.model.TeamMembership;
@Singleton
public class DefaultGroupManager extends DefaultGenericDao<Team> implements GroupManager {
private final UserManager userManager;
public DefaultGroupManager(GeneralDao generalDao, Provider<Session> sessionProvider, UserManager userManager) {
super(generalDao, sessionProvider);
this.userManager = userManager;
}
@Transactional
@Override
public Collection<Team> getGroups(Long userId) {
Collection<Team> groups = new ArrayList<Team>();
for (TeamMembership membership: userManager.load(userId).getMemberships())
groups.add(membership.getGroup());
return groups;
}
}

View File

@ -0,0 +1,37 @@
package com.pmease.gitop.core.entitymanager.impl;
import java.util.Collection;
import javax.inject.Provider;
import javax.inject.Singleton;
import org.hibernate.Session;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;
import com.pmease.commons.persistence.Transactional;
import com.pmease.commons.persistence.dao.DefaultGenericDao;
import com.pmease.commons.persistence.dao.GeneralDao;
import com.pmease.gitop.core.entitymanager.RoleManager;
import com.pmease.gitop.core.model.Role;
@Singleton
public class DefaultRoleManager extends DefaultGenericDao<Role> implements RoleManager {
public DefaultRoleManager(GeneralDao generalDao, Provider<Session> sessionProvider) {
super(generalDao, sessionProvider);
}
@Transactional
@Override
public Collection<Role> getAnonymousRoles() {
return search(new Criterion[]{Restrictions.eq("anonymous", true)});
}
@Transactional
@Override
public Collection<Role> getRegisterRoles() {
return search(new Criterion[]{Restrictions.eq("register", true)});
}
}

View File

@ -0,0 +1,37 @@
package com.pmease.gitop.core.entitymanager.impl;
import java.util.Collection;
import javax.inject.Provider;
import javax.inject.Singleton;
import org.hibernate.Session;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;
import com.pmease.commons.persistence.Transactional;
import com.pmease.commons.persistence.dao.DefaultGenericDao;
import com.pmease.commons.persistence.dao.GeneralDao;
import com.pmease.gitop.core.entitymanager.TeamManager;
import com.pmease.gitop.core.model.Team;
@Singleton
public class DefaultTeamManager extends DefaultGenericDao<Team> implements TeamManager {
public DefaultTeamManager(GeneralDao generalDao, Provider<Session> sessionProvider) {
super(generalDao, sessionProvider);
}
@Transactional
@Override
public Collection<Team> getAnonymousTeams() {
return search(new Criterion[]{Restrictions.eq("anonymous", true)});
}
@Transactional
@Override
public Collection<Team> getRegisterTeams() {
return search(new Criterion[]{Restrictions.eq("register", true)});
}
}

View File

@ -38,7 +38,6 @@ public class Repository extends AbstractEntity implements UserBelonging {
@Column(nullable=true)
private GateKeeper gateKeeper;
@Override
public User getOwner() {
return owner;
}
@ -70,6 +69,11 @@ public class Repository extends AbstractEntity implements UserBelonging {
public void setGateKeeper(GateKeeper gateKeeper) {
this.gateKeeper = gateKeeper;
}
@Override
public User getUser() {
return getOwner();
}
@Override
public boolean has(ProtectedObject object) {
@ -78,7 +82,7 @@ public class Repository extends AbstractEntity implements UserBelonging {
return repository.getId().equals(getId());
} else if (object instanceof RepositoryBelonging) {
RepositoryBelonging repositoryBelonging = (RepositoryBelonging) object;
return repositoryBelonging.getOwner().getId().equals(getId());
return repositoryBelonging.getRepository().getId().equals(getId());
} else {
return false;
}

View File

@ -1,6 +1,8 @@
package com.pmease.gitop.core.model;
import javax.persistence.Column;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
@ -11,7 +13,11 @@ import javax.persistence.UniqueConstraint;
import org.hibernate.annotations.FetchMode;
import com.pmease.commons.persistence.AbstractEntity;
import com.pmease.gitop.core.model.permission.RepositoryOperation;
import com.pmease.gitop.core.model.permission.BranchPermission;
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;
import com.pmease.gitop.core.model.permission.operation.Read;
@SuppressWarnings("serial")
@Entity
@ -25,38 +31,59 @@ public class RepositoryAuthorization extends AbstractEntity {
@ManyToOne(fetch=FetchType.EAGER)
@org.hibernate.annotations.Fetch(FetchMode.SELECT)
@JoinColumn(nullable=false)
private Team subject;
private Team team;
@ManyToOne(fetch=FetchType.EAGER)
@org.hibernate.annotations.Fetch(FetchMode.SELECT)
@JoinColumn(nullable=false)
private Repository object;
private Repository repository;
@Column(nullable=false)
private RepositoryOperation operation;
public Team getSubject() {
return subject;
}
public void setSubject(Team subject) {
this.subject = subject;
}
private PrivilegedOperation operation = new Read();
public Repository getObject() {
return object;
}
private List<BranchPermission> branchPermissions = new ArrayList<BranchPermission>();
public void setObject(Repository object) {
this.object = object;
}
public RepositoryOperation getOperation() {
public PrivilegedOperation getOperation() {
return operation;
}
public void setOperation(RepositoryOperation operation) {
public void setOperation(PrivilegedOperation operation) {
this.operation = operation;
}
public List<BranchPermission> getBranchPermissions() {
return branchPermissions;
}
public void setBranchPermissions(List<BranchPermission> branchPermissions) {
this.branchPermissions = branchPermissions;
}
public PrivilegedOperation operationOf(ProtectedObject object) {
for (BranchPermission each: getBranchPermissions()) {
if (new ProtectedBranches(repository, each.getBranchNames()).has(object))
return each.getBranchOperation();
}
if (getRepository().has(object))
return getOperation();
else
return null;
}
public Team getTeam() {
return team;
}
public void setTeam(Team team) {
this.team = team;
}
public Repository getRepository() {
return repository;
}
public void setRepository(Repository repository) {
this.repository = repository;
}
}

View File

@ -26,11 +26,15 @@ public class Role extends AbstractEntity implements Permission {
private String description;
private boolean anonymous;
private boolean register;
@Column(nullable=false)
private List<PrivilegedOperation> operations = new ArrayList<PrivilegedOperation>();
@OneToMany(mappedBy="role")
private Collection<RoleMembership> memberships;
private Collection<RoleMembership> memberships = new ArrayList<RoleMembership>();
public String getName() {
return name;
@ -48,6 +52,22 @@ public class Role extends AbstractEntity implements Permission {
this.description = description;
}
public boolean isAnonymous() {
return anonymous;
}
public void setAnonymous(boolean anonymous) {
this.anonymous = anonymous;
}
public boolean isRegister() {
return register;
}
public void setRegister(boolean register) {
this.register = register;
}
public Collection<RoleMembership> getMemberships() {
return memberships;
}

View File

@ -1,5 +1,6 @@
package com.pmease.gitop.core.model;
import java.util.ArrayList;
import java.util.Collection;
import javax.persistence.Column;
@ -13,6 +14,7 @@ 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;
import com.pmease.gitop.core.model.permission.operation.Read;
@Entity
@org.hibernate.annotations.Cache(
@ -30,13 +32,17 @@ public class Team extends AbstractEntity implements Permission {
private String description;
private PrivilegedOperation operation;
private boolean anonymous;
private boolean register;
private PrivilegedOperation operation = new Read();
@OneToMany(mappedBy="team")
private Collection<TeamMembership> memberships;
private Collection<TeamMembership> memberships = new ArrayList<TeamMembership>();
@OneToMany(mappedBy="subject")
private Collection<RepositoryAuthorization> repositoryAuthorizations;
private Collection<RepositoryAuthorization> repositoryAuthorizations = new ArrayList<RepositoryAuthorization>();
public User getOwner() {
return owner;
@ -62,6 +68,22 @@ public class Team extends AbstractEntity implements Permission {
this.description = description;
}
public boolean isAnonymous() {
return anonymous;
}
public void setAnonymous(boolean anonymous) {
this.anonymous = anonymous;
}
public boolean isRegister() {
return register;
}
public void setRegister(boolean register) {
this.register = register;
}
public PrivilegedOperation getOperation() {
return operation;
}
@ -93,8 +115,7 @@ public class Team extends AbstractEntity implements Permission {
ObjectPermission objectPermission = (ObjectPermission) permission;
for (RepositoryAuthorization each: getRepositoryAuthorizations()) {
PrivilegedOperation operation = each.getOperation().operationOf(
objectPermission.getObject(), each.getObject());
PrivilegedOperation operation = each.operationOf(objectPermission.getObject());
if (operation != null)
return operation.can(objectPermission.getOperation());

View File

@ -14,7 +14,7 @@ import com.pmease.commons.persistence.AbstractEntity;
@SuppressWarnings("serial")
@Entity
@Table(uniqueConstraints={
@UniqueConstraint(columnNames={"user", "group"})
@UniqueConstraint(columnNames={"user", "team"})
})
@org.hibernate.annotations.Cache(
usage=org.hibernate.annotations.CacheConcurrencyStrategy.READ_WRITE)
@ -28,7 +28,7 @@ public class TeamMembership extends AbstractEntity {
@ManyToOne(fetch=FetchType.EAGER)
@org.hibernate.annotations.Fetch(FetchMode.SELECT)
@JoinColumn(nullable=false)
private Team group;
private Team team;
public User getUser() {
return user;
@ -38,12 +38,12 @@ public class TeamMembership extends AbstractEntity {
this.user = user;
}
public Team getGroup() {
return group;
public Team getTeam() {
return team;
}
public void setGroup(Team group) {
this.group = group;
public void setTeam(Team team) {
this.team = team;
}
}

View File

@ -1,12 +1,11 @@
package com.pmease.gitop.core.model;
import java.util.ArrayList;
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;
@ -25,26 +24,37 @@ import com.pmease.gitop.core.model.permission.object.UserBelonging;
@Entity
@org.hibernate.annotations.Cache(
usage=org.hibernate.annotations.CacheConcurrencyStrategy.READ_WRITE)
public class User extends AbstractUser implements ProtectedObject, Permission {
public class User extends AbstractUser implements ProtectedObject {
@OneToMany(mappedBy="user")
private Collection<TeamMembership> memberships;
private Collection<TeamMembership> teamMemberships = new ArrayList<TeamMembership>();
@OneToMany(mappedBy="user")
private Collection<MergeRequest> mergeRequests;
private Collection<RoleMembership> roleMemberships = new ArrayList<RoleMembership>();
@OneToMany(mappedBy="user")
private Collection<MergeRequest> mergeRequests = new ArrayList<MergeRequest>();
@OneToMany(mappedBy="owner")
private Collection<Repository> repositories;
private Collection<Repository> repositories = new ArrayList<Repository>();
@OneToMany(mappedBy="owner")
private Collection<Team> teams;
private Collection<Team> teams = new ArrayList<Team>();
public Collection<TeamMembership> getMemberships() {
return memberships;
public Collection<TeamMembership> getTeamMemberships() {
return teamMemberships;
}
public void setMemberships(Collection<TeamMembership> memberships) {
this.memberships = memberships;
public void setTeamMemberships(Collection<TeamMembership> teamMemberships) {
this.teamMemberships = teamMemberships;
}
public Collection<RoleMembership> getRoleMemberships() {
return roleMemberships;
}
public void setRoleMemberships(Collection<RoleMembership> roleMemberships) {
this.roleMemberships = roleMemberships;
}
public Collection<Repository> getRepositories() {
@ -78,20 +88,10 @@ public class User extends AbstractUser implements ProtectedObject, Permission {
return user.getId().equals(getId());
} else if (object instanceof UserBelonging) {
UserBelonging userBelonging = (UserBelonging) object;
return userBelonging.getOwner().getId().equals(getId());
return userBelonging.getUser().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;
}
}

View File

@ -4,24 +4,21 @@ import com.pmease.gitop.core.model.permission.operation.PrivilegedOperation;
public class BranchPermission {
private String branchNames;
private final String branchNames;
private PrivilegedOperation branchOperation;
private final PrivilegedOperation branchOperation;
public BranchPermission(String branchNames, PrivilegedOperation branchOperation) {
this.branchNames = branchNames;
this.branchOperation = 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;
}
}

View File

@ -2,8 +2,16 @@ package com.pmease.gitop.core.model.permission;
import org.apache.shiro.authz.Permission;
import com.pmease.gitop.core.model.Repository;
import com.pmease.gitop.core.model.User;
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.object.SystemObject;
import com.pmease.gitop.core.model.permission.operation.Administration;
import com.pmease.gitop.core.model.permission.operation.PrivilegedOperation;
import com.pmease.gitop.core.model.permission.operation.Read;
import com.pmease.gitop.core.model.permission.operation.Write;
import com.pmease.gitop.core.model.permission.operation.WriteToBranch;
/**
* This class represents permissions to operate an account and its belongings.
@ -49,4 +57,48 @@ public class ObjectPermission implements Permission {
}
}
public static ObjectPermission ofUserAdmin(User user) {
return new ObjectPermission(user, new Administration());
}
public static ObjectPermission ofUserRead(User user) {
return new ObjectPermission(user, new Read());
}
public static ObjectPermission ofUserWrite(User user) {
return new ObjectPermission(user, new Write());
}
public static ObjectPermission ofRepositoryAdmin(Repository repository) {
return new ObjectPermission(repository, new Administration());
}
public static ObjectPermission ofRepositoryRead(Repository repository) {
return new ObjectPermission(repository, new Read());
}
public static ObjectPermission ofRepositoryWrite(Repository repository) {
return new ObjectPermission(repository, new Write());
}
public static ObjectPermission ofBranchAdmin(Repository repository, String branchName) {
return new ObjectPermission(new ProtectedBranches(repository, branchName), new Administration());
}
public static ObjectPermission ofBranchRead(Repository repository, String branchName) {
return new ObjectPermission(new ProtectedBranches(repository, branchName), new Read());
}
public static ObjectPermission ofBranchWrite(Repository repository, String branchName) {
return new ObjectPermission(new ProtectedBranches(repository, branchName), new WriteToBranch("**"));
}
public static ObjectPermission ofBranchWrite(Repository repository, String branchName, String filePath) {
return new ObjectPermission(new ProtectedBranches(repository, branchName), new WriteToBranch(filePath));
}
public static ObjectPermission ofSystem(PrivilegedOperation operation) {
return new ObjectPermission(new SystemObject(), operation);
}
}

View File

@ -1,45 +0,0 @@
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<BranchPermission> branchLevel = new ArrayList<BranchPermission>();
public PrivilegedOperation getRepositoryWide() {
return repositoryLevel;
}
public void setRepositoryLevel(PrivilegedOperation repositoryLevel) {
this.repositoryLevel = repositoryLevel;
}
public List<BranchPermission> getBranchLevel() {
return branchLevel;
}
public void setBranchLevel(List<BranchPermission> 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;
}
}

View File

@ -2,6 +2,7 @@ package com.pmease.gitop.core.model.permission.object;
import com.pmease.commons.util.pattern.WildcardUtils;
import com.pmease.gitop.core.model.Repository;
import com.pmease.gitop.core.model.User;
public class ProtectedBranches implements RepositoryBelonging {
@ -22,15 +23,21 @@ public class ProtectedBranches implements RepositoryBelonging {
public boolean has(ProtectedObject object) {
if (object instanceof ProtectedBranches) {
ProtectedBranches branches = (ProtectedBranches) object;
return WildcardUtils.matchPath(getBranchNames(), branches.getBranchNames());
return getRepository().getId().equals(branches.getRepository().getId())
&& WildcardUtils.matchPath(getBranchNames(), branches.getBranchNames());
} else {
return false;
}
}
@Override
public Repository getOwner() {
public Repository getRepository() {
return repository;
}
@Override
public User getUser() {
return getRepository().getUser();
}
}

View File

@ -2,6 +2,6 @@ package com.pmease.gitop.core.model.permission.object;
import com.pmease.gitop.core.model.Repository;
public interface RepositoryBelonging extends ProtectedObject {
Repository getOwner();
public interface RepositoryBelonging extends UserBelonging {
Repository getRepository();
}

View File

@ -3,5 +3,5 @@ package com.pmease.gitop.core.model.permission.object;
import com.pmease.gitop.core.model.User;
public interface UserBelonging extends ProtectedObject {
User getOwner();
User getUser();
}

View File

@ -0,0 +1,10 @@
package com.pmease.gitop.core.model.permission.operation;
public class NoAccess implements PrivilegedOperation {
@Override
public boolean can(PrivilegedOperation operation) {
return false;
}
}

View File

@ -4,7 +4,7 @@ public class Write implements PrivilegedOperation{
@Override
public boolean can(PrivilegedOperation operation) {
return operation instanceof Write || new Read().can(operation);
return operation instanceof Write || new WriteToBranch("**").can(operation) || new Read().can(operation);
}
}

View File

@ -4,16 +4,16 @@ import com.pmease.commons.util.pattern.WildcardUtils;
public class WriteToBranch implements PrivilegedOperation {
private String filePaths = "**";
private final String filePaths;
public WriteToBranch(String filePaths) {
this.filePaths = filePaths;
}
public String getFilePaths() {
return filePaths;
}
public void setFilePaths(String filePaths) {
this.filePaths = filePaths;
}
@Override
public boolean can(PrivilegedOperation operation) {
if (operation instanceof WriteToBranch) {

View File

@ -0,0 +1,398 @@
package com.pmease.gitop.core.model.permission;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import com.pmease.gitop.core.model.Repository;
import com.pmease.gitop.core.model.RepositoryAuthorization;
import com.pmease.gitop.core.model.Team;
import com.pmease.gitop.core.model.User;
import com.pmease.gitop.core.model.permission.operation.Administration;
import com.pmease.gitop.core.model.permission.operation.NoAccess;
import com.pmease.gitop.core.model.permission.operation.Read;
import com.pmease.gitop.core.model.permission.operation.Write;
import com.pmease.gitop.core.model.permission.operation.WriteToBranch;
public class PermissionTest {
@Test
public void shouldHandleUserAdminPermissionAppropriately() {
User user = new User();
user.setId(100L);
user.setName("robin");
Repository gitop = new Repository();
gitop.setId(200L);
gitop.setOwner(user);
gitop.setName("gitop");
Repository quickbuild = new Repository();
quickbuild.setId(250L);
quickbuild.setOwner(user);
quickbuild.setName("quickbuild");
Team team = new Team();
team.setOwner(user);
team.setOperation(new Administration());
RepositoryAuthorization authorization = new RepositoryAuthorization();
authorization.setId(300L);
authorization.setTeam(team);
authorization.setRepository(gitop);
authorization.setOperation(new NoAccess());
team.getRepositoryAuthorizations().add(authorization);
assertTrue(team.implies(ObjectPermission.ofUserAdmin(user)));
assertTrue(team.implies(ObjectPermission.ofUserWrite(user)));
assertTrue(team.implies(ObjectPermission.ofUserRead(user)));
assertTrue(team.implies(ObjectPermission.ofRepositoryAdmin(quickbuild)));
assertTrue(team.implies(ObjectPermission.ofRepositoryWrite(quickbuild)));
assertTrue(team.implies(ObjectPermission.ofRepositoryRead(quickbuild)));
assertTrue(team.implies(ObjectPermission.ofBranchAdmin(quickbuild, "branch1")));
assertTrue(team.implies(ObjectPermission.ofBranchWrite(quickbuild, "branch1")));
assertTrue(team.implies(ObjectPermission.ofBranchRead(quickbuild, "branch1")));
assertTrue(team.implies(ObjectPermission.ofBranchWrite(quickbuild, "branch1", "src/file")));
assertFalse(team.implies(ObjectPermission.ofRepositoryRead(gitop)));
assertFalse(team.implies(ObjectPermission.ofBranchRead(gitop, "branch1")));
assertFalse(team.implies(ObjectPermission.ofSystem(new Administration())));
assertFalse(team.implies(ObjectPermission.ofSystem(new Write())));
}
@Test
public void shouldHandleUserWriterPermissionAppropriately() {
User user = new User();
user.setId(100L);
user.setName("robin");
Repository repository = new Repository();
repository.setId(200L);
repository.setOwner(user);
repository.setName("gitop");
Team team = new Team();
team.setOwner(user);
team.setOperation(new Write());
RepositoryAuthorization authorization = new RepositoryAuthorization();
authorization.setId(300L);
authorization.setTeam(team);
authorization.setRepository(repository);
authorization.setOperation(new Write());
authorization.getBranchPermissions().add(new BranchPermission("branch2", new Read()));
team.getRepositoryAuthorizations().add(authorization);
assertTrue(team.implies(ObjectPermission.ofUserWrite(user)));
assertTrue(team.implies(ObjectPermission.ofUserRead(user)));
assertTrue(team.implies(ObjectPermission.ofRepositoryWrite(repository)));
assertTrue(team.implies(ObjectPermission.ofRepositoryRead(repository)));
assertTrue(team.implies(ObjectPermission.ofBranchWrite(repository, "branch1")));
assertTrue(team.implies(ObjectPermission.ofBranchRead(repository, "branch1")));
assertTrue(team.implies(ObjectPermission.ofBranchWrite(repository, "branch1", "src/file")));
assertTrue(team.implies(ObjectPermission.ofBranchRead(repository, "branch2")));
assertFalse(team.implies(ObjectPermission.ofBranchWrite(repository, "branch2")));
assertFalse(team.implies(ObjectPermission.ofUserAdmin(user)));
assertFalse(team.implies(ObjectPermission.ofRepositoryAdmin(repository)));
assertFalse(team.implies(ObjectPermission.ofBranchAdmin(repository, "branch1")));
}
@Test
public void shouldHandleUserReaderPermissionAppropriately() {
User user = new User();
user.setId(100L);
user.setName("robin");
Repository repository = new Repository();
repository.setId(200L);
repository.setOwner(user);
repository.setName("gitop");
Team team = new Team();
team.setOwner(user);
team.setOperation(new Read());
assertTrue(team.implies(ObjectPermission.ofUserRead(user)));
assertTrue(team.implies(ObjectPermission.ofRepositoryRead(repository)));
assertTrue(team.implies(ObjectPermission.ofBranchRead(repository, "branch1")));
assertFalse(team.implies(ObjectPermission.ofBranchWrite(repository, "branch1", "src/file")));
assertFalse(team.implies(ObjectPermission.ofBranchWrite(repository, "branch1")));
assertFalse(team.implies(ObjectPermission.ofRepositoryWrite(repository)));
assertFalse(team.implies(ObjectPermission.ofUserWrite(user)));
assertFalse(team.implies(ObjectPermission.ofUserAdmin(user)));
assertFalse(team.implies(ObjectPermission.ofRepositoryAdmin(repository)));
assertFalse(team.implies(ObjectPermission.ofBranchAdmin(repository, "branch1")));
}
@Test
public void shouldHandleRepositoryAdminPermissionAppropriately() {
User user = new User();
user.setId(100L);
Repository gitop = new Repository();
gitop.setId(200L);
gitop.setName("gitop");
gitop.setOwner(user);
Repository quickbuild = new Repository();
quickbuild.setId(250L);
quickbuild.setName("quickbuild");
quickbuild.setOwner(user);
Team team = new Team();
team.setId(300L);
team.setOwner(user);
team.setOperation(new NoAccess());
RepositoryAuthorization authorization = new RepositoryAuthorization();
authorization.setId(400L);
authorization.setTeam(team);
authorization.setRepository(gitop);
authorization.setOperation(new Administration());
authorization.getBranchPermissions().add(new BranchPermission("branch2", new NoAccess()));
team.getRepositoryAuthorizations().add(authorization);
assertTrue(team.implies(ObjectPermission.ofRepositoryAdmin(gitop)));
assertTrue(team.implies(ObjectPermission.ofBranchAdmin(gitop, "branch1")));
assertTrue(team.implies(ObjectPermission.ofBranchWrite(gitop, "branch1", "src/file")));
assertTrue(team.implies(ObjectPermission.ofBranchWrite(gitop, "branch1")));
assertTrue(team.implies(ObjectPermission.ofRepositoryWrite(gitop)));
assertTrue(team.implies(ObjectPermission.ofRepositoryRead(gitop)));
assertTrue(team.implies(ObjectPermission.ofBranchRead(gitop, "branch1")));
assertFalse(team.implies(ObjectPermission.ofBranchRead(gitop, "branch2")));
assertFalse(team.implies(ObjectPermission.ofUserRead(user)));
assertFalse(team.implies(ObjectPermission.ofUserWrite(user)));
assertFalse(team.implies(ObjectPermission.ofUserAdmin(user)));
assertFalse(team.implies(ObjectPermission.ofRepositoryRead(quickbuild)));
}
@Test
public void shouldHandleRepositoryWritePermissionAppropriately() {
User user = new User();
user.setId(100L);
Repository gitop = new Repository();
gitop.setId(200L);
gitop.setName("gitop");
gitop.setOwner(user);
Repository quickbuild = new Repository();
quickbuild.setId(250L);
quickbuild.setName("quickbuild");
quickbuild.setOwner(user);
Team team = new Team();
team.setId(300L);
team.setOwner(user);
team.setOperation(new NoAccess());
RepositoryAuthorization authorization = new RepositoryAuthorization();
authorization.setId(400L);
authorization.setTeam(team);
authorization.setRepository(gitop);
authorization.setOperation(new Write());
team.getRepositoryAuthorizations().add(authorization);
assertTrue(team.implies(ObjectPermission.ofBranchWrite(gitop, "branch1", "src/file")));
assertTrue(team.implies(ObjectPermission.ofBranchWrite(gitop, "branch1")));
assertTrue(team.implies(ObjectPermission.ofRepositoryWrite(gitop)));
assertTrue(team.implies(ObjectPermission.ofRepositoryRead(gitop)));
assertTrue(team.implies(ObjectPermission.ofBranchRead(gitop, "branch1")));
assertFalse(team.implies(ObjectPermission.ofBranchAdmin(gitop, "branch1")));
assertFalse(team.implies(ObjectPermission.ofRepositoryAdmin(gitop)));
assertFalse(team.implies(ObjectPermission.ofUserRead(user)));
assertFalse(team.implies(ObjectPermission.ofUserWrite(user)));
assertFalse(team.implies(ObjectPermission.ofUserAdmin(user)));
assertFalse(team.implies(ObjectPermission.ofRepositoryRead(quickbuild)));
}
@Test
public void shouldHandleRepositoryReadPermissionAppropriately() {
User user = new User();
user.setId(100L);
Repository gitop = new Repository();
gitop.setId(200L);
gitop.setName("gitop");
gitop.setOwner(user);
Repository quickbuild = new Repository();
quickbuild.setId(250L);
quickbuild.setName("quickbuild");
quickbuild.setOwner(user);
Team team = new Team();
team.setId(300L);
team.setOwner(user);
team.setOperation(new NoAccess());
RepositoryAuthorization authorization = new RepositoryAuthorization();
authorization.setId(400L);
authorization.setTeam(team);
authorization.setRepository(gitop);
authorization.setOperation(new Read());
team.getRepositoryAuthorizations().add(authorization);
assertTrue(team.implies(ObjectPermission.ofRepositoryRead(gitop)));
assertTrue(team.implies(ObjectPermission.ofBranchRead(gitop, "branch1")));
assertFalse(team.implies(ObjectPermission.ofBranchWrite(gitop, "branch1", "src/file")));
assertFalse(team.implies(ObjectPermission.ofBranchWrite(gitop, "branch1")));
assertFalse(team.implies(ObjectPermission.ofRepositoryWrite(gitop)));
assertFalse(team.implies(ObjectPermission.ofBranchAdmin(gitop, "branch1")));
assertFalse(team.implies(ObjectPermission.ofRepositoryAdmin(gitop)));
assertFalse(team.implies(ObjectPermission.ofUserRead(user)));
assertFalse(team.implies(ObjectPermission.ofUserWrite(user)));
assertFalse(team.implies(ObjectPermission.ofUserAdmin(user)));
assertFalse(team.implies(ObjectPermission.ofRepositoryRead(quickbuild)));
}
@Test
public void shouldHandleBranchAdminPermissionAppropriately() {
User user = new User();
user.setId(100L);
Repository gitop = new Repository();
gitop.setId(200L);
gitop.setName("gitop");
gitop.setOwner(user);
Repository quickbuild = new Repository();
quickbuild.setId(250L);
quickbuild.setName("quickbuild");
quickbuild.setOwner(user);
Team team = new Team();
team.setId(300L);
team.setOwner(user);
team.setOperation(new NoAccess());
RepositoryAuthorization authorization = new RepositoryAuthorization();
authorization.setId(400L);
authorization.setTeam(team);
authorization.setRepository(gitop);
authorization.setOperation(new NoAccess());
authorization.getBranchPermissions().add(new BranchPermission("**/release", new Administration()));
team.getRepositoryAuthorizations().add(authorization);
assertTrue(team.implies(ObjectPermission.ofBranchAdmin(gitop, "5.0/release")));
assertTrue(team.implies(ObjectPermission.ofBranchRead(gitop, "test/release")));
assertTrue(team.implies(ObjectPermission.ofBranchWrite(gitop, "1.0/release", "src/file")));
assertTrue(team.implies(ObjectPermission.ofBranchWrite(gitop, "2.0/release")));
assertFalse(team.implies(ObjectPermission.ofBranchAdmin(quickbuild, "release")));
assertFalse(team.implies(ObjectPermission.ofRepositoryWrite(gitop)));
assertFalse(team.implies(ObjectPermission.ofRepositoryRead(gitop)));
assertFalse(team.implies(ObjectPermission.ofBranchAdmin(gitop, "branch1")));
assertFalse(team.implies(ObjectPermission.ofUserRead(user)));
assertFalse(team.implies(ObjectPermission.ofUserWrite(user)));
assertFalse(team.implies(ObjectPermission.ofUserAdmin(user)));
assertFalse(team.implies(ObjectPermission.ofRepositoryAdmin(gitop)));
assertFalse(team.implies(ObjectPermission.ofRepositoryRead(quickbuild)));
}
@Test
public void shouldHandleBranchWritePermissionAppropriately() {
User user = new User();
user.setId(100L);
Repository gitop = new Repository();
gitop.setId(200L);
gitop.setName("gitop");
gitop.setOwner(user);
Repository quickbuild = new Repository();
quickbuild.setId(250L);
quickbuild.setName("quickbuild");
quickbuild.setOwner(user);
Team team = new Team();
team.setId(300L);
team.setOwner(user);
team.setOperation(new NoAccess());
RepositoryAuthorization authorization = new RepositoryAuthorization();
authorization.setId(400L);
authorization.setTeam(team);
authorization.setRepository(gitop);
authorization.setOperation(new NoAccess());
authorization.getBranchPermissions().add(new BranchPermission("**/release", new WriteToBranch("-**/*.java, **")));
team.getRepositoryAuthorizations().add(authorization);
assertTrue(team.implies(ObjectPermission.ofBranchRead(gitop, "test/release")));
assertTrue(team.implies(ObjectPermission.ofBranchWrite(gitop, "1.0/release", "src/file")));
assertFalse(team.implies(ObjectPermission.ofBranchWrite(gitop, "2.0/release", "test.java")));
assertFalse(team.implies(ObjectPermission.ofBranchAdmin(gitop, "1.0/release")));
assertFalse(team.implies(ObjectPermission.ofRepositoryWrite(gitop)));
assertFalse(team.implies(ObjectPermission.ofRepositoryRead(gitop)));
assertFalse(team.implies(ObjectPermission.ofBranchAdmin(gitop, "branch1")));
assertFalse(team.implies(ObjectPermission.ofUserRead(user)));
assertFalse(team.implies(ObjectPermission.ofUserWrite(user)));
assertFalse(team.implies(ObjectPermission.ofUserAdmin(user)));
assertFalse(team.implies(ObjectPermission.ofRepositoryAdmin(gitop)));
assertFalse(team.implies(ObjectPermission.ofRepositoryRead(quickbuild)));
}
@Test
public void shouldHandleMultipleBranchPermissionsAppropriately() {
User user = new User();
user.setId(100L);
Repository gitop = new Repository();
gitop.setId(200L);
gitop.setName("gitop");
gitop.setOwner(user);
Repository quickbuild = new Repository();
quickbuild.setId(250L);
quickbuild.setName("quickbuild");
quickbuild.setOwner(user);
Team team = new Team();
team.setId(300L);
team.setOwner(user);
team.setOperation(new NoAccess());
RepositoryAuthorization authorization = new RepositoryAuthorization();
authorization.setId(400L);
authorization.setTeam(team);
authorization.setRepository(gitop);
authorization.setOperation(new NoAccess());
authorization.getBranchPermissions().add(new BranchPermission("branch1", new WriteToBranch("**")));
authorization.getBranchPermissions().add(new BranchPermission("branch2", new Read()));
team.getRepositoryAuthorizations().add(authorization);
assertTrue(team.implies(ObjectPermission.ofBranchRead(gitop, "branch1")));
assertTrue(team.implies(ObjectPermission.ofBranchRead(gitop, "branch2")));
assertTrue(team.implies(ObjectPermission.ofBranchWrite(gitop, "branch1")));
assertFalse(team.implies(ObjectPermission.ofBranchWrite(gitop, "branch2")));
team.setOperation(new Read());
assertTrue(team.implies(ObjectPermission.ofBranchRead(gitop, "branch1")));
assertTrue(team.implies(ObjectPermission.ofBranchRead(quickbuild, "branch2")));
assertTrue(team.implies(ObjectPermission.ofBranchWrite(gitop, "branch1")));
assertFalse(team.implies(ObjectPermission.ofBranchWrite(gitop, "branch2")));
}
}