Simplify model by removing individual permissions and role concept.

This commit is contained in:
robin shine 2013-09-29 16:22:35 +08:00
parent 6cefe8fbef
commit 0f5ae8b81c
46 changed files with 324 additions and 802 deletions

View File

@ -16,8 +16,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import com.pmease.commons.git.Git; import com.pmease.commons.git.Git;
import com.pmease.gitop.core.manager.RepositoryManager; import com.pmease.gitop.core.manager.ProjectManager;
import com.pmease.gitop.core.model.Repository; import com.pmease.gitop.core.model.Project;
@Singleton @Singleton
@SuppressWarnings("serial") @SuppressWarnings("serial")
@ -27,39 +27,39 @@ public class GitServlet extends HttpServlet {
private static final String INFO_REFS = "info/refs"; private static final String INFO_REFS = "info/refs";
private final RepositoryManager repositoryManager; private final ProjectManager projectManager;
@Inject @Inject
public GitServlet(RepositoryManager repositoryManager) { public GitServlet(ProjectManager projectManager) {
this.repositoryManager = repositoryManager; this.projectManager = projectManager;
} }
private Repository getRepository(HttpServletRequest request, HttpServletResponse response, String repoInfo) private Project getProject(HttpServletRequest request, HttpServletResponse response, String repoInfo)
throws IOException { throws IOException {
repoInfo = StringUtils.stripStart(StringUtils.stripEnd(repoInfo, "/"), "/"); repoInfo = StringUtils.stripStart(StringUtils.stripEnd(repoInfo, "/"), "/");
String ownerName = StringUtils.substringBefore(repoInfo, "/"); String ownerName = StringUtils.substringBefore(repoInfo, "/");
String repositoryName = StringUtils.substringAfter(repoInfo, "/"); String projectName = StringUtils.substringAfter(repoInfo, "/");
if (StringUtils.isBlank(ownerName) || StringUtils.isBlank(repositoryName)) { if (StringUtils.isBlank(ownerName) || StringUtils.isBlank(projectName)) {
String url = request.getRequestURL().toString(); String url = request.getRequestURL().toString();
String urlRoot = url.substring(0, url.length()-request.getPathInfo().length()); String urlRoot = url.substring(0, url.length()-request.getPathInfo().length());
String message = "Expecting url of format " + urlRoot + "/<owner name>/<repository name>"; String message = "Expecting url of format " + urlRoot + "/<owner name>/<project name>";
logger.error("Error serving git request: " + message); logger.error("Error serving git request: " + message);
response.sendError(HttpServletResponse.SC_BAD_REQUEST, message); response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
return null; return null;
} }
Repository repository = repositoryManager.find(ownerName, repositoryName); Project project = projectManager.find(ownerName, projectName);
if (repository == null) { if (project == null) {
String message = "Unable to find repository '" + repositoryName + "' owned by '" + ownerName + "'."; String message = "Unable to find project '" + projectName + "' owned by '" + ownerName + "'.";
logger.error("Error serving git request: " + message); logger.error("Error serving git request: " + message);
response.sendError(HttpServletResponse.SC_BAD_REQUEST, message); response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
return null; return null;
} }
return repository; return project;
} }
private void doNotCache(HttpServletResponse response) { private void doNotCache(HttpServletResponse response) {
@ -74,13 +74,13 @@ public class GitServlet extends HttpServlet {
String service = StringUtils.substringAfterLast(pathInfo, "/"); String service = StringUtils.substringAfterLast(pathInfo, "/");
String repoInfo = StringUtils.substringBeforeLast(pathInfo, "/"); String repoInfo = StringUtils.substringBeforeLast(pathInfo, "/");
Repository repository = getRepository(req, resp, repoInfo); Project project = getProject(req, resp, repoInfo);
if (repository != null) { if (project != null) {
doNotCache(resp); doNotCache(resp);
resp.setHeader("Content-Type", "application/x-" + service + "-result"); resp.setHeader("Content-Type", "application/x-" + service + "-result");
Git git = new Git(repositoryManager.locateStorage(repository).ofCode()); Git git = new Git(projectManager.locateStorage(project).ofCode());
try { try {
if (service.contains("upload")) { if (service.contains("upload")) {
@ -111,8 +111,8 @@ public class GitServlet extends HttpServlet {
} }
String repoInfo = pathInfo.substring(0, pathInfo.length() - INFO_REFS.length()); String repoInfo = pathInfo.substring(0, pathInfo.length() - INFO_REFS.length());
Repository repository = getRepository(req, resp, repoInfo); Project project = getProject(req, resp, repoInfo);
if (repository != null) { if (project != null) {
doNotCache(resp); doNotCache(resp);
String service = req.getParameter("service"); String service = req.getParameter("service");
resp.setHeader("Content-Type", "application/x-" + service + "-advertisement"); resp.setHeader("Content-Type", "application/x-" + service + "-advertisement");
@ -122,7 +122,7 @@ public class GitServlet extends HttpServlet {
pack.writeString("# service=" + service + "\n"); pack.writeString("# service=" + service + "\n");
pack.end(); pack.end();
Git git = new Git(repositoryManager.locateStorage(repository).ofCode()); Git git = new Git(projectManager.locateStorage(project).ofCode());
try { try {
if (service.contains("upload")) { if (service.contains("upload")) {

View File

@ -5,7 +5,7 @@ import java.util.Collection;
import com.pmease.commons.editable.annotation.Editable; import com.pmease.commons.editable.annotation.Editable;
import com.pmease.gitop.core.model.MergeRequest; import com.pmease.gitop.core.model.MergeRequest;
import com.pmease.gitop.core.model.User; import com.pmease.gitop.core.model.User;
import com.pmease.gitop.core.permission.operation.RepositoryOperation; import com.pmease.gitop.core.permission.operation.GeneralOperation;
@SuppressWarnings("serial") @SuppressWarnings("serial")
@Editable @Editable
@ -13,7 +13,7 @@ public class ApprovedByAuthorizedUsers extends AbstractGateKeeper {
@Override @Override
public CheckResult check(MergeRequest request) { public CheckResult check(MergeRequest request) {
Collection<User> authorizedUsers = request.getDestination().getRepository().findAuthorizedUsers(RepositoryOperation.WRITE); Collection<User> authorizedUsers = request.getDestination().getProject().findAuthorizedUsers(GeneralOperation.WRITE);
OrGateKeeper or = new OrGateKeeper(); OrGateKeeper or = new OrGateKeeper();
for (User user: authorizedUsers) { for (User user: authorizedUsers) {
ApprovedBySpecifiedUser entry = new ApprovedBySpecifiedUser(); ApprovedBySpecifiedUser entry = new ApprovedBySpecifiedUser();

View File

@ -0,0 +1,29 @@
package com.pmease.gitop.core.gatekeeper;
import com.google.common.collect.Sets;
import com.pmease.commons.editable.annotation.Editable;
import com.pmease.gitop.core.model.MergeRequest;
import com.pmease.gitop.core.model.User;
import com.pmease.gitop.core.model.Vote;
@SuppressWarnings("serial")
@Editable
public class ApprovedByProjectOwner extends AbstractGateKeeper {
@Override
public CheckResult check(MergeRequest request) {
User projectOwner = request.getDestination().getProject().getOwner();
Vote.Result result = projectOwner.checkVoteSince(request.getBaseUpdate());
if (result == null) {
request.inviteToVote(Sets.newHashSet(projectOwner), 1);
return pending("To be approved by user '" + projectOwner.getName() + "'.");
} else if (result.isAccept()) {
return accept("Approved by user '" + projectOwner.getName() + "'.");
} else {
return reject("Rejected by user '" + projectOwner.getName() + "'.");
}
}
}

View File

@ -1,29 +0,0 @@
package com.pmease.gitop.core.gatekeeper;
import com.google.common.collect.Sets;
import com.pmease.commons.editable.annotation.Editable;
import com.pmease.gitop.core.model.MergeRequest;
import com.pmease.gitop.core.model.User;
import com.pmease.gitop.core.model.Vote;
@SuppressWarnings("serial")
@Editable
public class ApprovedByRepositoryOwner extends AbstractGateKeeper {
@Override
public CheckResult check(MergeRequest request) {
User repositoryOwner = request.getDestination().getRepository().getOwner();
Vote.Result result = repositoryOwner.checkVoteSince(request.getBaseUpdate());
if (result == null) {
request.inviteToVote(Sets.newHashSet(repositoryOwner), 1);
return pending("To be approved by user '" + repositoryOwner.getName() + "'.");
} else if (result.isAccept()) {
return accept("Approved by user '" + repositoryOwner.getName() + "'.");
} else {
return reject("Rejected by user '" + repositoryOwner.getName() + "'.");
}
}
}

View File

@ -7,7 +7,7 @@ import javax.validation.constraints.Min;
import com.pmease.commons.editable.annotation.Editable; import com.pmease.commons.editable.annotation.Editable;
import com.pmease.gitop.core.model.MergeRequest; import com.pmease.gitop.core.model.MergeRequest;
import com.pmease.gitop.core.model.TeamMembership; import com.pmease.gitop.core.model.Membership;
import com.pmease.gitop.core.model.User; import com.pmease.gitop.core.model.User;
import com.pmease.gitop.core.model.Vote; import com.pmease.gitop.core.model.Vote;
@ -30,7 +30,7 @@ public class ApprovedBySpecifiedTeam extends TeamAwareGateKeeper {
@Override @Override
public CheckResult check(MergeRequest request) { public CheckResult check(MergeRequest request) {
Collection<User> members = new HashSet<User>(); Collection<User> members = new HashSet<User>();
for (TeamMembership membership: getTeam().getMemberships()) for (Membership membership: getTeam().getMemberships())
members.add(membership.getUser()); members.add(membership.getUser());
int approvals = 0; int approvals = 0;

View File

@ -7,7 +7,7 @@ import javax.validation.constraints.Min;
import com.pmease.commons.editable.annotation.Editable; import com.pmease.commons.editable.annotation.Editable;
import com.pmease.gitop.core.model.MergeRequest; import com.pmease.gitop.core.model.MergeRequest;
import com.pmease.gitop.core.model.TeamMembership; import com.pmease.gitop.core.model.Membership;
import com.pmease.gitop.core.model.User; import com.pmease.gitop.core.model.User;
import com.pmease.gitop.core.model.Vote; import com.pmease.gitop.core.model.Vote;
@ -40,7 +40,7 @@ public class GetMinScoreFromSpecifiedTeam extends TeamAwareGateKeeper {
@Override @Override
public CheckResult check(MergeRequest request) { public CheckResult check(MergeRequest request) {
Collection<User> members = new HashSet<User>(); Collection<User> members = new HashSet<User>();
for (TeamMembership membership: getTeam().getMemberships()) for (Membership membership: getTeam().getMemberships())
members.add(membership.getUser()); members.add(membership.getUser());
int score = 0; int score = 0;

View File

@ -2,7 +2,7 @@ package com.pmease.gitop.core.gatekeeper;
import com.pmease.commons.editable.annotation.Editable; import com.pmease.commons.editable.annotation.Editable;
import com.pmease.gitop.core.model.MergeRequest; import com.pmease.gitop.core.model.MergeRequest;
import com.pmease.gitop.core.model.TeamMembership; import com.pmease.gitop.core.model.Membership;
import com.pmease.gitop.core.model.Vote; import com.pmease.gitop.core.model.Vote;
@SuppressWarnings("serial") @SuppressWarnings("serial")
@ -12,7 +12,7 @@ public class NoRejectionBySpecifiedTeam extends TeamAwareGateKeeper {
@Override @Override
public CheckResult check(MergeRequest request) { public CheckResult check(MergeRequest request) {
for (TeamMembership membership: getTeam().getMemberships()) { for (Membership membership: getTeam().getMemberships()) {
Vote.Result result = membership.getUser().checkVoteSince(request.getBaseUpdate()); Vote.Result result = membership.getUser().checkVoteSince(request.getBaseUpdate());
if (result.isReject()) { if (result.isReject()) {
return reject("Rejected by user '" + membership.getUser().getName() + "'."); return reject("Rejected by user '" + membership.getUser().getName() + "'.");

View File

@ -12,7 +12,7 @@ import com.pmease.commons.util.pattern.PatternSetMatcher;
import com.pmease.commons.util.pattern.WildcardPathMatcher; import com.pmease.commons.util.pattern.WildcardPathMatcher;
import com.pmease.gitop.core.manager.BranchManager; import com.pmease.gitop.core.manager.BranchManager;
import com.pmease.gitop.core.model.MergeRequest; import com.pmease.gitop.core.model.MergeRequest;
import com.pmease.gitop.core.model.Repository; import com.pmease.gitop.core.model.Project;
@SuppressWarnings("serial") @SuppressWarnings("serial")
@Editable @Editable
@ -32,9 +32,9 @@ public class SubmittedToSpecifiedBranch extends AbstractGateKeeper {
@Override @Override
public CheckResult check(MergeRequest request) { public CheckResult check(MergeRequest request) {
Repository repository = request.getDestination().getRepository(); Project project = request.getDestination().getProject();
BranchManager branchManager = AppLoader.getInstance(BranchManager.class); BranchManager branchManager = AppLoader.getInstance(BranchManager.class);
EntityLoader entityLoader = branchManager.asEntityLoader(repository); EntityLoader entityLoader = branchManager.asEntityLoader(project);
EntityMatcher entityMatcher = new EntityMatcher(entityLoader, new WildcardPathMatcher()); EntityMatcher entityMatcher = new EntityMatcher(entityLoader, new WildcardPathMatcher());
PatternSetMatcher patternSetMatcher = new PatternSetMatcher(entityMatcher); PatternSetMatcher patternSetMatcher = new PatternSetMatcher(entityMatcher);
@ -48,13 +48,13 @@ public class SubmittedToSpecifiedBranch extends AbstractGateKeeper {
@Override @Override
public Object trim(Object context) { public Object trim(Object context) {
Preconditions.checkArgument(context instanceof Repository); Preconditions.checkArgument(context instanceof Project);
Repository repository = (Repository) context; Project project = (Project) context;
BranchManager branchManager = AppLoader.getInstance(BranchManager.class); BranchManager branchManager = AppLoader.getInstance(BranchManager.class);
EntityLoader entityLoader = branchManager.asEntityLoader(repository); EntityLoader entityLoader = branchManager.asEntityLoader(project);
EntityPatternSet patternSet = EntityPatternSet.fromStored(getBranchPatterns(), entityLoader); EntityPatternSet patternSet = EntityPatternSet.fromStored(getBranchPatterns(), entityLoader);
patternSet.trim(repository); patternSet.trim(project);
if (patternSet.getStored().isEmpty()) { if (patternSet.getStored().isEmpty()) {
return null; return null;

View File

@ -10,7 +10,7 @@ import com.pmease.commons.git.FindChangedFilesCommand;
import com.pmease.commons.git.Git; import com.pmease.commons.git.Git;
import com.pmease.commons.loader.AppLoader; import com.pmease.commons.loader.AppLoader;
import com.pmease.commons.util.pattern.WildcardUtils; import com.pmease.commons.util.pattern.WildcardUtils;
import com.pmease.gitop.core.manager.RepositoryManager; import com.pmease.gitop.core.manager.ProjectManager;
import com.pmease.gitop.core.model.MergeRequest; import com.pmease.gitop.core.model.MergeRequest;
import com.pmease.gitop.core.model.MergeRequestUpdate; import com.pmease.gitop.core.model.MergeRequestUpdate;
@ -32,8 +32,8 @@ public class TouchSpecifiedFiles extends AbstractGateKeeper {
@Override @Override
public CheckResult check(MergeRequest request) { public CheckResult check(MergeRequest request) {
RepositoryManager repositoryManager = AppLoader.getInstance(RepositoryManager.class); ProjectManager projectManager = AppLoader.getInstance(ProjectManager.class);
File repoDir = repositoryManager.locateStorage(request.getDestination().getRepository()).ofCode(); File repoDir = projectManager.locateStorage(request.getDestination().getProject()).ofCode();
FindChangedFilesCommand command = new Git(repoDir).findChangedFiles(); FindChangedFilesCommand command = new Git(repoDir).findChangedFiles();

View File

@ -0,0 +1,11 @@
package com.pmease.gitop.core.manager;
import com.google.inject.ImplementedBy;
import com.pmease.commons.hibernate.dao.GenericDao;
import com.pmease.gitop.core.manager.impl.DefaultAuthorizationManager;
import com.pmease.gitop.core.model.Authorization;
@ImplementedBy(DefaultAuthorizationManager.class)
public interface AuthorizationManager extends GenericDao<Authorization> {
}

View File

@ -5,13 +5,13 @@ import com.pmease.commons.hibernate.dao.GenericDao;
import com.pmease.commons.util.namedentity.EntityLoader; import com.pmease.commons.util.namedentity.EntityLoader;
import com.pmease.gitop.core.manager.impl.DefaultBranchManager; import com.pmease.gitop.core.manager.impl.DefaultBranchManager;
import com.pmease.gitop.core.model.Branch; import com.pmease.gitop.core.model.Branch;
import com.pmease.gitop.core.model.Repository; import com.pmease.gitop.core.model.Project;
@ImplementedBy(DefaultBranchManager.class) @ImplementedBy(DefaultBranchManager.class)
public interface BranchManager extends GenericDao<Branch> { public interface BranchManager extends GenericDao<Branch> {
public Branch find(Repository repository, String branchName); public Branch find(Project project, String branchName);
public EntityLoader asEntityLoader(Repository repository); public EntityLoader asEntityLoader(Project project);
} }

View File

@ -0,0 +1,19 @@
package com.pmease.gitop.core.manager;
import java.util.Collection;
import com.google.inject.ImplementedBy;
import com.pmease.commons.hibernate.dao.GenericDao;
import com.pmease.gitop.core.manager.impl.DefaultProjectManager;
import com.pmease.gitop.core.model.Project;
import com.pmease.gitop.core.storage.ProjectStorage;
@ImplementedBy(DefaultProjectManager.class)
public interface ProjectManager extends GenericDao<Project> {
ProjectStorage locateStorage(Project project);
Project find(String ownerName, String projectName);
Collection<Project> findPublic();
}

View File

@ -1,11 +0,0 @@
package com.pmease.gitop.core.manager;
import com.google.inject.ImplementedBy;
import com.pmease.commons.hibernate.dao.GenericDao;
import com.pmease.gitop.core.manager.impl.DefaultRepositoryAuthorizationByTeamManager;
import com.pmease.gitop.core.model.RepositoryAuthorizationByIndividual;
@ImplementedBy(DefaultRepositoryAuthorizationByTeamManager.class)
public interface RepositoryAuthorizationByIndividualManager extends GenericDao<RepositoryAuthorizationByIndividual> {
}

View File

@ -1,11 +0,0 @@
package com.pmease.gitop.core.manager;
import com.google.inject.ImplementedBy;
import com.pmease.commons.hibernate.dao.GenericDao;
import com.pmease.gitop.core.manager.impl.DefaultRepositoryAuthorizationByTeamManager;
import com.pmease.gitop.core.model.RepositoryAuthorizationByTeam;
@ImplementedBy(DefaultRepositoryAuthorizationByTeamManager.class)
public interface RepositoryAuthorizationByTeamManager extends GenericDao<RepositoryAuthorizationByTeam> {
}

View File

@ -1,19 +0,0 @@
package com.pmease.gitop.core.manager;
import java.util.Collection;
import com.google.inject.ImplementedBy;
import com.pmease.commons.hibernate.dao.GenericDao;
import com.pmease.gitop.core.manager.impl.DefaultRepositoryManager;
import com.pmease.gitop.core.model.Repository;
import com.pmease.gitop.core.storage.RepositoryStorage;
@ImplementedBy(DefaultRepositoryManager.class)
public interface RepositoryManager extends GenericDao<Repository> {
RepositoryStorage locateStorage(Repository repository);
Repository find(String ownerName, String repositoryName);
Collection<Repository> findPublic();
}

View File

@ -1,11 +0,0 @@
package com.pmease.gitop.core.manager;
import com.google.inject.ImplementedBy;
import com.pmease.commons.hibernate.dao.GenericDao;
import com.pmease.gitop.core.manager.impl.DefaultRoleManager;
import com.pmease.gitop.core.model.Role;
@ImplementedBy(DefaultRoleManager.class)
public interface RoleManager extends GenericDao<Role> {
}

View File

@ -1,11 +0,0 @@
package com.pmease.gitop.core.manager;
import com.google.inject.ImplementedBy;
import com.pmease.commons.hibernate.dao.GenericDao;
import com.pmease.gitop.core.manager.impl.DefaultRepositoryAuthorizationByTeamManager;
import com.pmease.gitop.core.model.UserAuthorizationByIndividual;
@ImplementedBy(DefaultRepositoryAuthorizationByTeamManager.class)
public interface UserAuthorizationByIndividualManager extends GenericDao<UserAuthorizationByIndividual> {
}

View File

@ -0,0 +1,20 @@
package com.pmease.gitop.core.manager.impl;
import javax.inject.Inject;
import javax.inject.Singleton;
import com.pmease.commons.hibernate.dao.AbstractGenericDao;
import com.pmease.commons.hibernate.dao.GeneralDao;
import com.pmease.gitop.core.manager.AuthorizationManager;
import com.pmease.gitop.core.model.Authorization;
@Singleton
public class DefaultAuthorizationManager extends AbstractGenericDao<Authorization>
implements AuthorizationManager {
@Inject
public DefaultAuthorizationManager(GeneralDao generalDao) {
super(generalDao);
}
}

View File

@ -13,7 +13,7 @@ import com.pmease.commons.util.namedentity.EntityLoader;
import com.pmease.commons.util.namedentity.NamedEntity; import com.pmease.commons.util.namedentity.NamedEntity;
import com.pmease.gitop.core.manager.BranchManager; import com.pmease.gitop.core.manager.BranchManager;
import com.pmease.gitop.core.model.Branch; import com.pmease.gitop.core.model.Branch;
import com.pmease.gitop.core.model.Repository; import com.pmease.gitop.core.model.Project;
@Singleton @Singleton
public class DefaultBranchManager extends AbstractGenericDao<Branch> implements BranchManager { public class DefaultBranchManager extends AbstractGenericDao<Branch> implements BranchManager {
@ -26,12 +26,12 @@ public class DefaultBranchManager extends AbstractGenericDao<Branch> implements
@Sessional @Sessional
@Override @Override
public Branch find(Repository repository, String name) { public Branch find(Project project, String name) {
return find(new Criterion[]{Restrictions.eq("repository", repository), Restrictions.eq("name", name)}); return find(new Criterion[]{Restrictions.eq("project", project), Restrictions.eq("name", name)});
} }
@Override @Override
public EntityLoader asEntityLoader(final Repository repository) { public EntityLoader asEntityLoader(final Project project) {
return new EntityLoader() { return new EntityLoader() {
@Override @Override
@ -58,7 +58,7 @@ public class DefaultBranchManager extends AbstractGenericDao<Branch> implements
@Override @Override
public NamedEntity get(String name) { public NamedEntity get(String name) {
final Branch branch = find(repository, name); final Branch branch = find(project, name);
if (branch != null) { if (branch != null) {
return new NamedEntity() { return new NamedEntity() {

View File

@ -15,17 +15,17 @@ import com.pmease.commons.hibernate.Transactional;
import com.pmease.commons.hibernate.dao.AbstractGenericDao; import com.pmease.commons.hibernate.dao.AbstractGenericDao;
import com.pmease.commons.hibernate.dao.GeneralDao; import com.pmease.commons.hibernate.dao.GeneralDao;
import com.pmease.gitop.core.manager.ConfigManager; import com.pmease.gitop.core.manager.ConfigManager;
import com.pmease.gitop.core.manager.RepositoryManager; import com.pmease.gitop.core.manager.ProjectManager;
import com.pmease.gitop.core.model.Repository; import com.pmease.gitop.core.model.Project;
import com.pmease.gitop.core.storage.RepositoryStorage; import com.pmease.gitop.core.storage.ProjectStorage;
@Singleton @Singleton
public class DefaultRepositoryManager extends AbstractGenericDao<Repository> implements RepositoryManager { public class DefaultProjectManager extends AbstractGenericDao<Project> implements ProjectManager {
private ConfigManager configManager; private ConfigManager configManager;
@Inject @Inject
public DefaultRepositoryManager(GeneralDao generalDao, ConfigManager configManager) { public DefaultProjectManager(GeneralDao generalDao, ConfigManager configManager) {
super(generalDao); super(generalDao);
this.configManager = configManager; this.configManager = configManager;
@ -33,11 +33,11 @@ public class DefaultRepositoryManager extends AbstractGenericDao<Repository> imp
@Transactional @Transactional
@Override @Override
public void save(Repository entity) { public void save(Project entity) {
if (entity.isNew()) { if (entity.isNew()) {
super.save(entity); super.save(entity);
RepositoryStorage storage = locateStorage(entity); ProjectStorage storage = locateStorage(entity);
storage.clean(); storage.clean();
new Git(storage.ofCode()).init().bare(true).call(); new Git(storage.ofCode()).init().bare(true).call();
@ -48,31 +48,31 @@ public class DefaultRepositoryManager extends AbstractGenericDao<Repository> imp
@Transactional @Transactional
@Override @Override
public void delete(Repository entity) { public void delete(Project entity) {
super.delete(entity); super.delete(entity);
locateStorage(entity).delete(); locateStorage(entity).delete();
} }
@Override @Override
public RepositoryStorage locateStorage(Repository repository) { public ProjectStorage locateStorage(Project project) {
return new RepositoryStorage(new File(configManager.getStorageSetting().getRepoStorageDir(), repository.getId().toString())); return new ProjectStorage(new File(configManager.getStorageSetting().getStorageDir(), project.getId().toString()));
} }
@Override @Override
public Collection<Repository> findPublic() { public Collection<Project> findPublic() {
return query(new Criterion[]{Restrictions.eq("publiclyAccessible", true)}); return query(new Criterion[]{Restrictions.eq("publiclyAccessible", true)});
} }
@Override @Override
public Repository find(String ownerName, String repositoryName) { public Project find(String ownerName, String projectName) {
Criteria criteria = createCriteria(); Criteria criteria = createCriteria();
criteria.add(Restrictions.eq("name", repositoryName)); criteria.add(Restrictions.eq("name", projectName));
criteria.createAlias("owner", "owner"); criteria.createAlias("owner", "owner");
criteria.add(Restrictions.eq("owner.name", ownerName)); criteria.add(Restrictions.eq("owner.name", ownerName));
criteria.setMaxResults(1); criteria.setMaxResults(1);
return (Repository) criteria.uniqueResult(); return (Project) criteria.uniqueResult();
} }
} }

View File

@ -1,21 +0,0 @@
package com.pmease.gitop.core.manager.impl;
import javax.inject.Inject;
import javax.inject.Singleton;
import com.pmease.commons.hibernate.dao.AbstractGenericDao;
import com.pmease.commons.hibernate.dao.GeneralDao;
import com.pmease.gitop.core.manager.RepositoryAuthorizationByIndividualManager;
import com.pmease.gitop.core.model.RepositoryAuthorizationByIndividual;
@Singleton
public class DefaultRepositoryAuthorizationByIndividualManager
extends AbstractGenericDao<RepositoryAuthorizationByIndividual>
implements RepositoryAuthorizationByIndividualManager {
@Inject
public DefaultRepositoryAuthorizationByIndividualManager(GeneralDao generalDao) {
super(generalDao);
}
}

View File

@ -1,20 +0,0 @@
package com.pmease.gitop.core.manager.impl;
import javax.inject.Inject;
import javax.inject.Singleton;
import com.pmease.commons.hibernate.dao.AbstractGenericDao;
import com.pmease.commons.hibernate.dao.GeneralDao;
import com.pmease.gitop.core.manager.RepositoryAuthorizationByTeamManager;
import com.pmease.gitop.core.model.RepositoryAuthorizationByTeam;
@Singleton
public class DefaultRepositoryAuthorizationByTeamManager extends AbstractGenericDao<RepositoryAuthorizationByTeam>
implements RepositoryAuthorizationByTeamManager {
@Inject
public DefaultRepositoryAuthorizationByTeamManager(GeneralDao generalDao) {
super(generalDao);
}
}

View File

@ -1,22 +0,0 @@
package com.pmease.gitop.core.manager.impl;
import javax.inject.Inject;
import javax.inject.Provider;
import javax.inject.Singleton;
import org.hibernate.Session;
import com.pmease.commons.hibernate.dao.AbstractGenericDao;
import com.pmease.commons.hibernate.dao.GeneralDao;
import com.pmease.gitop.core.manager.RoleManager;
import com.pmease.gitop.core.model.Role;
@Singleton
public class DefaultRoleManager extends AbstractGenericDao<Role> implements RoleManager {
@Inject
public DefaultRoleManager(GeneralDao generalDao, Provider<Session> sessionProvider) {
super(generalDao);
}
}

View File

@ -1,21 +0,0 @@
package com.pmease.gitop.core.manager.impl;
import javax.inject.Inject;
import javax.inject.Singleton;
import com.pmease.commons.hibernate.dao.AbstractGenericDao;
import com.pmease.commons.hibernate.dao.GeneralDao;
import com.pmease.gitop.core.manager.UserAuthorizationByIndividualManager;
import com.pmease.gitop.core.model.UserAuthorizationByIndividual;
@Singleton
public class DefaultUserAuthorizationByIndividualManager
extends AbstractGenericDao<UserAuthorizationByIndividual>
implements UserAuthorizationByIndividualManager {
@Inject
public DefaultUserAuthorizationByIndividualManager(GeneralDao generalDao) {
super(generalDao);
}
}

View File

@ -7,14 +7,14 @@ import javax.persistence.Table;
import javax.persistence.UniqueConstraint; import javax.persistence.UniqueConstraint;
import com.pmease.commons.hibernate.AbstractEntity; import com.pmease.commons.hibernate.AbstractEntity;
import com.pmease.gitop.core.permission.operation.RepositoryOperation; import com.pmease.gitop.core.permission.operation.GeneralOperation;
@SuppressWarnings("serial") @SuppressWarnings("serial")
@Entity @Entity
@Table(uniqueConstraints={ @Table(uniqueConstraints={
@UniqueConstraint(columnNames={"team", "repository"}) @UniqueConstraint(columnNames={"team", "project"})
}) })
public class RepositoryAuthorizationByTeam extends AbstractEntity { public class Authorization extends AbstractEntity {
@ManyToOne @ManyToOne
@JoinColumn(nullable=false) @JoinColumn(nullable=false)
@ -22,15 +22,15 @@ public class RepositoryAuthorizationByTeam extends AbstractEntity {
@ManyToOne @ManyToOne
@JoinColumn(nullable=false) @JoinColumn(nullable=false)
private Repository repository; private Project project;
private RepositoryOperation authorizedOperation = RepositoryOperation.READ; private GeneralOperation authorizedOperation = GeneralOperation.READ;
public RepositoryOperation getAuthorizedOperation() { public GeneralOperation getAuthorizedOperation() {
return authorizedOperation; return authorizedOperation;
} }
public void setAuthorizedOperation(RepositoryOperation authorizedOperation) { public void setAuthorizedOperation(GeneralOperation authorizedOperation) {
this.authorizedOperation = authorizedOperation; this.authorizedOperation = authorizedOperation;
} }
@ -42,12 +42,12 @@ public class RepositoryAuthorizationByTeam extends AbstractEntity {
this.team = team; this.team = team;
} }
public Repository getRepository() { public Project getProject() {
return repository; return project;
} }
public void setRepository(Repository repository) { public void setProject(Project project) {
this.repository = repository; this.project = project;
} }
} }

View File

@ -12,23 +12,23 @@ import com.pmease.commons.hibernate.AbstractEntity;
@SuppressWarnings("serial") @SuppressWarnings("serial")
@Entity @Entity
@Table(uniqueConstraints={ @Table(uniqueConstraints={
@UniqueConstraint(columnNames={"repository", "name"}) @UniqueConstraint(columnNames={"project", "name"})
}) })
public class Branch extends AbstractEntity { public class Branch extends AbstractEntity {
@ManyToOne @ManyToOne
@JoinColumn(nullable=false) @JoinColumn(nullable=false)
private Repository repository; private Project project;
@Column(nullable=false) @Column(nullable=false)
private String name; private String name;
public Repository getRepository() { public Project getProject() {
return repository; return project;
} }
public void setRepository(Repository repository) { public void setProject(Project project) {
this.repository = repository; this.project = project;
} }
public String getName() { public String getName() {

View File

@ -13,7 +13,7 @@ import com.pmease.commons.hibernate.AbstractEntity;
@Table(uniqueConstraints={ @Table(uniqueConstraints={
@UniqueConstraint(columnNames={"user", "team"}) @UniqueConstraint(columnNames={"user", "team"})
}) })
public class TeamMembership extends AbstractEntity { public class Membership extends AbstractEntity {
@ManyToOne @ManyToOne
@JoinColumn(nullable=false) @JoinColumn(nullable=false)

View File

@ -26,7 +26,7 @@ import com.pmease.commons.hibernate.AbstractEntity;
import com.pmease.gitop.core.Gitop; import com.pmease.gitop.core.Gitop;
import com.pmease.gitop.core.gatekeeper.CheckResult; import com.pmease.gitop.core.gatekeeper.CheckResult;
import com.pmease.gitop.core.gatekeeper.GateKeeper; import com.pmease.gitop.core.gatekeeper.GateKeeper;
import com.pmease.gitop.core.manager.RepositoryManager; import com.pmease.gitop.core.manager.ProjectManager;
import com.pmease.gitop.core.manager.VoteInvitationManager; import com.pmease.gitop.core.manager.VoteInvitationManager;
@SuppressWarnings("serial") @SuppressWarnings("serial")
@ -172,7 +172,7 @@ public class MergeRequest extends AbstractEntity {
if (effectiveUpdates == null) { if (effectiveUpdates == null) {
effectiveUpdates = new ArrayList<MergeRequestUpdate>(); effectiveUpdates = new ArrayList<MergeRequestUpdate>();
File repoDir = Gitop.getInstance(RepositoryManager.class).locateStorage(getDestination().getRepository()).ofCode(); File repoDir = Gitop.getInstance(ProjectManager.class).locateStorage(getDestination().getProject()).ofCode();
Git git = new Git(repoDir); Git git = new Git(repoDir);
CheckAncestorCommand command = git.checkAncestor(); CheckAncestorCommand command = git.checkAncestor();
command.ancestor(getMergeBase()); command.ancestor(getMergeBase());
@ -195,7 +195,7 @@ public class MergeRequest extends AbstractEntity {
} }
public boolean isFastForward() { public boolean isFastForward() {
File repoDir = Gitop.getInstance(RepositoryManager.class).locateStorage(getDestination().getRepository()).ofCode(); File repoDir = Gitop.getInstance(ProjectManager.class).locateStorage(getDestination().getProject()).ofCode();
CheckAncestorCommand command = new Git(repoDir).checkAncestor(); CheckAncestorCommand command = new Git(repoDir).checkAncestor();
command.ancestor(getDestination().getName()); command.ancestor(getDestination().getName());
command.descendant(getLatestUpdate().getRefName()); command.descendant(getLatestUpdate().getRefName());
@ -203,8 +203,8 @@ public class MergeRequest extends AbstractEntity {
} }
public Collection<String> findTouchedFiles() { public Collection<String> findTouchedFiles() {
RepositoryManager repositoryManager = Gitop.getInstance(RepositoryManager.class); ProjectManager projectManager = Gitop.getInstance(ProjectManager.class);
File repoDir = repositoryManager.locateStorage(getDestination().getRepository()).ofCode(); File repoDir = projectManager.locateStorage(getDestination().getProject()).ofCode();
MergeRequestUpdate update = getLatestUpdate(); MergeRequestUpdate update = getLatestUpdate();
if (update != null) { if (update != null) {
FindChangedFilesCommand command = new Git(repoDir).findChangedFiles(); FindChangedFilesCommand command = new Git(repoDir).findChangedFiles();
@ -218,8 +218,8 @@ public class MergeRequest extends AbstractEntity {
public boolean isMerged() { public boolean isMerged() {
if (merged == null) { if (merged == null) {
RepositoryManager repositoryManager = Gitop.getInstance(RepositoryManager.class); ProjectManager projectManager = Gitop.getInstance(ProjectManager.class);
File repoDir = repositoryManager.locateStorage(getDestination().getRepository()).ofCode(); File repoDir = projectManager.locateStorage(getDestination().getProject()).ofCode();
CheckAncestorCommand command = new Git(repoDir).checkAncestor(); CheckAncestorCommand command = new Git(repoDir).checkAncestor();
command.ancestor(getLatestUpdate().getRefName()); command.ancestor(getLatestUpdate().getRefName());
command.descendant(getDestination().getName()); command.descendant(getDestination().getName());
@ -230,8 +230,8 @@ public class MergeRequest extends AbstractEntity {
public String getMergeBase() { public String getMergeBase() {
if (mergeBase == null) { if (mergeBase == null) {
RepositoryManager repositoryManager = Gitop.getInstance(RepositoryManager.class); ProjectManager projectManager = Gitop.getInstance(ProjectManager.class);
File repoDir = repositoryManager.locateStorage(getDestination().getRepository()).ofCode(); File repoDir = projectManager.locateStorage(getDestination().getProject()).ofCode();
CalcMergeBaseCommand command = new Git(repoDir).calcMergeBase(); CalcMergeBaseCommand command = new Git(repoDir).calcMergeBase();
command.rev1(getLatestUpdate().getRefName()); command.rev1(getLatestUpdate().getRefName());
command.rev2(getDestination().getName()); command.rev2(getDestination().getName());
@ -315,7 +315,7 @@ public class MergeRequest extends AbstractEntity {
} }
/** /**
* Check this request with gate keeper of target repository. * Check this request with gate keeper of target project.
* <p> * <p>
* @param force * @param force
* whether or not to force the check. Since the check might be time-consuming, Gitop * whether or not to force the check. Since the check might be time-consuming, Gitop
@ -326,7 +326,7 @@ public class MergeRequest extends AbstractEntity {
*/ */
public Optional<CheckResult> check(boolean force) { public Optional<CheckResult> check(boolean force) {
if (checkResult == null || force) { if (checkResult == null || force) {
GateKeeper gateKeeper = getDestination().getRepository().getGateKeeper(); GateKeeper gateKeeper = getDestination().getProject().getGateKeeper();
if (gateKeeper != null) { if (gateKeeper != null) {
checkResult = Optional.of(gateKeeper.check(this)); checkResult = Optional.of(gateKeeper.check(this));

View File

@ -23,7 +23,7 @@ import com.pmease.gitop.core.manager.UserManager;
import com.pmease.gitop.core.permission.ObjectPermission; import com.pmease.gitop.core.permission.ObjectPermission;
import com.pmease.gitop.core.permission.object.ProtectedObject; import com.pmease.gitop.core.permission.object.ProtectedObject;
import com.pmease.gitop.core.permission.object.UserBelonging; import com.pmease.gitop.core.permission.object.UserBelonging;
import com.pmease.gitop.core.permission.operation.RepositoryOperation; import com.pmease.gitop.core.permission.operation.GeneralOperation;
@Entity @Entity
@Table(uniqueConstraints={ @Table(uniqueConstraints={
@ -31,7 +31,7 @@ import com.pmease.gitop.core.permission.operation.RepositoryOperation;
}) })
@SuppressWarnings("serial") @SuppressWarnings("serial")
@Editable @Editable
public class Repository extends AbstractEntity implements UserBelonging { public class Project extends AbstractEntity implements UserBelonging {
@ManyToOne @ManyToOne
@JoinColumn(nullable=false) @JoinColumn(nullable=false)
@ -44,17 +44,13 @@ public class Repository extends AbstractEntity implements UserBelonging {
private boolean publiclyAccessible; private boolean publiclyAccessible;
private RepositoryOperation defaultAuthorizedOperation; @Column(nullable=false)
private GeneralOperation defaultAuthorizedOperation = GeneralOperation.NO_ACCESS;
private GateKeeper gateKeeper; private GateKeeper gateKeeper;
@OneToMany(mappedBy="repository") @OneToMany(mappedBy="project")
private Collection<RepositoryAuthorizationByTeam> authorizationsByTeam = private Collection<Authorization> authorizations = new ArrayList<Authorization>();
new ArrayList<RepositoryAuthorizationByTeam>();
@OneToMany(mappedBy="repository")
private Collection<RepositoryAuthorizationByIndividual> authorizationsByIndividual =
new ArrayList<RepositoryAuthorizationByIndividual>();
public User getOwner() { public User getOwner() {
return owner; return owner;
@ -65,7 +61,7 @@ public class Repository extends AbstractEntity implements UserBelonging {
} }
@Editable(description= @Editable(description=
"Specify name of the repository. It will be used to identify the repository when accessing via Git.") "Specify name of the project. It will be used to identify the project when accessing via Git.")
@NotEmpty @NotEmpty
public String getName() { public String getName() {
return name; return name;
@ -75,7 +71,7 @@ public class Repository extends AbstractEntity implements UserBelonging {
this.name = name; this.name = name;
} }
@Editable(description="Specify description of the repository.") @Editable(description="Specify description of the project.")
public String getDescription() { public String getDescription() {
return description; return description;
} }
@ -85,7 +81,7 @@ public class Repository extends AbstractEntity implements UserBelonging {
} }
@Editable(name="Public", description= @Editable(name="Public", description=
"If a repository is made public, it will be able to be browsed/pulled by anonymous users.") "If a project is made public, it will be able to be browsed/pulled by anonymous users.")
public boolean isPubliclyAccessible() { public boolean isPubliclyAccessible() {
return publiclyAccessible; return publiclyAccessible;
} }
@ -94,12 +90,12 @@ public class Repository extends AbstractEntity implements UserBelonging {
this.publiclyAccessible = publiclyAccessible; this.publiclyAccessible = publiclyAccessible;
} }
public RepositoryOperation getDefaultAuthorizedOperation() { public GeneralOperation getDefaultAuthorizedOperation() {
return defaultAuthorizedOperation; return defaultAuthorizedOperation;
} }
public void setDefaultAuthorizedOperation( public void setDefaultAuthorizedOperation(
RepositoryOperation defaultAuthorizedOperation) { GeneralOperation defaultAuthorizedOperation) {
this.defaultAuthorizedOperation = defaultAuthorizedOperation; this.defaultAuthorizedOperation = defaultAuthorizedOperation;
} }
@ -119,35 +115,25 @@ public class Repository extends AbstractEntity implements UserBelonging {
return getOwner(); return getOwner();
} }
public Collection<RepositoryAuthorizationByTeam> getAuthorizationsByTeam() { public Collection<Authorization> getAuthorizations() {
return authorizationsByTeam; return authorizations;
} }
public void setAuthorizationsByTeam( public void setAuthorizations(Collection<Authorization> authorizations) {
Collection<RepositoryAuthorizationByTeam> authorizationsByTeam) { this.authorizations = authorizations;
this.authorizationsByTeam = authorizationsByTeam;
}
public Collection<RepositoryAuthorizationByIndividual> getAuthorizationsByIndividual() {
return authorizationsByIndividual;
}
public void setAuthorizationsByIndividual(
Collection<RepositoryAuthorizationByIndividual> authorizationsByIndividual) {
this.authorizationsByIndividual = authorizationsByIndividual;
} }
@Override @Override
public boolean has(ProtectedObject object) { public boolean has(ProtectedObject object) {
if (object instanceof Repository) { if (object instanceof Project) {
Repository repository = (Repository) object; Project project = (Project) object;
return repository.getId().equals(getId()); return project.getId().equals(getId());
} else { } else {
return false; return false;
} }
} }
public Collection<User> findAuthorizedUsers(RepositoryOperation operation) { public Collection<User> findAuthorizedUsers(GeneralOperation operation) {
Set<User> authorizedUsers = new HashSet<User>(); Set<User> authorizedUsers = new HashSet<User>();
for (User user: Gitop.getInstance(UserManager.class).query(null)) { for (User user: Gitop.getInstance(UserManager.class).query(null)) {
if (user.asSubject().isPermitted(new ObjectPermission(this, operation))) if (user.asSubject().isPermitted(new ObjectPermission(this, operation)))

View File

@ -1,53 +0,0 @@
package com.pmease.gitop.core.model;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import com.pmease.commons.hibernate.AbstractEntity;
import com.pmease.gitop.core.permission.operation.RepositoryOperation;
@SuppressWarnings("serial")
@Entity
@Table(uniqueConstraints={
@UniqueConstraint(columnNames={"individual", "repository"})
})
public class RepositoryAuthorizationByIndividual extends AbstractEntity {
@ManyToOne
@JoinColumn(nullable=false)
private User individual;
@ManyToOne
@JoinColumn(nullable=false)
private Repository repository;
private RepositoryOperation authorizedOperation = RepositoryOperation.READ;
public RepositoryOperation getAuthorizedOperation() {
return authorizedOperation;
}
public void setAuthorizedOperation(RepositoryOperation authorizedOperation) {
this.authorizedOperation = authorizedOperation;
}
public User getIndividual() {
return individual;
}
public void setIndividual(User individual) {
this.individual = individual;
}
public Repository getRepository() {
return repository;
}
public void setRepository(Repository repository) {
this.repository = repository;
}
}

View File

@ -1,75 +0,0 @@
package com.pmease.gitop.core.model;
import java.util.ArrayList;
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.hibernate.AbstractEntity;
import com.pmease.gitop.core.permission.ObjectPermission;
import com.pmease.gitop.core.permission.operation.PrivilegedOperation;
@Entity
@SuppressWarnings("serial")
public class Role extends AbstractEntity implements Permission {
@Column(nullable=false, unique=true)
private String name;
private String description;
@Column(nullable=false)
private ArrayList<PrivilegedOperation> operations = new ArrayList<PrivilegedOperation>();
@OneToMany(mappedBy="role")
private Collection<RoleMembership> memberships = new ArrayList<RoleMembership>();
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<RoleMembership> getMemberships() {
return memberships;
}
public void setMemberships(Collection<RoleMembership> memberships) {
this.memberships = memberships;
}
public ArrayList<PrivilegedOperation> getOperations() {
return operations;
}
public void setOperations(ArrayList<PrivilegedOperation> operations) {
this.operations = operations;
}
@Override
public boolean implies(Permission permission) {
if (permission instanceof ObjectPermission) {
ObjectPermission objectPermission = (ObjectPermission) permission;
for (PrivilegedOperation each: getOperations()) {
if (each.can(objectPermission.getOperation()))
return true;
}
}
return false;
}
}

View File

@ -1,42 +0,0 @@
package com.pmease.gitop.core.model;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import com.pmease.commons.hibernate.AbstractEntity;
@SuppressWarnings("serial")
@Entity
@Table(uniqueConstraints={
@UniqueConstraint(columnNames={"user", "role"})
})
public class RoleMembership extends AbstractEntity {
@ManyToOne
@JoinColumn(nullable=false)
private User user;
@ManyToOne
@JoinColumn(nullable=false)
private Role role;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Role getRole() {
return role;
}
public void setRole(Role role) {
this.role = role;
}
}

View File

@ -15,7 +15,7 @@ import org.apache.shiro.authz.Permission;
import com.pmease.commons.hibernate.AbstractEntity; import com.pmease.commons.hibernate.AbstractEntity;
import com.pmease.gitop.core.permission.ObjectPermission; import com.pmease.gitop.core.permission.ObjectPermission;
import com.pmease.gitop.core.permission.operation.UserOperation; import com.pmease.gitop.core.permission.operation.GeneralOperation;
@Entity @Entity
@Table(uniqueConstraints={ @Table(uniqueConstraints={
@ -33,18 +33,14 @@ public class Team extends AbstractEntity implements Permission {
private String description; private String description;
private boolean anonymous;
private boolean register;
@Column(nullable=false) @Column(nullable=false)
private UserOperation authorizedOperation = UserOperation.READ; private GeneralOperation authorizedOperation = GeneralOperation.READ;
@OneToMany(mappedBy="team") @OneToMany(mappedBy="team")
private Collection<TeamMembership> memberships = new ArrayList<TeamMembership>(); private Collection<Membership> memberships = new ArrayList<Membership>();
@OneToMany(mappedBy="team") @OneToMany(mappedBy="team")
private Collection<RepositoryAuthorizationByTeam> repositoryAuthorizations = new ArrayList<RepositoryAuthorizationByTeam>(); private Collection<Authorization> authorizations = new ArrayList<Authorization>();
public User getOwner() { public User getOwner() {
return owner; return owner;
@ -70,44 +66,28 @@ public class Team extends AbstractEntity implements Permission {
this.description = description; this.description = description;
} }
public boolean isAnonymous() { public GeneralOperation getAuthorizedOperation() {
return anonymous;
}
public void setAnonymous(boolean anonymous) {
this.anonymous = anonymous;
}
public boolean isRegister() {
return register;
}
public void setRegister(boolean register) {
this.register = register;
}
public UserOperation getAuthorizedOperation() {
return authorizedOperation; return authorizedOperation;
} }
public void setAuthorizedOperation(UserOperation authorizedOeration) { public void setAuthorizedOperation(GeneralOperation authorizedOeration) {
this.authorizedOperation = authorizedOeration; this.authorizedOperation = authorizedOeration;
} }
public Collection<TeamMembership> getMemberships() { public Collection<Membership> getMemberships() {
return memberships; return memberships;
} }
public void setMemberships(Collection<TeamMembership> memberships) { public void setMemberships(Collection<Membership> memberships) {
this.memberships = memberships; this.memberships = memberships;
} }
public Collection<RepositoryAuthorizationByTeam> getRepositoryAuthorizations() { public Collection<Authorization> getAuthorizations() {
return repositoryAuthorizations; return authorizations;
} }
public void setRepositoryAuthorizations(Collection<RepositoryAuthorizationByTeam> repositoryAuthorizations) { public void setAuthorizations(Collection<Authorization> authorizations) {
this.repositoryAuthorizations = repositoryAuthorizations; this.authorizations = authorizations;
} }
@Override @Override
@ -118,10 +98,10 @@ public class Team extends AbstractEntity implements Permission {
if (userPermission.implies(objectPermission)) if (userPermission.implies(objectPermission))
return true; return true;
for (RepositoryAuthorizationByTeam authorization: getRepositoryAuthorizations()) { for (Authorization authorization: getAuthorizations()) {
Permission repositoryPermission = new ObjectPermission( Permission projectPermission = new ObjectPermission(
authorization.getRepository(), authorization.getAuthorizedOperation()); authorization.getProject(), authorization.getAuthorizedOperation());
if (repositoryPermission.implies(objectPermission)) if (projectPermission.implies(objectPermission))
return true; return true;
} }
} }

View File

@ -16,19 +16,19 @@ import com.pmease.commons.editable.annotation.Password;
import com.pmease.commons.loader.AppLoader; import com.pmease.commons.loader.AppLoader;
import com.pmease.commons.shiro.AbstractUser; import com.pmease.commons.shiro.AbstractUser;
import com.pmease.gitop.core.Gitop; import com.pmease.gitop.core.Gitop;
import com.pmease.gitop.core.manager.RepositoryManager; import com.pmease.gitop.core.manager.ProjectManager;
import com.pmease.gitop.core.manager.UserManager; import com.pmease.gitop.core.manager.UserManager;
import com.pmease.gitop.core.permission.ObjectPermission; import com.pmease.gitop.core.permission.ObjectPermission;
import com.pmease.gitop.core.permission.object.ProtectedObject; import com.pmease.gitop.core.permission.object.ProtectedObject;
import com.pmease.gitop.core.permission.object.UserBelonging; import com.pmease.gitop.core.permission.object.UserBelonging;
import com.pmease.gitop.core.permission.operation.RepositoryOperation; import com.pmease.gitop.core.permission.operation.GeneralOperation;
/** /**
* This class represents either a project or an user in the system. * This class represents either a project or an user in the system.
* <p> * <p>
* In Gitop, users and projects are the same thing. * In Gitop, users and projects are the same thing.
* If necessary, you can always treat an user account as a project account. * If necessary, you can always treat an user account as a project account.
* {@link Repository} and {@link Team} are always created under a specific account. * {@link Project} and {@link Team} are always created under a specific account.
* *
* @author robin * @author robin
* *
@ -43,17 +43,16 @@ public class User extends AbstractUser implements ProtectedObject {
private String fullName; private String fullName;
@OneToMany(mappedBy="user") private boolean admin;
private Collection<TeamMembership> teamMemberships = new ArrayList<TeamMembership>();
@OneToMany(mappedBy="user") @OneToMany(mappedBy="user")
private Collection<RoleMembership> roleMemberships = new ArrayList<RoleMembership>(); private Collection<Membership> memberships = new ArrayList<Membership>();
@OneToMany(mappedBy="submitter") @OneToMany(mappedBy="submitter")
private Collection<MergeRequest> mergeRequests = new ArrayList<MergeRequest>(); private Collection<MergeRequest> mergeRequests = new ArrayList<MergeRequest>();
@OneToMany(mappedBy="owner") @OneToMany(mappedBy="owner")
private Collection<Repository> repositories = new ArrayList<Repository>(); private Collection<Project> repositories = new ArrayList<Project>();
@OneToMany(mappedBy="owner") @OneToMany(mappedBy="owner")
private Collection<Team> teams = new ArrayList<Team>(); private Collection<Team> teams = new ArrayList<Team>();
@ -64,18 +63,6 @@ public class User extends AbstractUser implements ProtectedObject {
@OneToMany(mappedBy="voter") @OneToMany(mappedBy="voter")
private Collection<VoteInvitation> voteVitations = new ArrayList<VoteInvitation>(); private Collection<VoteInvitation> voteVitations = new ArrayList<VoteInvitation>();
@OneToMany(mappedBy="individual")
private Collection<RepositoryAuthorizationByIndividual> repositoryAuthorizations =
new ArrayList<RepositoryAuthorizationByIndividual>();
@OneToMany(mappedBy="individual")
private Collection<UserAuthorizationByIndividual> userAuthorizations =
new ArrayList<UserAuthorizationByIndividual>();
@OneToMany(mappedBy="user")
private Collection<UserAuthorizationByIndividual> authorizationsByIndividual =
new ArrayList<UserAuthorizationByIndividual>();
@Editable(order=100) @Editable(order=100)
@NotEmpty @NotEmpty
@Override @Override
@ -111,27 +98,27 @@ public class User extends AbstractUser implements ProtectedObject {
return super.getPasswordHash(); return super.getPasswordHash();
} }
public Collection<TeamMembership> getTeamMemberships() { public boolean isAdmin() {
return teamMemberships; return admin;
} }
public void setTeamMemberships(Collection<TeamMembership> teamMemberships) { public void setAdmin(boolean admin) {
this.teamMemberships = teamMemberships; this.admin = admin;
} }
public Collection<RoleMembership> getRoleMemberships() { public Collection<Membership> getMemberships() {
return roleMemberships; return memberships;
} }
public void setRoleMemberships(Collection<RoleMembership> roleMemberships) { public void setMemberships(Collection<Membership> memberships) {
this.roleMemberships = roleMemberships; this.memberships = memberships;
} }
public Collection<Repository> getRepositories() { public Collection<Project> getRepositories() {
return repositories; return repositories;
} }
public void setRepositories(Collection<Repository> repositories) { public void setRepositories(Collection<Project> repositories) {
this.repositories = repositories; this.repositories = repositories;
} }
@ -175,33 +162,6 @@ public class User extends AbstractUser implements ProtectedObject {
this.voteVitations = voteVitations; this.voteVitations = voteVitations;
} }
public Collection<RepositoryAuthorizationByIndividual> getRepositoryAuthorizations() {
return repositoryAuthorizations;
}
public void setRepositoryAuthorizations(
Collection<RepositoryAuthorizationByIndividual> repositoryAuthorizations) {
this.repositoryAuthorizations = repositoryAuthorizations;
}
public Collection<UserAuthorizationByIndividual> getUserAuthorizations() {
return userAuthorizations;
}
public void setUserAuthorizations(
Collection<UserAuthorizationByIndividual> userAuthorizations) {
this.userAuthorizations = userAuthorizations;
}
public Collection<UserAuthorizationByIndividual> getAuthorizationsByIndividual() {
return authorizationsByIndividual;
}
public void setAuthorizationsByIndividual(
Collection<UserAuthorizationByIndividual> authorizationsByIndividual) {
this.authorizationsByIndividual = authorizationsByIndividual;
}
@Override @Override
public boolean has(ProtectedObject object) { public boolean has(ProtectedObject object) {
if (object instanceof User) { if (object instanceof User) {
@ -233,17 +193,21 @@ public class User extends AbstractUser implements ProtectedObject {
if (userId != 0L) { if (userId != 0L) {
return AppLoader.getInstance(UserManager.class).load(userId); return AppLoader.getInstance(UserManager.class).load(userId);
} else { } else {
User user = new User(); return anonymous();
user.setId(userId);
user.setName("Anonymous");
return user;
} }
} }
public static User anonymous() {
User user = new User();
user.setId(0L);
user.setName("Guest");
return user;
}
@Override @Override
public boolean implies(Permission permission) { public boolean implies(Permission permission) {
// Root user can do anything // Administrator can do anything
if (isRoot()) if (isRoot() || isAdmin())
return true; return true;
if (permission instanceof ObjectPermission) { if (permission instanceof ObjectPermission) {
@ -253,40 +217,22 @@ public class User extends AbstractUser implements ProtectedObject {
if (has(objectPermission.getObject())) if (has(objectPermission.getObject()))
return true; return true;
for (RepositoryAuthorizationByIndividual authorization: getRepositoryAuthorizations()) {
ObjectPermission repositoryPermission = new ObjectPermission(
authorization.getRepository(), authorization.getAuthorizedOperation());
if (repositoryPermission.implies(objectPermission))
return true;
}
for (UserAuthorizationByIndividual each: getUserAuthorizations()) {
ObjectPermission userPermission = new ObjectPermission(each.getUser(), each.getAuthorizedOperation());
if (userPermission.implies(objectPermission))
return true;
}
for (Team team: getTeams()) { for (Team team: getTeams()) {
if (team.implies(objectPermission)) if (team.implies(objectPermission))
return true; return true;
} }
for (RoleMembership each: getRoleMemberships()) { for (Project each: Gitop.getInstance(ProjectManager.class).query(null)) {
if (each.getRole().implies(objectPermission)) ObjectPermission projectPermission = new ObjectPermission(each, each.getDefaultAuthorizedOperation());
return true; if (projectPermission.implies(objectPermission))
}
for (Repository each: Gitop.getInstance(RepositoryManager.class).query(null)) {
ObjectPermission repositoryPermission = new ObjectPermission(each, each.getDefaultAuthorizedOperation());
if (repositoryPermission.implies(objectPermission))
return true; return true;
} }
} }
// check if is public access // check if is public access
for (Repository each: Gitop.getInstance(RepositoryManager.class).findPublic()) { for (Project each: Gitop.getInstance(ProjectManager.class).findPublic()) {
ObjectPermission repositoryPermission = new ObjectPermission(each, RepositoryOperation.READ); ObjectPermission projectPermission = new ObjectPermission(each, GeneralOperation.READ);
if (repositoryPermission.implies(objectPermission)) if (projectPermission.implies(objectPermission))
return true; return true;
} }
} }
@ -301,4 +247,11 @@ public class User extends AbstractUser implements ProtectedObject {
return getId() == 0L; return getId() == 0L;
} }
public String getDisplayName() {
if (getFullName() == null)
return getName();
else
return getFullName();
}
} }

View File

@ -1,53 +0,0 @@
package com.pmease.gitop.core.model;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import com.pmease.commons.hibernate.AbstractEntity;
import com.pmease.gitop.core.permission.operation.UserOperation;
@SuppressWarnings("serial")
@Entity
@Table(uniqueConstraints={
@UniqueConstraint(columnNames={"individual", "user"})
})
public class UserAuthorizationByIndividual extends AbstractEntity {
@ManyToOne
@JoinColumn(nullable=false)
private User individual;
@ManyToOne
@JoinColumn(nullable=false)
private User user;
private UserOperation authorizedOperation = UserOperation.READ;
public UserOperation getAuthorizedOperation() {
return authorizedOperation;
}
public void setAuthorizedOperation(UserOperation authorizedOperation) {
this.authorizedOperation = authorizedOperation;
}
public User getIndividual() {
return individual;
}
public void setIndividual(User individual) {
this.individual = individual;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}

View File

@ -1,24 +0,0 @@
package com.pmease.gitop.core.permission;
import com.pmease.gitop.core.permission.operation.PrivilegedOperation;
public class BranchPermission {
private final String branchNames;
private final PrivilegedOperation branchOperation;
public BranchPermission(String branchNames, PrivilegedOperation branchOperation) {
this.branchNames = branchNames;
this.branchOperation = branchOperation;
}
public String getBranchNames() {
return branchNames;
}
public PrivilegedOperation getBranchOperation() {
return branchOperation;
}
}

View File

@ -2,14 +2,11 @@ package com.pmease.gitop.core.permission;
import org.apache.shiro.authz.Permission; import org.apache.shiro.authz.Permission;
import com.pmease.gitop.core.model.Repository; import com.pmease.gitop.core.model.Project;
import com.pmease.gitop.core.model.User; import com.pmease.gitop.core.model.User;
import com.pmease.gitop.core.permission.object.ProtectedObject; import com.pmease.gitop.core.permission.object.ProtectedObject;
import com.pmease.gitop.core.permission.object.SystemObject; import com.pmease.gitop.core.permission.operation.GeneralOperation;
import com.pmease.gitop.core.permission.operation.PrivilegedOperation; import com.pmease.gitop.core.permission.operation.PrivilegedOperation;
import com.pmease.gitop.core.permission.operation.RepositoryOperation;
import com.pmease.gitop.core.permission.operation.SystemOperation;
import com.pmease.gitop.core.permission.operation.UserOperation;
/** /**
* This class represents permissions to operate an account and its belongings. * This class represents permissions to operate an account and its belongings.
@ -56,31 +53,27 @@ public class ObjectPermission implements Permission {
} }
public static ObjectPermission ofUserAdmin(User user) { public static ObjectPermission ofUserAdmin(User user) {
return new ObjectPermission(user, UserOperation.ADMINISTRATION); return new ObjectPermission(user, GeneralOperation.ADMINISTRATION);
} }
public static ObjectPermission ofUserRead(User user) { public static ObjectPermission ofUserRead(User user) {
return new ObjectPermission(user, UserOperation.READ); return new ObjectPermission(user, GeneralOperation.READ);
} }
public static ObjectPermission ofUserWrite(User user) { public static ObjectPermission ofUserWrite(User user) {
return new ObjectPermission(user, UserOperation.WRITE); return new ObjectPermission(user, GeneralOperation.WRITE);
} }
public static ObjectPermission ofRepositoryAdmin(Repository repository) { public static ObjectPermission ofProjectAdmin(Project project) {
return new ObjectPermission(repository, RepositoryOperation.ADMINISTRATION); return new ObjectPermission(project, GeneralOperation.ADMINISTRATION);
} }
public static ObjectPermission ofRepositoryRead(Repository repository) { public static ObjectPermission ofProjectRead(Project project) {
return new ObjectPermission(repository, RepositoryOperation.READ); return new ObjectPermission(project, GeneralOperation.READ);
} }
public static ObjectPermission ofRepositoryWrite(Repository repository) { public static ObjectPermission ofProjectWrite(Project project) {
return new ObjectPermission(repository, RepositoryOperation.WRITE); return new ObjectPermission(project, GeneralOperation.WRITE);
} }
public static ObjectPermission ofSystem(SystemOperation operation) {
return new ObjectPermission(new SystemObject(), operation);
}
} }

View File

@ -8,7 +8,6 @@ import org.apache.shiro.authc.credential.CredentialsMatcher;
import com.pmease.commons.hibernate.dao.GeneralDao; import com.pmease.commons.hibernate.dao.GeneralDao;
import com.pmease.commons.shiro.AbstractRealm; import com.pmease.commons.shiro.AbstractRealm;
import com.pmease.commons.shiro.AbstractUser; import com.pmease.commons.shiro.AbstractUser;
import com.pmease.gitop.core.manager.RoleManager;
import com.pmease.gitop.core.manager.TeamManager; import com.pmease.gitop.core.manager.TeamManager;
import com.pmease.gitop.core.manager.UserManager; import com.pmease.gitop.core.manager.UserManager;
import com.pmease.gitop.core.model.User; import com.pmease.gitop.core.model.User;
@ -20,7 +19,7 @@ public class UserRealm extends AbstractRealm {
@Inject @Inject
public UserRealm(GeneralDao generalDao, CredentialsMatcher credentialsMatcher, public UserRealm(GeneralDao generalDao, CredentialsMatcher credentialsMatcher,
UserManager userManager, RoleManager roleManager, TeamManager teamManager) { UserManager userManager, TeamManager teamManager) {
super(credentialsMatcher); super(credentialsMatcher);
this.userManager = userManager; this.userManager = userManager;
@ -31,9 +30,7 @@ public class UserRealm extends AbstractRealm {
if (userId != 0L) { if (userId != 0L) {
return userManager.load(userId); return userManager.load(userId);
} else { } else {
User user = new User(); return User.anonymous();
user.setId(0L);
return user;
} }
} }

View File

@ -1,10 +0,0 @@
package com.pmease.gitop.core.permission.object;
public class SystemObject implements ProtectedObject {
@Override
public boolean has(ProtectedObject object) {
return true;
}
}

View File

@ -0,0 +1,49 @@
package com.pmease.gitop.core.permission.operation;
public enum GeneralOperation implements PrivilegedOperation {
NO_ACCESS("No Access") {
@Override
public boolean can(PrivilegedOperation operation) {
return false;
}
},
READ("Read") {
@Override
public boolean can(PrivilegedOperation operation) {
return operation == READ;
}
},
WRITE("Write") {
@Override
public boolean can(PrivilegedOperation operation) {
return operation == WRITE || READ.can(operation);
}
},
ADMINISTRATION("Administration") {
@Override
public boolean can(PrivilegedOperation operation) {
return true;
}
};
private final String displayName;
GeneralOperation(String displayName) {
this.displayName = displayName;
}
@Override
public String toString() {
return displayName;
}
}

View File

@ -1,28 +0,0 @@
package com.pmease.gitop.core.permission.operation;
public enum RepositoryOperation implements PrivilegedOperation {
READ {
@Override
public boolean can(PrivilegedOperation operation) {
return operation == READ;
}
},
WRITE {
@Override
public boolean can(PrivilegedOperation operation) {
return operation == WRITE || READ.can(operation);
}
},
ADMINISTRATION {
@Override
public boolean can(PrivilegedOperation operation) {
return true;
}
}
}

View File

@ -8,14 +8,6 @@ public enum SystemOperation implements PrivilegedOperation {
return true; return true;
} }
},
VOTE {
@Override
public boolean can(PrivilegedOperation operation) {
return operation == VOTE;
}
}, },
ADD_COMMENT { ADD_COMMENT {
@ -24,6 +16,14 @@ public enum SystemOperation implements PrivilegedOperation {
return operation == ADD_COMMENT; return operation == ADD_COMMENT;
} }
},
CREATE_PROJECT {
@Override
public boolean can(PrivilegedOperation operation) {
return operation == CREATE_PROJECT;
}
}, },
CREATE_MERGE_REQUEST { CREATE_MERGE_REQUEST {
@ -32,31 +32,5 @@ public enum SystemOperation implements PrivilegedOperation {
return operation == CREATE_MERGE_REQUEST; 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 || RepositoryOperation.READ.can(operation);
}
},
WRITE_ALL_REPOSITORIES {
@Override
public boolean can(PrivilegedOperation operation) {
return operation == WRITE_ALL_REPOSITORIES
|| READ_ALL_REPOSITORIES.can(operation)
|| RepositoryOperation.WRITE.can(operation);
}
} }
} }

View File

@ -1,28 +0,0 @@
package com.pmease.gitop.core.permission.operation;
public enum UserOperation implements PrivilegedOperation {
READ {
@Override
public boolean can(PrivilegedOperation operation) {
return operation == READ || RepositoryOperation.READ.can(operation);
}
},
WRITE {
@Override
public boolean can(PrivilegedOperation operation) {
return operation == WRITE || READ.can(operation) || RepositoryOperation.WRITE.can(operation);
}
},
ADMINISTRATION {
@Override
public boolean can(PrivilegedOperation operation) {
return true;
}
}
}

View File

@ -10,16 +10,16 @@ import com.pmease.commons.editable.annotation.Editable;
@Editable @Editable
public class StorageSetting implements Serializable { public class StorageSetting implements Serializable {
private String repoStorageDir; private String storageDir;
@Editable @Editable
@NotEmpty @NotEmpty
public String getRepoStorageDir() { public String getStorageDir() {
return repoStorageDir; return storageDir;
} }
public void setRepoStorageDir(String repoStorageDir) { public void setStorageDir(String storageDir) {
this.repoStorageDir = repoStorageDir; this.storageDir = storageDir;
} }
} }

View File

@ -4,11 +4,11 @@ import java.io.File;
import com.pmease.commons.util.FileUtils; import com.pmease.commons.util.FileUtils;
public class RepositoryStorage { public class ProjectStorage {
private final File storageDir; private final File storageDir;
public RepositoryStorage(File storageDir) { public ProjectStorage(File storageDir) {
this.storageDir = storageDir; this.storageDir = storageDir;
} }

View File

@ -5,9 +5,9 @@ import org.apache.wicket.markup.html.form.Form;
import com.pmease.commons.editable.EditContext; import com.pmease.commons.editable.EditContext;
import com.pmease.commons.wicket.editable.EditHelper; import com.pmease.commons.wicket.editable.EditHelper;
import com.pmease.gitop.core.Gitop; import com.pmease.gitop.core.Gitop;
import com.pmease.gitop.core.manager.RepositoryManager; import com.pmease.gitop.core.manager.ProjectManager;
import com.pmease.gitop.core.manager.UserManager; import com.pmease.gitop.core.manager.UserManager;
import com.pmease.gitop.core.model.Repository; import com.pmease.gitop.core.model.Project;
@SuppressWarnings("serial") @SuppressWarnings("serial")
public class TestPage extends BasePage { public class TestPage extends BasePage {
@ -16,7 +16,7 @@ public class TestPage extends BasePage {
protected void onInitialize() { protected void onInitialize() {
super.onInitialize(); super.onInitialize();
final EditContext editContext = EditHelper.getContext(new Repository()); final EditContext editContext = EditHelper.getContext(new Project());
Form<?> form = new Form<Void>("form") { Form<?> form = new Form<Void>("form") {
@ -25,9 +25,9 @@ public class TestPage extends BasePage {
super.onSubmit(); super.onSubmit();
editContext.validate(); editContext.validate();
if (!editContext.hasValidationError(true)) { if (!editContext.hasValidationError(true)) {
Repository repository = (Repository) editContext.getBean(); Project project = (Project) editContext.getBean();
repository.setOwner(Gitop.getInstance(UserManager.class).getRootUser()); project.setOwner(Gitop.getInstance(UserManager.class).getRootUser());
Gitop.getInstance(RepositoryManager.class).save(repository); Gitop.getInstance(ProjectManager.class).save(project);
} }
} }