View Javadoc
1   /*
2    * This file is part of dependency-check-core.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   *
16   * Copyright (c) 2019 Jason Dillon. All Rights Reserved.
17   */
18  package org.owasp.dependencycheck.data.ossindex;
19  
20  import com.google.common.annotations.VisibleForTesting;
21  import org.joda.time.Duration;
22  import org.jspecify.annotations.NonNull;
23  import org.owasp.dependencycheck.utils.Settings;
24  import org.slf4j.Logger;
25  import org.slf4j.LoggerFactory;
26  import org.sonatype.ossindex.service.client.OssindexClient;
27  import org.sonatype.ossindex.service.client.OssindexClientConfiguration;
28  import org.sonatype.ossindex.service.client.cache.DirectoryCache;
29  import org.sonatype.ossindex.service.client.internal.OssindexClientImpl;
30  import org.sonatype.ossindex.service.client.marshal.GsonMarshaller;
31  import org.sonatype.ossindex.service.client.marshal.Marshaller;
32  import org.sonatype.ossindex.service.client.transport.AuthConfiguration;
33  import org.sonatype.ossindex.service.client.transport.Transport;
34  import org.sonatype.ossindex.service.client.transport.UserAgentSupplier;
35  
36  import java.io.File;
37  import java.io.IOException;
38  
39  /**
40   * Produces {@link OssindexClient} instances.
41   *
42   * @author Jason Dillon
43   * @since 5.0.0
44   */
45  public final class OssIndexClientProvider {
46      /**
47       * Default base URL for Sonatype OSS Index after its migration to part of Sonatype Guide. This overrides the default
48       * from {@link OssindexClientConfiguration#DEFAULT_BASE_URL} which is now outdated.
49       */
50      public static final String DEFAULT_BASE_URL = "https://api.guide.sonatype.com";
51  
52      /**
53       * Default number of hours to cache entries from OSS Index when the cache is enabled.
54       */
55      public static final int DEFAULT_CACHE_VALID_FOR_HOURS = 24;
56  
57      /**
58       * Static logger.
59       */
60      private static final Logger LOGGER = LoggerFactory.getLogger(OssIndexClientProvider.class);
61  
62      /**
63       * Private constructor for utility class.
64       */
65      private OssIndexClientProvider() {
66          //private constructor for utility class
67      }
68  
69      /**
70       * Constructs a new OSS Index Client.
71       *
72       * @param settings the configured settings
73       * @return a new OSS Index Client
74       */
75      public static OssindexClient create(final Settings settings) {
76          final OssindexClientConfiguration config = new OssindexClientConfiguration();
77  
78          config.setBaseUrl(settings.getString(Settings.KEYS.ANALYZER_OSSINDEX_URL, DEFAULT_BASE_URL));
79          config.setAuthConfiguration(new AuthConfiguration(
80                  settings.getString(Settings.KEYS.ANALYZER_OSSINDEX_USER, ""),
81                  settings.getString(Settings.KEYS.ANALYZER_OSSINDEX_PASSWORD))
82          );
83  
84          final int batchSize = settings.getInt(Settings.KEYS.ANALYZER_OSSINDEX_BATCH_SIZE, OssindexClientConfiguration.DEFAULT_BATCH_SIZE);
85          config.setBatchSize(batchSize);
86  
87          if (settings.getBoolean(Settings.KEYS.ANALYZER_OSSINDEX_USE_CACHE, true)) {
88              final DirectoryCache.Configuration cache = new DirectoryCache.Configuration();
89              final File data;
90              try {
91                  data = settings.getDataDirectory();
92                  final File cacheDir = new File(data, "oss_cache");
93                  if (cacheDir.isDirectory() || cacheDir.mkdirs()) {
94                      cache.setBaseDir(cacheDir.toPath());
95                      cache.setExpireAfter(Duration.standardHours(settings.getInt(Settings.KEYS.ANALYZER_OSSINDEX_CACHE_VALID_FOR_HOURS, DEFAULT_CACHE_VALID_FOR_HOURS)));
96                      config.setCacheConfiguration(cache);
97                      LOGGER.debug("OSS Index Cache: {}", cache);
98                  } else {
99                      LOGGER.warn("Unable to use a cache for the OSS Index");
100                 }
101             } catch (IOException ex) {
102                 LOGGER.warn("Unable to use a cache for the OSS Index", ex);
103             }
104         }
105         // customize User-Agent for use with dependency-check
106         final UserAgentSupplier userAgent = new UserAgentSupplier(
107                 "dependency-check",
108                 settings.getString(Settings.KEYS.APPLICATION_VERSION, "unknown")
109         );
110 
111         final Transport transport = new ODCConnectionTransport(config, userAgent);
112 
113         final Marshaller marshaller = new GsonMarshaller();
114 
115         return newClientFor(config, transport, marshaller);
116     }
117 
118     @VisibleForTesting
119     static @NonNull OssindexClientImpl newClientFor(OssindexClientConfiguration config, Transport transport, Marshaller marshaller) {
120         return new OssindexClientImpl(config, transport, marshaller);
121     }
122 }