All Downloads are FREE. Search and download functionalities are using the official Maven repository.

toolkit.clients.vulnerable-code-client.42.0.0.source-code.VulnerableCodeService.kt Maven / Gradle / Ivy

/*
 * Copyright (C) 2021 The ORT Project Authors (see )
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * SPDX-License-Identifier: Apache-2.0
 * License-Filename: LICENSE
 */

package org.ossreviewtoolkit.clients.vulnerablecode

import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonNames
import kotlinx.serialization.json.JsonNamingStrategy

import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient

import retrofit2.Retrofit
import retrofit2.converter.kotlinx.serialization.asConverterFactory
import retrofit2.http.Body
import retrofit2.http.POST

/**
 * Interface for a REST service that allows interaction with the VulnerableCode API to query information about
 * vulnerabilities detected for specific packages.
 */
interface VulnerableCodeService {
    companion object {
        /**
         * The URL to version 1 of the API. Version 2 is currently in the works.
         */
        const val PUBLIC_SERVER_URL = "https://public.vulnerablecode.io/api/"

        /**
         * The JSON (de-)serialization object used by this service.
         */
        val JSON = Json {
            ignoreUnknownKeys = true
            namingStrategy = JsonNamingStrategy.SnakeCase
        }

        /**
         * Create a new service instance that connects to the [url] specified and uses the optionally provided [client].
         */
        fun create(url: String? = null, apiKey: String? = null, client: OkHttpClient? = null): VulnerableCodeService {
            val vulnerableCodeClient = (client ?: OkHttpClient()).run {
                takeIf { apiKey == null } ?: run {
                    newBuilder().addInterceptor { chain ->
                        val requestBuilder = chain.request().newBuilder().apply {
                            header("Authorization", "Token $apiKey")
                        }

                        chain.proceed(requestBuilder.build())
                    }.build()
                }
            }

            val contentType = "application/json".toMediaType()
            val retrofit = Retrofit.Builder()
                .client(vulnerableCodeClient)
                .baseUrl(url ?: PUBLIC_SERVER_URL)
                .addConverterFactory(JSON.asConverterFactory(contentType))
                .build()

            return retrofit.create(VulnerableCodeService::class.java)
        }
    }

    /**
     * Data class that represents a score assigned to a vulnerability. A source of vulnerability information can
     * provide multiple score values using different scoring systems.
     */
    @Serializable
    data class Score(
        /** The name of the scoring system. */
        val scoringSystem: String,

        /** The individual scoring elements, usually a CVSS vector. */
        val scoringElements: String? = null,

        /**
         * The value in this scoring system. This is a string to support scoring systems that do not use numeric
         * scores, but literals like _LOW_, _MEDIUM_, etc.
         */
        val value: String
    )

    /**
     * Data class representing a reference to detailed information about a vulnerability. Information about a single
     * vulnerability can come from multiple sources; for each of these sources a reference is added to the data.
     */
    @Serializable
    data class VulnerabilityReference(
        /**
         * The URL of this reference. From this URL, it is also possible to identify the source of information.
         */
        val url: String,

        /**
         * A (possibly empty) list with [Score] objects that determine the severity this source assigns to this
         * vulnerability.
         */
        val scores: List
    )

    /**
     * Data class representing a single vulnerability with its references to detailed information.
     */
    @Serializable
    data class Vulnerability(
        /** The VulnerableCode-specific identifier for this vulnerability. */
        val vulnerabilityId: String,

        /** A list with [VulnerabilityReference]s pointing to sources of information about this vulnerability. */
        val references: List,

        /**
         * A list with strings representing alias identifiers for this vulnerability as they are used by other
         * databases. VulnerableCode here returns plain strings without further context information; therefore, it is
         * currently only possible to determine the source of a specific identifier from its structure, e.g. if it has
         * a well-known prefix like CVE or GHSA.
         */
        val aliases: List = emptyList()
    )

    /**
     * Data class describing a package in the result of a package query together with the vulnerabilities known for
     * this package.
     */
    @Serializable
    data class PackageVulnerabilities(
        /** The purl identifying this package. */
        val purl: String,

        /** An optional list with vulnerabilities that have not yet been resolved. */
        @JsonNames("unresolved_vulnerabilities")
        val affectedByVulnerabilities: List = emptyList(),

        /** An optional list with vulnerabilities that have already been resolved. */
        @JsonNames("resolved_vulnerabilities")
        val fixingVulnerabilities: List = emptyList()
    )

    /**
     * Data class to represent the bulk request for packages by their IDs. Using this request, the vulnerabilities
     * known for a set of packages can be retrieved. The request body is a JSON object with a property containing a
     * list of package identifiers.
     */
    @Serializable
    data class PackagesWrapper(
        val purls: Collection
    )

    /**
     * Retrieve information about the vulnerabilities assigned to the given [packages][packageUrls].
     * Return a list with information about packages including the resolved and unresolved vulnerabilities for these
     * packages.
     */
    @POST("packages/bulk_search")
    suspend fun getPackageVulnerabilities(@Body packageUrls: PackagesWrapper): List
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy