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

Port: OpenAPI spec fixes and improvements #722

Merged
merged 1 commit into from
Jun 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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