Skip to content

Commit

Permalink
Merge pull request #722 from DependencyTrack/port-pr-3557
Browse files Browse the repository at this point in the history
Port: OpenAPI spec fixes and improvements
  • Loading branch information
nscuro authored Jun 18, 2024
2 parents 76712ee + b9d288e commit 04c4f7c
Show file tree
Hide file tree
Showing 37 changed files with 566 additions and 291 deletions.
18 changes: 10 additions & 8 deletions src/main/java/org/dependencytrack/model/Component.java
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,7 @@ public void setPurl(String purl) {
}

@JsonSerialize(using = CustomPackageURLSerializer.class)
@ApiModelProperty(dataType = "string", accessMode = ApiModelProperty.AccessMode.READ_ONLY)
public PackageURL getPurlCoordinates() {
if (purlCoordinates == null) {
return null;
Expand Down Expand Up @@ -822,10 +823,13 @@ public void setComponentMetaInformation(ComponentMetaInformation componentMetaIn
this.componentMetaInformation = componentMetaInformation;
}

@JsonIgnore
@ApiModelProperty(hidden = true)
public boolean isNew() {
return isNew;
}

@JsonIgnore
public void setNew(final boolean aNew) {
isNew = aNew;
}
Expand All @@ -838,30 +842,28 @@ public void setLastInheritedRiskScore(Double lastInheritedRiskScore) {
this.lastInheritedRiskScore = lastInheritedRiskScore;
}

@JsonIgnore
@ApiModelProperty(hidden = true)
public String getBomRef() {
return bomRef;
}

@JsonIgnore
public void setBomRef(String bomRef) {
this.bomRef = bomRef;
}

@JsonIgnore
@ApiModelProperty(hidden = true)
public List<org.cyclonedx.model.License> getLicenseCandidates() {
return licenseCandidates;
}

@JsonIgnore
public void setLicenseCandidates(final List<org.cyclonedx.model.License> licenseCandidates) {
this.licenseCandidates = licenseCandidates;
}

public int getUsedBy() {
return usedBy;
}

public void setUsedBy(int usedBy) {
this.usedBy = usedBy;
}

public Set<String> getDependencyGraph() {
return dependencyGraph;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ public class AccessControlResource extends AlpineResource {
value = "Returns the projects assigned to the specified team",
response = String.class,
responseContainer = "List",
responseHeaders = @ResponseHeader(name = TOTAL_COUNT_HEADER, response = Long.class, description = "The total number of projects")
responseHeaders = @ResponseHeader(name = TOTAL_COUNT_HEADER, response = Long.class, description = "The total number of projects"),
notes = "<p>Requires permission <strong>ACCESS_MANAGEMENT</strong></p>"
)
@PaginatedApi
@ApiResponses(value = {
Expand Down Expand Up @@ -99,7 +100,8 @@ public Response retrieveProjects (@ApiParam(value = "The UUID of the team to ret
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation(
value = "Adds an ACL mapping",
response = AclMappingRequest.class
response = AclMappingRequest.class,
notes = "<p>Requires permission <strong>ACCESS_MANAGEMENT</strong></p>"
)
@ApiResponses(value = {
@ApiResponse(code = 401, message = "Unauthorized"),
Expand Down Expand Up @@ -135,7 +137,8 @@ public Response addMapping(AclMappingRequest request) {
@Path("/mapping/team/{teamUuid}/project/{projectUuid}")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation(
value = "Removes an ACL mapping"
value = "Removes an ACL mapping",
notes = "<p>Requires permission <strong>ACCESS_MANAGEMENT</strong></p>"
)
@ApiResponses(value = {
@ApiResponse(code = 401, message = "Unauthorized"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ public class AnalysisResource extends AlpineResource {
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation(
value = "Retrieves an analysis trail",
response = Analysis.class
response = Analysis.class,
notes = "<p>Requires permission <strong>VIEW_VULNERABILITY</strong></p>"
)
@ApiResponses(value = {
@ApiResponse(code = 401, message = "Unauthorized"),
Expand Down Expand Up @@ -119,7 +120,8 @@ public Response retrieveAnalysis(@ApiParam(value = "The UUID of the project", fo
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation(
value = "Records an analysis decision",
response = Analysis.class
response = Analysis.class,
notes = "<p>Requires permission <strong>VULNERABILITY_ANALYSIS</strong></p>"
)
@ApiResponses(value = {
@ApiResponse(code = 401, message = "Unauthorized"),
Expand Down
75 changes: 51 additions & 24 deletions src/main/java/org/dependencytrack/resources/v1/BomResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@
import org.dependencytrack.resources.v1.vo.IsTokenBeingProcessedResponse;
import org.glassfish.jersey.media.multipart.BodyPartEntity;
import org.glassfish.jersey.media.multipart.FormDataBodyPart;
import org.glassfish.jersey.media.multipart.FormDataMultiPart;
import org.glassfish.jersey.media.multipart.FormDataParam;

import javax.validation.Validator;
Expand Down Expand Up @@ -98,7 +97,8 @@ public class BomResource extends AlpineResource {
@Produces({CycloneDxMediaType.APPLICATION_CYCLONEDX_XML, CycloneDxMediaType.APPLICATION_CYCLONEDX_JSON, MediaType.APPLICATION_OCTET_STREAM})
@ApiOperation(
value = "Returns dependency metadata for a project in CycloneDX format",
response = String.class
response = String.class,
notes = "<p>Requires permission <strong>VIEW_PORTFOLIO</strong></p>"
)
@ApiResponses(value = {
@ApiResponse(code = 401, message = "Unauthorized"),
Expand Down Expand Up @@ -167,7 +167,8 @@ public Response exportProjectAsCycloneDx(
@Produces(CycloneDxMediaType.APPLICATION_CYCLONEDX_XML)
@ApiOperation(
value = "Returns dependency metadata for a specific component in CycloneDX format",
response = String.class
response = String.class,
notes = "<p>Requires permission <strong>VIEW_PORTFOLIO</strong></p>"
)
@ApiResponses(value = {
@ApiResponse(code = 401, message = "Unauthorized"),
Expand Down Expand Up @@ -213,14 +214,20 @@ public Response exportComponentAsCycloneDx(
@ApiOperation(
value = "Upload a supported bill of material format document",
notes = """
Expects CycloneDX and a valid project UUID. If a UUID is not specified, \
then the projectName and projectVersion must be specified. \
Optionally, if autoCreate is specified and 'true' and the project does not exist, \
the project will be created. In this scenario, the principal making the request will \
additionally need the PORTFOLIO_MANAGEMENT or PROJECT_CREATION_UPLOAD permission.
The BOM will be validated against the CycloneDX schema. If schema validation fails, \
a response with problem details in RFC 9457 format will be returned. In this case, \
the response's content type will be application/problem+json.""",
<p>
Expects CycloneDX and a valid project UUID. If a UUID is not specified,
then the <code>projectName</code> and <code>projectVersion</code> must be specified.
Optionally, if <code>autoCreate</code> is specified and <code>true</code> and the project does not exist,
the project will be created. In this scenario, the principal making the request will
additionally need the <strong>PORTFOLIO_MANAGEMENT</strong> or
<strong>PROJECT_CREATION_UPLOAD</strong> permission.
</p>
<p>
The BOM will be validated against the CycloneDX schema. If schema validation fails,
a response with problem details in RFC 9457 format will be returned. In this case,
the response's content type will be <code>application/problem+json</code>.
</p>
<p>Requires permission <strong>BOM_UPLOAD</strong></p>""",
response = BomUploadResponse.class,
nickname = "UploadBomBase64Encoded"
)
Expand All @@ -232,7 +239,7 @@ public Response exportComponentAsCycloneDx(
@ApiResponse(code = 404, message = "The project could not be found")
})
@PermissionRequired(Permissions.Constants.BOM_UPLOAD)
public Response uploadBom(BomSubmitRequest request) {
public Response uploadBom(@ApiParam(required = true) BomSubmitRequest request) {
final Validator validator = getValidator();
if (request.getProject() != null) { // behavior in v3.0.0
failOnValidationError(
Expand Down Expand Up @@ -293,14 +300,20 @@ public Response uploadBom(BomSubmitRequest request) {
@ApiOperation(
value = "Upload a supported bill of material format document",
notes = """
Expects CycloneDX and a valid project UUID. If a UUID is not specified, \
then the projectName and projectVersion must be specified. \
Optionally, if autoCreate is specified and 'true' and the project does not exist, \
the project will be created. In this scenario, the principal making the request will \
additionally need the PORTFOLIO_MANAGEMENT or PROJECT_CREATION_UPLOAD permission.
The BOM will be validated against the CycloneDX schema. If schema validation fails, \
a response with problem details in RFC 9457 format will be returned. In this case, \
the response's content type will be application/problem+json.""",
<p>
Expects CycloneDX and a valid project UUID. If a UUID is not specified,
then the <code>projectName</code> and <code>projectVersion</code> must be specified.
Optionally, if <code>autoCreate</code> is specified and <code>true</code> and the project does not exist,
the project will be created. In this scenario, the principal making the request will
additionally need the <strong>PORTFOLIO_MANAGEMENT</strong> or
<strong>PROJECT_CREATION_UPLOAD</strong> permission.
</p>
<p>
The BOM will be validated against the CycloneDX schema. If schema validation fails,
a response with problem details in RFC 9457 format will be returned. In this case,
the response's content type will be <code>application/problem+json</code>.
</p>
<p>Requires permission <strong>BOM_UPLOAD</strong></p>""",
response = BomUploadResponse.class,
nickname = "UploadBom"
)
Expand All @@ -319,9 +332,7 @@ public Response uploadBom(@FormDataParam("project") String projectUuid,
@FormDataParam("parentName") String parentName,
@FormDataParam("parentVersion") String parentVersion,
@FormDataParam("parentUUID") String parentUUID,
final FormDataMultiPart multiPart) {

final List<FormDataBodyPart> artifactParts = multiPart.getFields("bom");
@ApiParam(type = "string") @FormDataParam("bom") final List<FormDataBodyPart> artifactParts) {
if (projectUuid != null) { // behavior in v3.0.0
try (QueryManager qm = new QueryManager()) {
final Project project = qm.getObjectByUuid(Project.class, projectUuid);
Expand Down Expand Up @@ -366,7 +377,23 @@ public Response uploadBom(@FormDataParam("project") String projectUuid,
@GET
@Path("/token/{uuid}")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation(value = "Determines if there are any tasks associated with the token that are being processed, or in the queue to be processed.", notes = "Deprecated. Use /v1/event/token/{uuid} instead.", response = IsTokenBeingProcessedResponse.class)
@ApiOperation(
value = "Determines if there are any tasks associated with the token that are being processed, or in the queue to be processed.",
notes = """
<p>
This endpoint is intended to be used in conjunction with uploading a supported BOM document.
Upon upload, a token will be returned. The token can then be queried using this endpoint to
determine if any tasks (such as vulnerability analysis) is being performed on the BOM:
<ul>
<li>A value of <code>true</code> indicates processing is occurring.</li>
<li>A value of <code>false</code> indicates that no processing is occurring for the specified token.</li>
</ul>
However, a value of <code>false</code> also does not confirm the token is valid,
only that no processing is associated with the specified token.
</p>
<p>Requires permission <strong>BOM_UPLOAD</strong></p>
<p><strong>Deprecated</strong>. Use <code>/v1/event/token/{uuid}</code> instead.</p>""",
response = IsTokenBeingProcessedResponse.class)
@ApiResponses(value = {
@ApiResponse(code = 401, message = "Unauthorized")
})
Expand Down
Loading

0 comments on commit 04c4f7c

Please sign in to comment.