Commit 83589b63 authored by Martin Lowe's avatar Martin Lowe 🇨🇦 Committed by Christopher Guindon
Browse files

Fixed retrieval of repos based on different providers + hook updates



Updated rb hook for gitlab to use production endpoint since it is live.
Added gitlab + github repo members of the Project object. RElies on
changes that are currently in staging. Changed logic for retrieving
projects to contextually change where it looks for repositories based on
the request provider.
Signed-off-by: Martin Lowe's avatarMartin Lowe <martin.lowe@eclipse-foundation.org>
parent 5be4fb4e
......@@ -30,11 +30,15 @@ public class Project {
private String name;
private List<User> committers;
private List<Repo> repos;
private List<Repo> gitlabRepos;
private List<Repo> githubRepos;
private String specWorkingGroup;
public Project() {
this.committers = new ArrayList<>();
this.repos = new ArrayList<>();
this.gitlabRepos = new ArrayList<>();
this.githubRepos = new ArrayList<>();
}
/**
......@@ -83,14 +87,42 @@ public class Project {
* @return the repos
*/
public List<Repo> getRepos() {
return repos;
return new ArrayList<>(repos);
}
/**
* @param repos the repos to set
*/
public void setRepos(List<Repo> repos) {
this.repos = repos;
this.repos = new ArrayList<>(repos);
}
/**
* @return the gitlabRepos
*/
public List<Repo> getGitlabRepos() {
return new ArrayList<>(gitlabRepos);
}
/**
* @param githubRepos the githubRepos to set
*/
public void setGithubRepos(List<Repo> githubRepos) {
this.githubRepos = new ArrayList<>(githubRepos);
}
/**
* @return the gitlabRepos
*/
public List<Repo> getGithubRepos() {
return new ArrayList<>(githubRepos);
}
/**
* @param gitlabRepos the gitlabRepos to set
*/
public void setGitlabRepos(List<Repo> gitlabRepos) {
this.gitlabRepos = new ArrayList<>(gitlabRepos);
}
/**
......
......@@ -9,6 +9,7 @@
******************************************************************************/
package org.eclipsefoundation.git.eca.resource;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
......@@ -35,6 +36,7 @@ import org.eclipsefoundation.git.eca.model.Project;
import org.eclipsefoundation.git.eca.model.ValidationRequest;
import org.eclipsefoundation.git.eca.model.ValidationResponse;
import org.eclipsefoundation.git.eca.namespace.APIStatusCode;
import org.eclipsefoundation.git.eca.namespace.ProviderType;
import org.eclipsefoundation.git.eca.service.CachingService;
import org.eclipsefoundation.git.eca.service.OAuthService;
import org.slf4j.Logger;
......@@ -172,11 +174,10 @@ public class ValidationResource {
return true;
}
// validate author access to the current repo
validateAuthorAccess(response, c, eclipseAuthor, request.getRepoUrl());
validateAuthorAccess(response, c, eclipseAuthor, request);
// only committers can push on behalf of other users
if (!eclipseAuthor.equals(eclipseCommitter)
&& !isCommitter(response, eclipseCommitter, c.getHash(), request.getRepoUrl())) {
if (!eclipseAuthor.equals(eclipseCommitter) && !isCommitter(response, eclipseCommitter, c.getHash(), request)) {
addMessage(response, "You are not a project committer.", c.getHash());
addMessage(response, "Only project committers can push on behalf of others.", c.getHash());
addError(response, "You must be a committer to push on behalf of others.", c.getHash());
......@@ -195,9 +196,11 @@ public class ValidationResource {
* @param repoUrl repo URL for the current commit set, to be used when
* checking projects
*/
private void validateAuthorAccess(ValidationResponse r, Commit c, EclipseUser eclipseAuthor, String repoUrl) {
private void validateAuthorAccess(ValidationResponse r, Commit c, EclipseUser eclipseAuthor,
ValidationRequest req) {
// check if the author matches to an eclipse user and is a committer
if (isCommitter(r, eclipseAuthor, c.getHash(), repoUrl)) {
if (isCommitter(r, eclipseAuthor, c.getHash(), req)) {
addMessage(r, "The author is a committer on the project.", c.getHash());
} else {
addMessage(r, "The author is not a committer on the project.", c.getHash());
......@@ -243,20 +246,10 @@ public class ValidationResource {
* projects
* @return true if user is considered a committer, false otherwise.
*/
private boolean isCommitter(ValidationResponse r, EclipseUser user, String hash, String repoUrl) {
// check for all projects that make use of the given repo
@SuppressWarnings("unchecked")
Optional<List<Project>> cachedProjects = cache.get("projects|" + repoUrl, () -> projects.getProject(),
(Class<List<Project>>) (Object) List.class);
if (!cachedProjects.isPresent() || cachedProjects.get().isEmpty()) {
return false;
}
private boolean isCommitter(ValidationResponse r, EclipseUser user, String hash, ValidationRequest req) {
// filter the projects based on the repo URL. At least one repo in project must
// match the repo URL to be valid
List<Project> filteredProjects = cachedProjects.get().stream()
.filter(p -> p.getRepos().stream().anyMatch(re -> re.getUrl().equals(repoUrl)))
.collect(Collectors.toList());
List<Project> filteredProjects = retrieveProjectsForRequest(req);
// iterate over filtered projects
for (Project p : filteredProjects) {
......@@ -300,6 +293,41 @@ public class ValidationResource {
return false;
}
/**
* Retrieves projects valid for the current request, or an empty list if no data
* or matching project repos could be found.
*
* @param req the current request
* @return list of matching projects for the current request, or an empty list
* if none found.
*/
private List<Project> retrieveProjectsForRequest(ValidationRequest req) {
String repoUrl = req.getRepoUrl();
// check for all projects that make use of the given repo
@SuppressWarnings("unchecked")
Optional<List<Project>> cachedProjects = cache.get("projects", () -> projects.getProject(),
(Class<List<Project>>) (Object) List.class);
if (!cachedProjects.isPresent() || cachedProjects.get().isEmpty()) {
return Collections.emptyList();
}
// filter the projects based on the repo URL. At least one repo in project must
// match the repo URL to be valid
if (ProviderType.GITLAB.equals(req.getProvider())) {
return cachedProjects.get().stream()
.filter(p -> p.getGitlabRepos().stream().anyMatch(re -> re.getUrl().equals(repoUrl)))
.collect(Collectors.toList());
} else if (ProviderType.GITHUB.equals(req.getProvider())) {
return cachedProjects.get().stream()
.filter(p -> p.getGithubRepos().stream().anyMatch(re -> re.getUrl().equals(repoUrl)))
.collect(Collectors.toList());
} else {
return cachedProjects.get().stream()
.filter(p -> p.getRepos().stream().anyMatch(re -> re.getUrl().equals(repoUrl)))
.collect(Collectors.toList());
}
}
/**
* Retrieves an Eclipse Account user object given the Git users email address
* (at minimum). This is facilitated using the Eclipse Foundation accounts API,
......
......@@ -51,7 +51,7 @@ json_data = {
:commits => processed_git_data
}
## Generate request
response = HTTParty.post("http://172.21.0.1:8083/git/eca", :body => MultiJson.dump(json_data), :headers => { 'Content-Type' => 'application/json' })
response = HTTParty.post("https://api.eclipse.org/git/eca", :body => MultiJson.dump(json_data), :headers => { 'Content-Type' => 'application/json' })
## convert request to hash map
parsed_response = MultiJson.load(response.body)
......
......@@ -58,7 +58,7 @@ public class MockProjectsAPI implements ProjectsAPI {
p1.setName("Sample project");
p1.setProjectId("sample.proj");
p1.setSpecWorkingGroup(null);
p1.setRepos(Arrays.asList(r1, r2));
p1.setGithubRepos(Arrays.asList(r1, r2));
p1.setCommitters(Arrays.asList(u1, u2));
src.add(p1);
......@@ -66,7 +66,7 @@ public class MockProjectsAPI implements ProjectsAPI {
p2.setName("Prototype thing");
p2.setProjectId("sample.proto");
p2.setSpecWorkingGroup(null);
p2.setRepos(Arrays.asList(r3));
p2.setGithubRepos(Arrays.asList(r3));
p2.setCommitters(Arrays.asList(u2));
src.add(p2);
......@@ -74,7 +74,7 @@ public class MockProjectsAPI implements ProjectsAPI {
p3.setName("Spec project");
p3.setProjectId("spec.proj");
p3.setSpecWorkingGroup("proj1");
p3.setRepos(Arrays.asList(r4));
p3.setGithubRepos(Arrays.asList(r4));
p3.setCommitters(Arrays.asList(u1, u2));
src.add(p3);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment