use of com.google.gerrit.server.project.ProjectControl in project gerrit by GerritCodeReview.
the class AdminSetParent method run.
@Override
protected void run() throws Failure {
if (oldParent == null && children.isEmpty()) {
throw die("child projects have to be specified as " + "arguments or the --children-of option has to be set");
}
if (oldParent == null && !excludedChildren.isEmpty()) {
throw die("--exclude can only be used together with --children-of");
}
final StringBuilder err = new StringBuilder();
final Set<Project.NameKey> grandParents = new HashSet<>();
grandParents.add(allProjectsName);
if (newParent != null) {
newParentKey = newParent.getProject().getNameKey();
// Catalog all grandparents of the "parent", we want to
// catch a cycle in the parent pointers before it occurs.
//
Project.NameKey gp = newParent.getProject().getParent();
while (gp != null && grandParents.add(gp)) {
final ProjectState s = projectCache.get(gp);
if (s != null) {
gp = s.getProject().getParent();
} else {
break;
}
}
}
final List<Project.NameKey> childProjects = new ArrayList<>();
for (final ProjectControl pc : children) {
childProjects.add(pc.getProject().getNameKey());
}
if (oldParent != null) {
try {
childProjects.addAll(getChildrenForReparenting(oldParent));
} catch (PermissionBackendException e) {
throw new Failure(1, "permissions unavailable", e);
}
}
for (final Project.NameKey nameKey : childProjects) {
final String name = nameKey.get();
if (allProjectsName.equals(nameKey)) {
// Don't allow the wild card project to have a parent.
//
err.append("error: Cannot set parent of '").append(name).append("'\n");
continue;
}
if (grandParents.contains(nameKey) || nameKey.equals(newParentKey)) {
// Try to avoid creating a cycle in the parent pointers.
//
err.append("error: Cycle exists between '").append(name).append("' and '").append(newParentKey != null ? newParentKey.get() : allProjectsName.get()).append("'\n");
continue;
}
try (MetaDataUpdate md = metaDataUpdateFactory.create(nameKey)) {
ProjectConfig config = ProjectConfig.read(md);
config.getProject().setParentName(newParentKey);
md.setMessage("Inherit access from " + (newParentKey != null ? newParentKey.get() : allProjectsName.get()) + "\n");
config.commit(md);
} catch (RepositoryNotFoundException notFound) {
err.append("error: Project ").append(name).append(" not found\n");
} catch (IOException | ConfigInvalidException e) {
final String msg = "Cannot update project " + name;
log.error(msg, e);
err.append("error: ").append(msg).append("\n");
}
projectCache.evict(nameKey);
}
if (err.length() > 0) {
while (err.charAt(err.length() - 1) == '\n') {
err.setLength(err.length() - 1);
}
throw die(err.toString());
}
}
use of com.google.gerrit.server.project.ProjectControl in project gerrit by GerritCodeReview.
the class GarbageCollectionCommand method runGC.
private void runGC() {
List<Project.NameKey> projectNames;
if (all) {
projectNames = Lists.newArrayList(projectCache.all());
} else {
projectNames = Lists.newArrayListWithCapacity(projects.size());
for (ProjectControl pc : projects) {
projectNames.add(pc.getProject().getNameKey());
}
}
GarbageCollectionResult result = garbageCollectionFactory.create().run(projectNames, aggressive, showProgress ? stdout : null);
if (result.hasErrors()) {
for (GarbageCollectionResult.Error e : result.getErrors()) {
String msg;
switch(e.getType()) {
case REPOSITORY_NOT_FOUND:
msg = "error: project \"" + e.getProjectName() + "\" not found";
break;
case GC_ALREADY_SCHEDULED:
msg = "error: garbage collection for project \"" + e.getProjectName() + "\" was already scheduled";
break;
case GC_FAILED:
msg = "error: garbage collection for project \"" + e.getProjectName() + "\" failed";
break;
default:
msg = "error: garbage collection for project \"" + e.getProjectName() + "\" failed: " + e.getType();
}
stdout.print(msg + "\n");
}
}
}
use of com.google.gerrit.server.project.ProjectControl in project gerrit by GerritCodeReview.
the class ProjectAccessFactory method call.
@Override
public ProjectAccess call() throws NoSuchProjectException, IOException, ConfigInvalidException, PermissionBackendException {
ProjectControl pc = checkProjectControl();
// Load the current configuration from the repository, ensuring its the most
// recent version available. If it differs from what was in the project
// state, force a cache flush now.
//
ProjectConfig config;
try (MetaDataUpdate md = metaDataUpdateFactory.create(projectName)) {
config = ProjectConfig.read(md);
if (config.updateGroupNames(groupBackend)) {
md.setMessage("Update group names\n");
config.commit(md);
projectCache.evict(config.getProject());
pc = checkProjectControl();
} else if (config.getRevision() != null && !config.getRevision().equals(pc.getProjectState().getConfig().getRevision())) {
projectCache.evict(config.getProject());
pc = checkProjectControl();
}
}
final RefControl metaConfigControl = pc.controlForRef(RefNames.REFS_CONFIG);
List<AccessSection> local = new ArrayList<>();
Set<String> ownerOf = new HashSet<>();
Map<AccountGroup.UUID, Boolean> visibleGroups = new HashMap<>();
for (AccessSection section : config.getAccessSections()) {
String name = section.getName();
if (AccessSection.GLOBAL_CAPABILITIES.equals(name)) {
if (pc.isOwner()) {
local.add(section);
ownerOf.add(name);
} else if (metaConfigControl.isVisible()) {
local.add(section);
}
} else if (RefConfigSection.isValid(name)) {
RefControl rc = pc.controlForRef(name);
if (rc.isOwner()) {
local.add(section);
ownerOf.add(name);
} else if (metaConfigControl.isVisible()) {
local.add(section);
} else if (rc.isVisible()) {
// Filter the section to only add rules describing groups that
// are visible to the current-user. This includes any group the
// user is a member of, as well as groups they own or that
// are visible to all users.
AccessSection dst = null;
for (Permission srcPerm : section.getPermissions()) {
Permission dstPerm = null;
for (PermissionRule srcRule : srcPerm.getRules()) {
AccountGroup.UUID group = srcRule.getGroup().getUUID();
if (group == null) {
continue;
}
Boolean canSeeGroup = visibleGroups.get(group);
if (canSeeGroup == null) {
try {
canSeeGroup = groupControlFactory.controlFor(group).isVisible();
} catch (NoSuchGroupException e) {
canSeeGroup = Boolean.FALSE;
}
visibleGroups.put(group, canSeeGroup);
}
if (canSeeGroup) {
if (dstPerm == null) {
if (dst == null) {
dst = new AccessSection(name);
local.add(dst);
}
dstPerm = dst.getPermission(srcPerm.getName(), true);
}
dstPerm.add(srcRule);
}
}
}
}
}
}
if (ownerOf.isEmpty() && pc.isOwnerAnyRef()) {
// Special case: If the section list is empty, this project has no current
// access control information. Rely on what ProjectControl determines
// is ownership, which probably means falling back to site administrators.
ownerOf.add(AccessSection.ALL);
}
final ProjectAccess detail = new ProjectAccess();
detail.setProjectName(projectName);
if (config.getRevision() != null) {
detail.setRevision(config.getRevision().name());
}
detail.setInheritsFrom(config.getProject().getParent(allProjectsName));
if (projectName.equals(allProjectsName)) {
if (pc.isOwner()) {
ownerOf.add(AccessSection.GLOBAL_CAPABILITIES);
}
}
detail.setLocal(local);
detail.setOwnerOf(ownerOf);
detail.setCanUpload(metaConfigControl.isVisible() && (pc.isOwner() || metaConfigControl.canUpload()));
detail.setConfigVisible(pc.isOwner() || metaConfigControl.isVisible());
detail.setGroupInfo(buildGroupInfo(local));
detail.setLabelTypes(pc.getLabelTypes());
detail.setFileHistoryLinks(getConfigFileLogLinks(projectName.get()));
return detail;
}
use of com.google.gerrit.server.project.ProjectControl in project gerrit by GerritCodeReview.
the class CreateMergePatchSet method applyImpl.
@Override
protected Response<ChangeInfo> applyImpl(BatchUpdate.Factory updateFactory, ChangeResource rsrc, MergePatchSetInput in) throws OrmException, IOException, InvalidChangeOperationException, RestApiException, UpdateException, PermissionBackendException {
rsrc.permissions().database(db).check(ChangePermission.ADD_PATCH_SET);
MergeInput merge = in.merge;
if (merge == null || Strings.isNullOrEmpty(merge.source)) {
throw new BadRequestException("merge.source must be non-empty");
}
ChangeControl ctl = rsrc.getControl();
PatchSet ps = psUtil.current(db.get(), ctl.getNotes());
ProjectControl projectControl = ctl.getProjectControl();
Change change = ctl.getChange();
Project.NameKey project = change.getProject();
Branch.NameKey dest = change.getDest();
try (Repository git = gitManager.openRepository(project);
ObjectInserter oi = git.newObjectInserter();
ObjectReader reader = oi.newReader();
RevWalk rw = new RevWalk(reader)) {
RevCommit sourceCommit = MergeUtil.resolveCommit(git, rw, merge.source);
if (!projectControl.canReadCommit(db.get(), git, sourceCommit)) {
throw new ResourceNotFoundException("cannot find source commit: " + merge.source + " to merge.");
}
RevCommit currentPsCommit = rw.parseCommit(ObjectId.fromString(ps.getRevision().get()));
Timestamp now = TimeUtil.nowTs();
IdentifiedUser me = user.get().asIdentifiedUser();
PersonIdent author = me.newCommitterIdent(now, serverTimeZone);
RevCommit newCommit = createMergeCommit(in, projectControl, dest, git, oi, rw, currentPsCommit, sourceCommit, author, ObjectId.fromString(change.getKey().get().substring(1)));
PatchSet.Id nextPsId = ChangeUtil.nextPatchSetId(ps.getId());
PatchSetInserter psInserter = patchSetInserterFactory.create(ctl, nextPsId, newCommit);
try (BatchUpdate bu = updateFactory.create(db.get(), project, me, now)) {
bu.setRepository(git, rw, oi);
bu.addOp(ctl.getId(), psInserter.setMessage("Uploaded patch set " + nextPsId.get() + ".").setDraft(ps.isDraft()).setNotify(NotifyHandling.NONE).setCheckAddPatchSetPermission(false));
bu.execute();
}
ChangeJson json = jsonFactory.create(ListChangesOption.CURRENT_REVISION);
return Response.ok(json.format(psInserter.getChange()));
}
}
use of com.google.gerrit.server.project.ProjectControl in project gerrit by GerritCodeReview.
the class CherryPick method applyImpl.
@Override
protected ChangeInfo applyImpl(BatchUpdate.Factory updateFactory, RevisionResource revision, CherryPickInput input) throws OrmException, IOException, UpdateException, RestApiException {
final ChangeControl control = revision.getControl();
input.parent = input.parent == null ? 1 : input.parent;
if (input.message == null || input.message.trim().isEmpty()) {
throw new BadRequestException("message must be non-empty");
} else if (input.destination == null || input.destination.trim().isEmpty()) {
throw new BadRequestException("destination must be non-empty");
}
if (!control.isVisible(dbProvider.get())) {
throw new AuthException("Cherry pick not permitted");
}
ProjectControl projectControl = control.getProjectControl();
Capable capable = projectControl.canPushToAtLeastOneRef();
if (capable != Capable.OK) {
throw new AuthException(capable.getMessage());
}
String refName = RefNames.fullName(input.destination);
RefControl refControl = projectControl.controlForRef(refName);
if (!refControl.canUpload()) {
throw new AuthException("Not allowed to cherry pick " + revision.getChange().getId().toString() + " to " + input.destination);
}
try {
Change.Id cherryPickedChangeId = cherryPickChange.cherryPick(updateFactory, revision.getChange(), revision.getPatchSet(), input, refName, refControl);
return json.noOptions().format(revision.getProject(), cherryPickedChangeId);
} catch (InvalidChangeOperationException e) {
throw new BadRequestException(e.getMessage());
} catch (IntegrationException | NoSuchChangeException e) {
throw new ResourceConflictException(e.getMessage());
}
}
Aggregations