Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MARP-1294 Create a central monitoring reporting for security issues of axonivy marketplace #251

Open
wants to merge 13 commits into
base: develop
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,19 @@ public static class Json {
public static final String CLIENT_ID = "client_id";
public static final String CLIENT_SECRET = "client_secret";
public static final String CODE = "code";
public static final String USER_ID = "id";
public static final String USER_NAME = "name";
public static final String USER_AVATAR_URL = "avatar_url";
public static final String USER_LOGIN_NAME = "login";
public static final String SEVERITY = "severity";
public static final String SECURITY_SEVERITY_LEVEL = "security_severity_level";
public static final String SEVERITY_ADVISORY = "security_advisory";
public static final String RULE = "rule";
}

@NoArgsConstructor(access = AccessLevel.PRIVATE)
public static class Url {
private static final String BASE_URL = "https://api.github.com";
public static final String USER = BASE_URL + "/user";
public static final String REPO_DEPENDABOT_ALERTS_OPEN = BASE_URL + "/repos/%s/%s/dependabot/alerts?state=open";
public static final String REPO_SECRET_SCANNING_ALERTS_OPEN =
BASE_URL + "/repos/%s/%s/secret-scanning/alerts?state=open";
public static final String REPO_CODE_SCANNING_ALERTS_OPEN =
BASE_URL + "/repos/%s/%s/code-scanning/alerts?state=open";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,5 @@ public class RequestMappingConstants {
public static final String LATEST_ARTIFACT_DOWNLOAD_URL_BY_ID = "/{id}/artifact";
public static final String EXTERNAL_DOCUMENT = API + "/externaldocument";
public static final String PRODUCT_MARKETPLACE_DATA = API + "/product-marketplace-data";
public static final String SECURITY_MONITOR = API + "/security-monitor";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.axonivy.market.controller;

import com.axonivy.market.constants.GitHubConstants;
import com.axonivy.market.github.service.GitHubService;
import com.axonivy.market.github.model.ProductSecurityInfo;
import com.axonivy.market.util.AuthorizationUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

import static com.axonivy.market.constants.RequestMappingConstants.SECURITY_MONITOR;
import static org.springframework.http.HttpHeaders.AUTHORIZATION;

@RestController
@RequestMapping(SECURITY_MONITOR)
@Tag(name = "Security Monitor Controllers", description = "API collection to get Github Marketplace security's detail.")
@AllArgsConstructor
public class SecurityMonitorController {
private final GitHubService gitHubService;

@GetMapping
@Operation(hidden = true)
public ResponseEntity<Object> getGitHubMarketplaceSecurity(
@RequestHeader(value = AUTHORIZATION) String authorizationHeader) {
String token = AuthorizationUtils.getBearerToken(authorizationHeader);
gitHubService.validateUserInOrganizationAndTeam(token, GitHubConstants.AXONIVY_MARKET_ORGANIZATION_NAME,
GitHubConstants.AXONIVY_MARKET_TEAM_NAME);
List<ProductSecurityInfo> securityInfoList = gitHubService.getSecurityDetailsForAllProducts(token,
GitHubConstants.AXONIVY_MARKET_ORGANIZATION_NAME);
return ResponseEntity.ok(securityInfoList);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.axonivy.market.enums;

import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor
public enum AccessLevel {
NO_PERMISSION, ENABLED, DISABLED
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.axonivy.market.github.model;

import com.axonivy.market.enums.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.util.Map;

@Getter
@Setter
@NoArgsConstructor
public class CodeScanning {
private Map<String, Integer> alerts;
private AccessLevel status;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.axonivy.market.github.model;

import com.axonivy.market.enums.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.util.Map;

@Getter
@Setter
@NoArgsConstructor
public class Dependabot {
private Map<String, Integer> alerts;
private AccessLevel status;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.axonivy.market.github.model;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.util.Date;

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class ProductSecurityInfo {
private String repoName;
private boolean isArchived;
private String visibility;
private boolean branchProtectionEnabled;
private Date lastCommitDate;
private String latestCommitSHA;
private Dependabot dependabot;
private SecretScanning secretScanning;
private CodeScanning codeScanning;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.axonivy.market.github.model;

import com.axonivy.market.enums.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Getter
@Setter
@NoArgsConstructor
public class SecretScanning {
private Integer numberOfAlerts;
private AccessLevel status;
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.axonivy.market.exceptions.model.UnauthorizedException;
import com.axonivy.market.github.model.GitHubAccessTokenResponse;
import com.axonivy.market.github.model.GitHubProperty;
import com.axonivy.market.github.model.ProductSecurityInfo;
import org.kohsuke.github.GHContent;
import org.kohsuke.github.GHOrganization;
import org.kohsuke.github.GHRepository;
Expand Down Expand Up @@ -37,4 +38,6 @@ GitHubAccessTokenResponse getAccessToken(String code, GitHubProperty gitHubPrope
User getAndUpdateUser(String accessToken);

void validateUserInOrganizationAndTeam(String accessToken, String team, String org) throws UnauthorizedException;

List<ProductSecurityInfo> getSecurityDetailsForAllProducts(String accessToken, String orgName);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,13 @@
import com.axonivy.market.constants.ReadmeConstants;
import com.axonivy.market.entity.Product;
import com.axonivy.market.entity.ProductModuleContent;
import com.axonivy.market.enums.Language;
import com.axonivy.market.github.service.GHAxonIvyProductRepoService;
import com.axonivy.market.github.service.GitHubService;
import com.axonivy.market.github.util.GitHubUtils;
import com.axonivy.market.model.ReadmeContentsModel;
import com.axonivy.market.service.ImageService;
import com.axonivy.market.util.ProductContentUtils;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.kohsuke.github.GHContent;
import org.kohsuke.github.GHOrganization;
import org.springframework.stereotype.Service;
Expand All @@ -26,7 +24,6 @@
import java.util.Optional;

import static com.axonivy.market.constants.CommonConstants.IMAGE_ID_PREFIX;
import static com.axonivy.market.util.ProductContentUtils.*;

@Log4j2
@Service
Expand Down
Loading
Loading