com.capitalone.dashboard.webhook.github.GitHubV3 Maven / Gradle / Ivy
package com.capitalone.dashboard.webhook.github;
import com.capitalone.dashboard.model.AuthType;
import com.capitalone.dashboard.model.GitHubCollector;
import com.capitalone.dashboard.model.UserEntitlements;
import com.capitalone.dashboard.repository.BaseCollectorRepository;
import com.capitalone.dashboard.repository.CollectorItemRepository;
import com.capitalone.dashboard.model.webhook.github.GitHubRepo;
import com.capitalone.dashboard.repository.UserEntitlementsRepository;
import com.capitalone.dashboard.settings.ApiSettings;
import com.capitalone.dashboard.client.RestClient;
import com.capitalone.dashboard.model.webhook.github.GitHubParsed;
import com.capitalone.dashboard.misc.HygieiaException;
import com.capitalone.dashboard.model.CollectorItem;
import com.capitalone.dashboard.model.CollectorType;
import com.capitalone.dashboard.service.CollectorService;
import com.capitalone.dashboard.util.HygieiaUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.bson.types.ObjectId;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.ParseException;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.ResourceAccessException;
import org.springframework.web.client.RestClientException;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public abstract class GitHubV3 {
private static final Log LOG = LogFactory.getLog(GitHubV3.class);
private static final String REPO_URL = "url";
private static final String BRANCH = "branch";
private static final String USER_ID = "userID";
private static final String PASSWORD = "password";
private static final String TOKEN = "personalAccessToken";
protected final CollectorService collectorService;
protected final RestClient restClient;
protected final ApiSettings apiSettings;
protected final CollectorItemRepository collectorItemRepository;
private final BaseCollectorRepository collectorRepository;
private UserEntitlementsRepository userEntitlementsRepository;
private static final String ENTITLEMENT_TYPE = "distinguishedName";
private Map authorTypeMap;
private Map ldapMap;
public GitHubV3(CollectorService collectorService,
RestClient restClient,
ApiSettings apiSettings,
CollectorItemRepository collectorItemRepository,
UserEntitlementsRepository userEntitlementsRepository,
BaseCollectorRepository collectorRepository
) {
this.collectorService = collectorService;
this.restClient = restClient;
this.apiSettings = apiSettings;
this.collectorItemRepository = collectorItemRepository;
this.collectorRepository = collectorRepository;
ldapMap = new HashMap<>();
authorTypeMap = new HashMap<>();
this.userEntitlementsRepository = userEntitlementsRepository;
}
public GitHubCollector getCollector() {
GitHubCollector existingCollector = null;
/**
* ClassCastException maybe happen when first migrating from collector to Github collector, once we run the collector
* the data will get updated
*/
try {
existingCollector = collectorRepository.findByName("GitHub");
} catch (ClassCastException ignore) {}
if (existingCollector != null ) {
return existingCollector;
}
GitHubCollector protoType = new GitHubCollector();
protoType.setName("GitHub");
protoType.setCollectorType(CollectorType.SCM);
protoType.setOnline(true);
protoType.setEnabled(true);
Map allOptions = new HashMap<>();
allOptions.put(GitHubRepo.REPO_URL, "");
allOptions.put(GitHubRepo.BRANCH, "");
allOptions.put(GitHubRepo.USER_ID, "");
allOptions.put(GitHubRepo.PASSWORD, "");
allOptions.put(GitHubRepo.PERSONAL_ACCESS_TOKEN, "");
allOptions.put(GitHubRepo.TYPE, "");
protoType.setAllFields(allOptions);
Map uniqueOptions = new HashMap<>();
uniqueOptions.put(GitHubRepo.REPO_URL, "");
uniqueOptions.put(GitHubRepo.BRANCH, "");
protoType.setUniqueFields(uniqueOptions);
return collectorRepository.save(protoType);
}
public abstract String process(JSONObject jsonObject) throws MalformedURLException, HygieiaException, ParseException;
public abstract CollectorItemRepository getCollectorItemRepository();
protected CollectorItem buildCollectorItem (ObjectId collectorId, String repoUrl, String branch) {
if (HygieiaUtils.checkForEmptyStringValues(repoUrl, branch)) { return null; }
CollectorItem collectorItem = new CollectorItem();
collectorItem.setCollectorId(collectorId);
collectorItem.setEnabled(true);
collectorItem.setPushed(true);
collectorItem.setLastUpdated(System.currentTimeMillis());
collectorItem.getOptions().put(REPO_URL, repoUrl);
collectorItem.getOptions().put(BRANCH, branch);
return collectorItem;
}
private boolean checkForEmptyStringValues(String ... values) {
for (String value: values) {
if (StringUtils.isEmpty(value)) { return true; }
}
return false;
}
protected CollectorItem getCollectorItem(String repoUrl, String branch) throws HygieiaException {
GitHubCollector col = getCollector();
if (col == null)
throw new HygieiaException("Failed creating collector.", HygieiaException.COLLECTOR_CREATE_ERROR);
CollectorItem item = collectorItemRepository.findRepoByUrlAndBranch(col.getId(), repoUrl, branch);
if (item != null)
return item;
item = buildCollectorItem(col.getId(), repoUrl, branch);
if (item == null)
throw new HygieiaException("Failed creating collector item. Invalid repo url and/or branch", HygieiaException.COLLECTOR_ITEM_CREATE_ERROR);
CollectorItem colItem = collectorService.createCollectorItem(item);
if (colItem == null)
throw new HygieiaException("Failed creating collector item.", HygieiaException.COLLECTOR_ITEM_CREATE_ERROR);
return colItem;
}
// Update lastUpdated field in collector item
protected void updateCollectorItemLastUpdated(String repoUrl, String branch) throws HygieiaException {
CollectorItem item = getCollectorItem(repoUrl, branch);
item.setLastUpdated(System.currentTimeMillis());
collectorItemRepository.save(item);
}
protected String getRepositoryToken(String scmUrl) {
GitHubCollector collector = getCollector();
List collectorIdList = new ArrayList<>();
collectorIdList.add(collector.getId());
Iterable collectorItemIterable
= getCollectorItemRepository().findAllByOptionNameValueAndCollectorIdsIn(REPO_URL, scmUrl, collectorIdList);
if (collectorItemIterable == null) { return null; }
String tokenValue = null;
for (CollectorItem collectorItem : collectorItemIterable) {
String collectorItemTokenValue = String.valueOf(collectorItem.getOptions().get(TOKEN));
if (!StringUtils.isEmpty(collectorItemTokenValue)
&& !"null".equalsIgnoreCase(collectorItemTokenValue)) {
tokenValue = collectorItemTokenValue;
break;
}
}
return tokenValue;
}
protected void getUser(String repoUrl, String user, String token) {
if (StringUtils.isEmpty(user)) return;
// This is weird. Github does replace the _ in commit author with - in the user api!!!
String formattedUser = user.replace("_", "-");
int retryCount = 0;
ResponseEntity response;
if(apiSettings.isOptimizeUserCallsToGithub()) {
UserEntitlements entitlements = userEntitlementsRepository.findTopByAuthTypeAndEntitlementTypeAndUsername(AuthType.LDAP,
ENTITLEMENT_TYPE, StringUtils.lowerCase(user));
String ldapDN = (entitlements == null) ? "" : entitlements.getEntitlements();
ldapMap.put(user, ldapDN);
authorTypeMap.put(user, "User");
return;
}
while(true) {
try {
long start = System.currentTimeMillis();
GitHubParsed gitHubParsed = new GitHubParsed(repoUrl);
String apiUrl = gitHubParsed.getBaseApiUrl();
String queryUrl = apiUrl.concat("users/").concat(formattedUser);
response = restClient.makeRestCallGet(queryUrl, "token", token);
JSONObject userJson = restClient.parseAsObject(response);
String ldapDN = restClient.getString(userJson, "ldap_dn");
String authorTypeStr = restClient.getString(userJson, "type");
if (StringUtils.isNotEmpty(ldapDN)) {
ldapMap.put(user, ldapDN);
}
if (StringUtils.isNotEmpty(authorTypeStr)) {
authorTypeMap.put(user, authorTypeStr);
}
long end = System.currentTimeMillis();
LOG.info("Time to make the LDAP call = "+(end-start));
return;
} catch (ResourceAccessException e) {
retryCount++;
if (retryCount > apiSettings.getWebHook().getGitHub().getMaxRetries()) {
LOG.error("Error getting LDAP_DN For user " + user + " after " + apiSettings.getWebHook().getGitHub().getMaxRetries() + " tries.", e);
return;
}
} catch (MalformedURLException | HygieiaException | ParseException | RestClientException e) {
LOG.error("LDAP user not found " + user, e);
return;
}
}
}
protected String getLDAPDN(String repoUrl, String user, String token) {
if (StringUtils.isEmpty(user) || "unknown".equalsIgnoreCase(user)) return null;
if (ldapMap == null) { ldapMap = new HashMap<>(); }
if(apiSettings.isOptimizeUserCallsToGithub()) {
return ldapMap.get(user);
}
//This is weird. Github does replace the _ in commit author with - in the user api!!!
String formattedUser = user.replace("_", "-");
if(ldapMap.containsKey(formattedUser)) {
return ldapMap.get(formattedUser);
}
this.getUser(repoUrl, formattedUser, token);
return ldapMap.get(formattedUser);
}
protected String getAuthorType(String repoUrl, String user, String token) {
if (StringUtils.isEmpty(user) || "unknown".equalsIgnoreCase(user)) return null;
if (authorTypeMap == null) { authorTypeMap = new HashMap<>(); }
//This is weird. Github does replace the _ in commit author with - in the user api!!!
String formattedUser = user.replace("_", "-");
if(authorTypeMap.containsKey(formattedUser)) {
return authorTypeMap.get(formattedUser);
}
this.getUser(repoUrl, formattedUser, token);
return authorTypeMap.get(formattedUser);
}
protected void checkForErrors(JSONObject responseJsonObject) throws HygieiaException, ParseException {
JSONArray errors = restClient.getArray(responseJsonObject, "errors");
if (!CollectionUtils.isEmpty(errors)) {
throw new HygieiaException("Error in GraphQL query:" + errors.toJSONString(), HygieiaException.JSON_FORMAT_ERROR);
}
}
protected boolean isRegistered(String repoUrl, String branch) throws HygieiaException{
GitHubCollector col = getCollector();
if (col == null)
throw new HygieiaException("Failed creating collector.", HygieiaException.COLLECTOR_CREATE_ERROR);
CollectorItem existingItem = getCollectorItemRepository().findRepoByUrlAndBranch(col.getId(), repoUrl, branch, true);
return existingItem != null;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy