zowe / sample-spring-boot-api-service
Showing 12 of 24 files from the diff.

@@ -37,8 +37,11 @@
Loading
37 37
38 38
    @Override
39 39
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
40 -
        configurer.favorPathExtension(true).favorParameter(false).ignoreAcceptHeader(true)
41 -
                .useRegisteredExtensionsOnly(true).defaultContentType(MediaType.APPLICATION_JSON);
40 +
        configurer
41 +
                .favorParameter(false)
42 +
                .ignoreAcceptHeader(true)
43 +
                .useRegisteredExtensionsOnly(true)
44 +
                .defaultContentType(MediaType.APPLICATION_JSON);
42 45
    }
43 46
44 47
    @Bean

@@ -21,7 +21,7 @@
Loading
21 21
22 22
@Service
23 23
public class PlatformThreadLevelSecurityByDaemon implements PlatformThreadLevelSecurity {
24 -
    private PlatformSecurityService platformSecurityService;
24 +
    private final PlatformSecurityService platformSecurityService;
25 25
26 26
    @Autowired
27 27
    public PlatformThreadLevelSecurityByDaemon(PlatformSecurityService platformSecurityService) {
@@ -40,13 +40,14 @@
Loading
40 40
    }
41 41
42 42
    @Override
43 -
    public Callable wrapCallableInEnvironmentForAuthenticatedUser(Callable callable) {
43 +
    public <T> Callable<T> wrapCallableInEnvironmentForAuthenticatedUser(Callable<T> callable) {
44 44
        return wrapCallableInEnvironment(callable, SecurityContextHolder.getContext());
45 45
    }
46 46
47 47
    @Override
48 -
    public Callable wrapCallableInEnvironment(Callable callable, SecurityContext securityContext) {
49 -
        return new DelegatingSecurityContextCallable(new CallInThreadLevelSecurityEnvironmentByDaemon(
50 -
            platformSecurityService, callable, securityContext.getAuthentication()), securityContext);
48 +
    public <T> Callable<T> wrapCallableInEnvironment(Callable<T> callable, SecurityContext securityContext) {
49 +
        return new DelegatingSecurityContextCallable<>(new CallInThreadLevelSecurityEnvironmentByDaemon<>(
50 +
                platformSecurityService, callable, securityContext.getAuthentication()), securityContext);
51 51
    }
52 +
52 53
}

@@ -12,12 +12,9 @@
Loading
12 12
 */
13 13
package jarpatcher;
14 14
15 -
import java.io.File;
16 -
import java.io.FileInputStream;
17 -
import java.io.FileOutputStream;
18 -
import java.io.IOException;
19 -
import java.io.InputStream;
20 -
import java.io.OutputStream;
15 +
import lombok.ToString;
16 +
17 +
import java.io.*;
21 18
import java.nio.file.Files;
22 19
import java.nio.file.Path;
23 20
import java.nio.file.Paths;
@@ -33,13 +30,15 @@
Loading
33 30
import java.util.zip.ZipInputStream;
34 31
import java.util.zip.ZipOutputStream;
35 32
36 -
import lombok.ToString;
37 -
33 +
// Suppresses `I/O function calls should not be vulnerable to path injection attacks` because it is only an internal
34 +
// development tool where a developer is responsible for the correct input. The input may vary according to the tool
35 +
// usage and it is difficult to validate. Do not suppress this security issue for the code which is released to
36 +
// customers.
38 37
public class JarPatcher {
39 38
    private static final Logger logger = Logger.getLogger(JarPatcher.class.getName());
40 39
41 40
    @ToString
42 -
    public class CompareResult {
41 +
    public static class CompareResult {
43 42
        Set<String> created = new HashSet<>();
44 43
        Set<String> deleted = new HashSet<>();
45 44
        Set<String> changed = new HashSet<>();
@@ -53,7 +52,7 @@
Loading
53 52
        }
54 53
    }
55 54
56 -
    public class JarPatcherError extends RuntimeException {
55 +
    public static class JarPatcherError extends RuntimeException {
57 56
        private static final long serialVersionUID = 8522323019867383326L;
58 57
59 58
        public JarPatcherError(IOException e) {
@@ -119,15 +118,15 @@
Loading
119 118
    private void printEntry(ZipFile f, ZipEntry entry) {  // NOSONAR
120 119
        if (logger.isLoggable(Level.INFO)) {
121 120
            logger.info(String.format("zipFile=%s file=%s size=%d crc=%d dir=%b comment=%s method=%s", f.getName(),
122 -
                entry.getName(), entry.getSize(), entry.getCrc(), entry.isDirectory(), entry.getComment(),
123 -
                entry.getMethod()));
121 +
                    entry.getName(), entry.getSize(), entry.getCrc(), entry.isDirectory(), entry.getComment(),
122 +
                    entry.getMethod()));
124 123
        }
125 124
    }
126 125
127 126
    private boolean compareEntries(ZipEntry entry1, ZipEntry entry2) {  // NOSONAR
128 127
        return (entry1.isDirectory() == entry2.isDirectory()) && (entry1.getSize() == entry2.getSize())
129 128
                && (entry1.getName().equals(entry2.getName())) && (entry1.getCrc() == entry2.getCrc()
130 -
                        && (entry1.isDirectory() || (entry1.getMethod() == entry2.getMethod())));
129 +
                && (entry1.isDirectory() || (entry1.getMethod() == entry2.getMethod())));
131 130
    }
132 131
133 132
    private Set<String> setFromEntryNames(ZipFile zipFile) {
@@ -206,7 +205,9 @@
Loading
206 205
        }
207 206
208 207
        try (FileOutputStream fos = new FileOutputStream(patchPath);
209 -
                ZipOutputStream zipOut = new ZipOutputStream(fos)) {
208 +
             BufferedOutputStream bos = new BufferedOutputStream(fos);
209 +
             ZipOutputStream zipOut = new ZipOutputStream(bos)
210 +
        ) {
210 211
211 212
            addChangedOrCreatedFiles(newPath, result, zipOut);
212 213
            addDeletedEntries(result.deleted, zipOut);
@@ -235,31 +236,45 @@
Loading
235 236
        String originalTargetPath = targetPath + "-original";
236 237
        Files.copy(Paths.get(targetPath), Paths.get(originalTargetPath), StandardCopyOption.REPLACE_EXISTING);
237 238
        try (FileOutputStream fos = new FileOutputStream(targetPath);
238 -
                ZipOutputStream zipOut = new ZipOutputStream(fos)) {
239 +
             BufferedOutputStream bos = new BufferedOutputStream(fos);
240 +
             ZipOutputStream zipOut = new ZipOutputStream(bos)
241 +
      ) {
239 242
            Set<String> deletedOrPatchedNames = new HashSet<>();
240 243
            int keeping = 0;
241 244
242 245
            ZipFile zipPatch = new ZipFile(patchPath);
243 246
            Enumeration<? extends ZipEntry> entries = zipPatch.entries();
244 -
            while (entries.hasMoreElements()) {
245 -
                ZipEntry entry = entries.nextElement();  // NOSONAR
246 -
                processPatchEntry(ignoredPath, zipOut, deletedOrPatchedNames, zipPatch, entry);
247 +
            try {
248 +
                while (entries.hasMoreElements()) {
249 +
                    ZipEntry entry = entries.nextElement(); //NOSONAR
250 +
251 +
                    String name = entry.getName();
252 +
                    if (!name.contains("..")) {
253 +
                        processPatchEntry(ignoredPath, zipOut, deletedOrPatchedNames, zipPatch, entry);
254 +
                    } else {
255 +
                        throw new IllegalArgumentException("Path cannot contain '..': " + name);
256 +
                    }
257 +
                }
258 +
            } finally {
259 +
                zipPatch.close();
247 260
            }
248 -
            zipPatch.close();
249 261
250 262
            ZipFile zipIn = new ZipFile(originalTargetPath);
251 263
            entries = zipIn.entries();
252 -
            while (entries.hasMoreElements()) {
253 -
                ZipEntry entry = entries.nextElement();  // NOSONAR
254 -
                String filename = entry.getName();
255 -
256 -
                if (!deletedOrPatchedNames.contains(filename)) {
257 -
                    keeping++;
258 -
                    deletedOrPatchedNames.add(filename);
259 -
                    writeEntry(zipOut, deletedOrPatchedNames, zipIn, entry, filename);
264 +
            try {
265 +
                while (entries.hasMoreElements()) {
266 +
                    ZipEntry entry = entries.nextElement();  // NOSONAR
267 +
                    String filename = entry.getName();
268 +
269 +
                    if (!deletedOrPatchedNames.contains(filename)) {
270 +
                        keeping++;
271 +
                        deletedOrPatchedNames.add(filename);
272 +
                        writeEntry(zipOut, deletedOrPatchedNames, zipIn, entry, filename);
273 +
                    }
260 274
                }
275 +
            } finally {
276 +
                zipIn.close();
261 277
            }
262 -
            zipIn.close();
263 278
264 279
            if (logger.isLoggable(Level.INFO)) {
265 280
                logger.info(String.format("Keeping %d ZIP entries", keeping));
@@ -269,7 +284,7 @@
Loading
269 284
    }
270 285
271 286
    private void processPatchEntry(String ignoredPath, ZipOutputStream zipOut, Set<String> deletedOrPatchedNames,
272 -
            ZipFile zipPatch, ZipEntry entry) throws IOException {  // NOSONAR
287 +
                                   ZipFile zipPatch, ZipEntry entry) throws IOException {  // NOSONAR
273 288
        String filename = entry.getName();
274 289
        if (filename.startsWith(DELETED)) {
275 290
            String realFilename = filename.substring(DELETED.length());
@@ -291,14 +306,17 @@
Loading
291 306
    }
292 307
293 308
    private void writeEntry(ZipOutputStream zipOut, Set<String> createdDirectories, ZipFile zipPatch, ZipEntry entry,  // NOSONAR
294 -
            String filename) throws IOException {
309 +
                            String filename) throws IOException {
295 310
        createDirectories(filename, zipOut, createdDirectories);
296 311
        ZipEntry zipEntry = new ZipEntry(filename);
297 312
        copyZipEntryAttributes(entry, zipEntry);
298 -
        InputStream inputStream = zipPatch.getInputStream(entry);
299 -
        zipOut.putNextEntry(zipEntry);
300 -
        copyStream(inputStream, zipOut);
301 -
        zipOut.closeEntry();
313 +
314 +
        try (InputStream inputStream = zipPatch.getInputStream(entry)) {
315 +
            zipOut.putNextEntry(zipEntry);
316 +
            copyStream(inputStream, zipOut);
317 +
        } finally {
318 +
            zipOut.closeEntry();
319 +
        }
302 320
    }
303 321
304 322
    private void copyZipEntryAttributes(ZipEntry inEntry, ZipEntry outEntry) {  // NOSONAR
@@ -314,4 +332,5 @@
Loading
314 332
        System.setProperty("java.util.logging.SimpleFormatter.format", "%5$s %n");
315 333
        System.exit(new JarPatcher().run(args));
316 334
    }
335 +
317 336
}

@@ -9,18 +9,19 @@
Loading
9 9
 */
10 10
package org.zowe.commons.zos;
11 11
12 +
import org.springframework.util.ResourceUtils;
13 +
14 +
import java.io.BufferedOutputStream;
12 15
import java.io.FileOutputStream;
13 16
import java.io.IOException;
14 17
import java.io.InputStream;
15 -
import java.io.OutputStream;
16 18
import java.net.URL;
17 19
import java.nio.file.Path;
18 20
import java.nio.file.Paths;
19 21
20 -
import org.springframework.util.ResourceUtils;
21 -
22 22
public class LibExtractor {
23 -
    public class LibExtractionError extends RuntimeException {
23 +
24 +
    public static class LibExtractionError extends RuntimeException {
24 25
        private static final long serialVersionUID = 2453905334387687806L;
25 26
26 27
        public LibExtractionError(String message, IOException e) {
@@ -30,16 +31,18 @@
Loading
30 31
31 32
    private static final int BUFFER_SIZE = 4096;
32 33
33 -
    private LibLoader libLoader = new LibLoader();
34 +
    private final LibLoader libLoader = new LibLoader();
34 35
35 36
    public void extractLibrary(String libraryName, String targetDir) {
36 37
        String filename = "lib/lib" + libraryName + ".so";
37 38
        Path targetPath = Paths.get(targetDir, libLoader.libraryFileName(libraryName));
38 -
        System.out.println(String.format("Extracting %s to %s", filename, targetPath));  // NOSONAR
39 +
        System.out.printf("Extracting %s to %s%n", filename, targetPath);  // NOSONAR
39 40
        try {
40 41
            URL url = ResourceUtils.getURL(ResourceUtils.CLASSPATH_URL_PREFIX + filename);
41 42
            try (InputStream inputStream = url.openStream();
42 -
                    OutputStream outputStream = new FileOutputStream(targetPath.toString())) {
43 +
                 FileOutputStream fos = new FileOutputStream(targetPath.toString());
44 +
                 BufferedOutputStream outputStream = new BufferedOutputStream(fos)
45 +
            ) {
43 46
                byte[] buffer = new byte[BUFFER_SIZE];
44 47
                int lengthRead;
45 48
                while ((lengthRead = inputStream.read(buffer)) > 0) {

@@ -13,16 +13,30 @@
Loading
13 13
import org.zowe.commons.zos.security.jni.Secur;
14 14
15 15
public class SafUtils {
16 -
    private SafUtils() {
17 -
        // no instances
18 -
    }
19 16
20 -
    private static ThreadLocal<String> threadApplid = new ThreadLocal<>();
17 +
    private static final SetApplid SECUR;
18 +
19 +
    static {
20 +
        if (ZosUtils.isRunningOnZos()) {
21 +
            SECUR = new SetApplid() {
22 +
23 +
                private final Secur secur = new Secur();
24 +
25 +
                @Override
26 +
                public int setApplid(String applid) {
27 +
                    return secur.setApplid(applid);
28 +
                }
29 +
30 +
            };
31 +
        } else {
32 +
            SECUR = applId -> 0;
33 +
        }
34 +
    }
21 35
22 36
    /**
23 37
     * Sets the APPLID for the current thread so the PlatformUser.authenticate can
24 38
     * use PassTickets for the provide APPLID.
25 -
     *
39 +
     * <p>
26 40
     * The APPLID can be changed but not unset.
27 41
     *
28 42
     * @param applid The APPLID to be set. Up to 8 characters.
@@ -32,12 +46,13 @@
Loading
32 46
            return;
33 47
        }
34 48
35 -
        String currentApplid = threadApplid.get();
36 -
        if (currentApplid == null || !currentApplid.equals(applid)) {
37 -
            if (ZosUtils.isRunningOnZos()) {
38 -
                new Secur().setApplid(applid);
39 -
            }
40 -
            threadApplid.set(applid);
41 -
        }
49 +
        SECUR.setApplid(applid);
42 50
    }
51 +
52 +
    private interface SetApplid {
53 +
54 +
        int setApplid(String applId);
55 +
56 +
    }
57 +
43 58
}

@@ -24,7 +24,7 @@
Loading
24 24
/**
25 25
 * Creates responses for exceptional behavior of the {@link GreetingController}.
26 26
 */
27 -
@ControllerAdvice(assignableTypes = { GreetingController.class })
27 +
@ControllerAdvice(assignableTypes = {GreetingController.class})
28 28
@Order(Ordered.HIGHEST_PRECEDENCE)
29 29
public class GreetingControllerExceptionHandler {
30 30
    private final ErrorService errorService;
@@ -38,6 +38,6 @@
Loading
38 38
    public ResponseEntity<ApiMessage> handleEmptyName(EmptyNameError exception) {
39 39
        ApiMessage message = errorService.createApiMessage(LocaleContextHolder.getLocale(), "org.zowe.sample.apiservice.greeting.empty");
40 40
41 -
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).contentType(MediaType.APPLICATION_JSON_UTF8).body(message);
41 +
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).contentType(MediaType.APPLICATION_JSON).body(message);
42 42
    }
43 43
}

@@ -9,38 +9,34 @@
Loading
9 9
 */
10 10
package org.zowe.commons.apiml;
11 11
12 -
import javax.net.ssl.SSLHandshakeException;
13 -
import javax.net.ssl.SSLPeerUnverifiedException;
14 -
15 -
import org.apache.commons.lang3.exception.ExceptionUtils;
16 -
import org.slf4j.Marker;
17 -
import org.zowe.commons.error.CommonsErrorService;
18 -
import org.zowe.commons.spring.SpringContext;
19 -
20 12
import ch.qos.logback.classic.Level;
21 13
import ch.qos.logback.classic.Logger;
22 14
import ch.qos.logback.classic.turbo.TurboFilter;
23 15
import ch.qos.logback.core.spi.FilterReply;
24 16
import lombok.extern.slf4j.Slf4j;
17 +
import org.apache.commons.lang3.StringUtils;
18 +
import org.apache.commons.lang3.exception.ExceptionUtils;
19 +
import org.slf4j.Marker;
20 +
import org.zowe.commons.error.CommonsErrorService;
21 +
22 +
import javax.net.ssl.SSLHandshakeException;
23 +
import javax.net.ssl.SSLPeerUnverifiedException;
25 24
26 25
@Slf4j
27 26
public class ApimlIntegrationFailureDetector extends TurboFilter {
28 27
29 28
    @Override
30 29
    public FilterReply decide(Marker marker, Logger logger, Level level, String format, Object[] params, Throwable t) {
31 -
        if (reportFatalErrorAndDecideToExit(level, t)) {
32 -
            System.exit(1);
30 +
        if (reportFatalError(level, t)) {
31 +
            return FilterReply.DENY;
33 32
        }
34 33
35 34
        if ((logger != null) && logger.getName().contains("com.netflix")
36 35
                && (logger.getName().contains("DiscoveryClient")
37 -
                        || logger.getName().contains("RedirectingEurekaHttpClient"))) {
36 +
                || logger.getName().contains("RedirectingEurekaHttpClient"))) {
38 37
            if (logger.getLevel() == Level.ERROR) {
39 38
                String message = ExceptionUtils.getMessage(t);
40 -
                if (message == null) {
41 -
                    message = ExceptionUtils.getRootCauseMessage(t);
42 -
                }
43 -
                if ((message != null) && !message.isEmpty()) {
39 +
                if (!StringUtils.isEmpty(message)) {
44 40
                    log.error(CommonsErrorService.get().getReadableMessage("org.zowe.commons.apiml.unableToRegister",
45 41
                            message));
46 42
                    logOriginalError(t);
@@ -53,8 +49,8 @@
Loading
53 49
    }
54 50
55 51
    private boolean isErrorFromDiscoveryClient(String stackFrame) {
56 -
        return ((stackFrame.indexOf(".ApiMediationClient") >= 0)
57 -
                || (stackFrame.indexOf("com.netflix.discovery.DiscoveryClient") >= 0));
52 +
        return ((stackFrame.contains(".ApiMediationClient"))
53 +
                || (stackFrame.contains("com.netflix.discovery.DiscoveryClient")));
58 54
    }
59 55
60 56
    private boolean isErrorFromDiscoveryClient(Throwable throwable) {
@@ -66,27 +62,24 @@
Loading
66 62
        return false;
67 63
    }
68 64
69 -
    boolean reportFatalErrorAndDecideToExit(Level level, Throwable t) {
70 -
        String errorMessageKey = null;
71 -
        if (level.isGreaterOrEqual(Level.ERROR)) {
72 -
            if ((ExceptionUtils.indexOfType(t, SSLPeerUnverifiedException.class) >= 0)
73 -
                    && isErrorFromDiscoveryClient(t)) {
74 -
                errorMessageKey = "org.zowe.commons.apiml.apimlCertificateNotTrusted";
75 -
            } else if ((ExceptionUtils.indexOfType(t, SSLHandshakeException.class) >= 0)
76 -
                    && isErrorFromDiscoveryClient(t)) {
77 -
                errorMessageKey = "org.zowe.commons.apiml.serviceCertificateNotTrusted";
78 -
            }
65 +
    boolean reportFatalError(Level level, Throwable t) {
66 +
        if (!level.isGreaterOrEqual(Level.ERROR) || !isErrorFromDiscoveryClient(t)) {
67 +
            return false;
79 68
        }
80 69
81 -
        if (errorMessageKey != null) {
82 -
            log.error(CommonsErrorService.get().getReadableMessage(errorMessageKey, t.getMessage()));
83 -
            logOriginalError(t);
84 -
            if (SpringContext.getApplicationContext() == null) {
85 -
                return true;
86 -
            }
70 +
        String errorMessageKey;
71 +
        if (ExceptionUtils.indexOfType(t, SSLPeerUnverifiedException.class) >= 0) {
72 +
            errorMessageKey = "org.zowe.commons.apiml.apimlCertificateNotTrusted";
73 +
        } else if (ExceptionUtils.indexOfType(t, SSLHandshakeException.class) >= 0) {
74 +
            errorMessageKey = "org.zowe.commons.apiml.serviceCertificateNotTrusted";
75 +
        } else {
76 +
            return false;
87 77
        }
88 78
89 -
        return false;
79 +
        log.error(CommonsErrorService.get().getReadableMessage(errorMessageKey, t.getMessage()));
80 +
        logOriginalError(t);
81 +
82 +
        return true;
90 83
    }
91 84
92 85
    private void logOriginalError(Throwable t) {

@@ -9,14 +9,9 @@
Loading
9 9
 */
10 10
package org.zowe.sample.apiservice.security;
11 11
12 -
import static org.zowe.commons.zos.security.platform.SafConstants.BPX_SERVER;
13 -
import static org.zowe.commons.zos.security.platform.SafConstants.CLASS_FACILITY;
14 -
import static org.zowe.commons.apidoc.ApiDocConstants.DOC_SCHEME_BASIC_AUTH;
15 -
16 -
import java.util.LinkedHashMap;
17 -
import java.util.Map;
18 -
19 -
import lombok.extern.slf4j.Slf4j;
12 +
import io.swagger.annotations.Api;
13 +
import io.swagger.annotations.ApiOperation;
14 +
import io.swagger.annotations.Authorization;
20 15
import org.springframework.beans.factory.annotation.Autowired;
21 16
import org.springframework.security.access.prepost.PreAuthorize;
22 17
import org.springframework.security.core.Authentication;
@@ -28,12 +23,15 @@
Loading
28 23
import org.zowe.commons.zos.security.platform.PlatformAccessControl.AccessLevel;
29 24
import org.zowe.commons.zos.security.service.PlatformSecurityService;
30 25
import org.zowe.commons.zos.security.thread.PlatformThreadLevelSecurity;
31 -
32 -
import io.swagger.annotations.Api;
33 -
import io.swagger.annotations.ApiOperation;
34 -
import io.swagger.annotations.Authorization;
35 26
import springfox.documentation.annotations.ApiIgnore;
36 27
28 +
import java.util.LinkedHashMap;
29 +
import java.util.Map;
30 +
31 +
import static org.zowe.commons.apidoc.ApiDocConstants.DOC_SCHEME_BASIC_AUTH;
32 +
import static org.zowe.commons.zos.security.platform.SafConstants.BPX_SERVER;
33 +
import static org.zowe.commons.zos.security.platform.SafConstants.CLASS_FACILITY;
34 +
37 35
@Api(tags = "Security")
38 36
@RestController
39 37
@RequestMapping("/api/v1/securityTest")
@@ -81,7 +79,7 @@
Loading
81 79
        }).run();
82 80
83 81
        try {
84 -
            String afterSwitchUserNameCall = (String) platformThreadLevelSecurity
82 +
            String afterSwitchUserNameCall = platformThreadLevelSecurity
85 83
                    .wrapCallableInEnvironmentForAuthenticatedUser(platformSecurityService::getCurrentThreadUserId)
86 84
                    .call();
87 85
            result.put("afterSwitchUserNameCall", afterSwitchUserNameCall);

@@ -9,41 +9,24 @@
Loading
9 9
 */
10 10
package org.zowe.commons.error;
11 11
12 +
import lombok.extern.slf4j.Slf4j;
13 +
import org.slf4j.Logger;
14 +
import org.slf4j.LoggerFactory;
15 +
import org.yaml.snakeyaml.Yaml;
16 +
import org.yaml.snakeyaml.error.YAMLException;
17 +
import org.zowe.commons.rest.response.*;
18 +
12 19
import java.io.IOException;
13 20
import java.io.InputStream;
14 21
import java.io.InputStreamReader;
15 22
import java.io.Reader;
16 23
import java.nio.charset.StandardCharsets;
17 24
import java.security.AccessController;
18 -
import java.security.PrivilegedActionException;
19 -
import java.security.PrivilegedExceptionAction;
20 -
import java.util.ArrayList;
21 -
import java.util.Arrays;
22 -
import java.util.Collections;
23 -
import java.util.Formatter;
24 -
import java.util.IllegalFormatConversionException;
25 -
import java.util.List;
26 -
import java.util.Locale;
27 -
import java.util.Map;
28 -
import java.util.MissingResourceException;
29 -
import java.util.Objects;
30 -
import java.util.PropertyResourceBundle;
31 -
import java.util.ResourceBundle;
25 +
import java.security.PrivilegedAction;
26 +
import java.util.*;
32 27
import java.util.concurrent.ConcurrentHashMap;
33 28
import java.util.stream.Collectors;
34 29
35 -
import org.slf4j.Logger;
36 -
import org.slf4j.LoggerFactory;
37 -
import org.yaml.snakeyaml.Yaml;
38 -
import org.yaml.snakeyaml.error.YAMLException;
39 -
import org.zowe.commons.rest.response.ApiMessage;
40 -
import org.zowe.commons.rest.response.BasicApiMessage;
41 -
import org.zowe.commons.rest.response.BasicMessage;
42 -
import org.zowe.commons.rest.response.Message;
43 -
import org.zowe.commons.rest.response.MessageType;
44 -
45 -
import lombok.extern.slf4j.Slf4j;
46 -
47 30
/**
48 31
 * Default implementation of {@link ErrorService} that loads messages from YAML
49 32
 * files.
@@ -79,7 +62,7 @@
Loading
79 62
     * Recommended way how to get an instance of ErrorService for your application.
80 63
     *
81 64
     * @return Error service that uses common messages and messages from default
82 -
     *         resource file (messages.yml).
65 +
     * resource file (messages.yml).
83 66
     */
84 67
    public static ErrorService getDefault() {
85 68
        ErrorServiceImpl errorService = new ErrorServiceImpl("/" + DEFAULT_MESSAGES_BASENAME + YAML_EXTENSION);
@@ -90,7 +73,7 @@
Loading
90 73
91 74
    /**
92 75
     * @return Returns an instance of error service with messages for the Zowe REST
93 -
     *         API Commons.
76 +
     * API Commons.
94 77
     */
95 78
    public static ErrorService getCommonsDefault() {
96 79
        ErrorServiceImpl errorService = new ErrorServiceImpl();
@@ -232,20 +215,19 @@
Loading
232 215
    }
233 216
234 217
    private String getLocalizedComponentOrUseDefault(Locale locale, String key, ErrorMessage message) {
235 -
        String component = message.getComponent();
236 -
        if (component == null) {
218 +
        String component;
219 +
        if ( message.getComponent() == null) {
237 220
            StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
238 -
            String className = stackTrace[STACK_TRACE_ELEMENT_ABOVE_CREATEAPIMESSAGE_METHOD].getClassName();
239 -
            component = className;
221 +
            component = stackTrace[STACK_TRACE_ELEMENT_ABOVE_CREATEAPIMESSAGE_METHOD].getClassName();
240 222
        } else {
241 -
            component = localizedText(locale, key + ".component", component);
223 +
            component = localizedText(locale, key + ".component", message.getComponent());
242 224
        }
243 225
        return component;
244 226
    }
245 227
246 228
    private String localizedText(Locale locale, String key, String defaultText) {
247 229
        if (locale != null) {
248 -
            for (int i = baseNames.size() -1; i >= 0; i--) {
230 +
            for (int i = baseNames.size() - 1; i >= 0; i--) {
249 231
                String baseName = baseNames.get(i);
250 232
                ResourceBundle bundle = getResourceBundle(baseName, locale);
251 233
                if (bundle == null) {
@@ -282,23 +264,24 @@
Loading
282 264
283 265
    private Object[] validateParameters(ErrorMessage message, String key, Object... parameters) {
284 266
        if (message.getKey().equals(INVALID_KEY_MESSAGE)) {
285 -
            return new Object[] { key };
267 +
            return new Object[]{key};
286 268
        } else {
287 269
            return parameters;
288 270
        }
289 271
    }
272 +
290 273
    /**
291 274
     * Custom implementation of {@code ResourceBundle.Control}, adding support for
292 275
     * UTF-8.
293 276
     */
294 -
    class ErrorServiceControl extends ResourceBundle.Control {
277 +
    static class ErrorServiceControl extends ResourceBundle.Control {
295 278
        protected ResourceBundle loadBundle(Reader reader) throws IOException {
296 279
            return new PropertyResourceBundle(reader);
297 280
        }
298 281
299 282
        @Override
300 283
        public ResourceBundle newBundle(String baseName, Locale locale, String format, ClassLoader loader,
301 -
                boolean reload) throws IllegalAccessException, InstantiationException, IOException {
284 +
                                        boolean reload) throws IllegalAccessException, InstantiationException, IOException {
302 285
            if (format.equals("java.properties")) {
303 286
                return newJavaPropertiesBundle(baseName, locale, loader);
304 287
            } else {
@@ -308,20 +291,23 @@
Loading
308 291
309 292
        private ResourceBundle newJavaPropertiesBundle(String baseName, Locale locale, ClassLoader loader)
310 293
                throws IOException {
311 -
            String bundleName = toBundleName(baseName, locale);
312 -
            String resourceName = toResourceName(bundleName, "properties");
313 -
            ClassLoader classLoader = loader;
314 -
            InputStream inputStream;
315 -
            try {
316 -
                inputStream = AccessController.doPrivileged((PrivilegedExceptionAction<InputStream>) () -> {
317 -
                    InputStream is = null;
318 -
                    is = classLoader.getResourceAsStream(resourceName);
319 -
                    return is;
320 -
                });
321 -
            } catch (PrivilegedActionException ex) {
322 -
                throw (IOException) ex.getException();
294 +
            try (
295 +
                    InputStream is = loader.getResourceAsStream(getResourceName(baseName, locale));
296 +
                    InputStream pid = AccessController.doPrivileged(getPrivilegedAction(is))
297 +
            ) {
298 +
                return loadBundleFromInputStream(pid);
323 299
            }
324 -
            return loadBundleFromInputStream(inputStream);
300 +
        }
301 +
302 +
        private String getResourceName(
303 +
                String baseName, Locale locale
304 +
        ) {
305 +
            String bundleName = toBundleName(baseName, locale);
306 +
            return toResourceName(bundleName, "properties");
307 +
        }
308 +
309 +
        private <T> PrivilegedAction<T> getPrivilegedAction(T in) {
310 +
            return () -> in;
325 311
        }
326 312
327 313
        private ResourceBundle loadBundleFromInputStream(InputStream inputStream) throws IOException {

@@ -9,12 +9,14 @@
Loading
9 9
 */
10 10
package org.zowe.commons;
11 11
12 -
import java.text.Normalizer;
13 -
14 12
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
15 13
import ch.qos.logback.classic.spi.ILoggingEvent;
16 14
import ch.qos.logback.core.Layout;
17 15
import lombok.Setter;
16 +
import org.apache.commons.lang3.ArrayUtils;
17 +
18 +
import java.nio.charset.Charset;
19 +
import java.text.Normalizer;
18 20
19 21
public class AccentStrippingPatternLayerEncoder extends PatternLayoutEncoder {  // NOSONAR
20 22
    // Sonar exclusion: This class is extending Logback class that is not under our control
@@ -29,7 +31,15 @@
Loading
29 31
        String txt = layout.doLayout(event);
30 32
        if (stripAccents) {
31 33
            String stripped = stripAccents(txt);
32 -
            return (stripped != null) ? stripped.getBytes() : null;
34 +
            if (stripped == null) {
35 +
                return ArrayUtils.EMPTY_BYTE_ARRAY;
36 +
            }
37 +
38 +
            Charset charset = getCharset();
39 +
            if (charset == null) {
40 +
                charset = Charset.defaultCharset();
41 +
            }
42 +
            return stripped.getBytes(charset);
33 43
        } else {
34 44
            return super.encode(event);
35 45
        }
@@ -40,7 +50,8 @@
Loading
40 50
                : Normalizer.normalize(input, Normalizer.Form.NFD).replaceAll("\\p{InCombiningDiacriticalMarks}+", "");  // NOSONAR: Used for internal strings
41 51
    }
42 52
43 -
    void overrideLayout(Layout layout) {
53 +
    void overrideLayout(Layout<ILoggingEvent> layout) {
44 54
        this.layout = layout;
45 55
    }
56 +
46 57
}

@@ -9,6 +9,7 @@
Loading
9 9
 */
10 10
package org.zowe.commons.spring;
11 11
12 +
import lombok.extern.slf4j.Slf4j;
12 13
import org.springframework.context.i18n.LocaleContextHolder;
13 14
import org.springframework.core.annotation.Order;
14 15
import org.springframework.http.HttpHeaders;
@@ -27,8 +28,6 @@
Loading
27 28
import org.zowe.commons.error.ErrorService;
28 29
import org.zowe.commons.rest.response.ApiMessage;
29 30
30 -
import lombok.extern.slf4j.Slf4j;
31 -
32 31
/**
33 32
 * Custom error message handling for REST API
34 33
 */
@@ -47,39 +46,39 @@
Loading
47 46
48 47
    @Override
49 48
    protected ResponseEntity<Object> handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException ex,
50 -
            HttpHeaders headers, HttpStatus status, WebRequest request) {
49 +
                                                                         HttpHeaders headers, HttpStatus status, WebRequest request) {
51 50
        ApiMessage message = localizedMessage("org.zowe.commons.rest.methodNotAllowed");
52 -
        return ResponseEntity.status(HttpStatus.METHOD_NOT_ALLOWED).contentType(MediaType.APPLICATION_JSON_UTF8)
51 +
        return ResponseEntity.status(HttpStatus.METHOD_NOT_ALLOWED).contentType(MediaType.APPLICATION_JSON)
53 52
                .body(message);
54 53
    }
55 54
56 55
    @Override
57 56
    protected ResponseEntity<Object> handleNoHandlerFoundException(NoHandlerFoundException ex, HttpHeaders headers,
58 -
            HttpStatus status, WebRequest request) {
57 +
                                                                   HttpStatus status, WebRequest request) {
59 58
        ApiMessage message = localizedMessage("org.zowe.commons.rest.notFound");
60 -
        return ResponseEntity.status(HttpStatus.NOT_FOUND).contentType(MediaType.APPLICATION_JSON_UTF8).body(message);
59 +
        return ResponseEntity.status(HttpStatus.NOT_FOUND).contentType(MediaType.APPLICATION_JSON).body(message);
61 60
    }
62 61
63 62
    @Override
64 63
    protected ResponseEntity<Object> handleHttpMediaTypeNotSupported(HttpMediaTypeNotSupportedException ex,
65 -
            HttpHeaders headers, HttpStatus status, WebRequest request) {
64 +
                                                                     HttpHeaders headers, HttpStatus status, WebRequest request) {
66 65
        ApiMessage message = localizedMessage("org.zowe.commons.rest.unsupportedMediaType");
67 -
        return ResponseEntity.status(HttpStatus.UNSUPPORTED_MEDIA_TYPE).contentType(MediaType.APPLICATION_JSON_UTF8)
66 +
        return ResponseEntity.status(HttpStatus.UNSUPPORTED_MEDIA_TYPE).contentType(MediaType.APPLICATION_JSON)
68 67
                .body(message);
69 68
    }
70 69
71 -
    @ExceptionHandler({ AccessDeniedException.class })
70 +
    @ExceptionHandler({AccessDeniedException.class})
72 71
    public ResponseEntity<Object> handleAccessDeniedException(AccessDeniedException ex, WebRequest request) {
73 72
        ApiMessage message = errorService.createApiMessage(LocaleContextHolder.getLocale(), FORBIDDEN_MESSAGE_KEY,
74 73
                ex.getMessage());
75 -
        return ResponseEntity.status(HttpStatus.FORBIDDEN).contentType(MediaType.APPLICATION_JSON_UTF8).body(message);
74 +
        return ResponseEntity.status(HttpStatus.FORBIDDEN).contentType(MediaType.APPLICATION_JSON).body(message);
76 75
    }
77 76
78 -
    @ExceptionHandler({ Exception.class })
77 +
    @ExceptionHandler({Exception.class})
79 78
    public ResponseEntity<Object> handleAll(Exception ex, WebRequest request) {
80 79
        ApiMessage message = localizedMessage(INTERNAL_SERVER_ERROR_MESSAGE_KEY);
81 80
        log.error(message.toLogMessage(), ex);
82 -
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).contentType(MediaType.APPLICATION_JSON_UTF8)
81 +
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).contentType(MediaType.APPLICATION_JSON)
83 82
                .body(message);
84 83
    }
85 84
}

@@ -9,19 +9,24 @@
Loading
9 9
 */
10 10
package org.zowe.commons.zos.security.platform;
11 11
12 +
import java.io.IOException;
13 +
import java.io.ObjectInputStream;
14 +
import java.io.ObjectOutputStream;
12 15
import java.io.Serializable;
13 16
14 17
import lombok.Builder;
15 18
import lombok.Data;
16 19
17 -
@Data @Builder
18 20
/**
19 21
 * More details about the z/OS security call results.
20 -
 *
22 +
 * <p>
21 23
 * See also:
22 24
 * https://www.ibm.com/support/knowledgecenter/en/SSYKE2_8.0.0/com.ibm.java.zsecurity.api.80.doc/com.ibm.os390.security/com/ibm/os390/security/PlatformReturned.html
23 25
 */
26 +
@Data
27 +
@Builder
24 28
public class PlatformReturned implements Serializable {
29 +
25 30
    private static final long serialVersionUID = -2699057722238941755L;
26 31
27 32
    private boolean success;
@@ -31,4 +36,24 @@
Loading
31 36
    private String errnoMsg;
32 37
    private String stringRet;
33 38
    private transient Object objectRet;
39 +
40 +
    private void readObject(ObjectInputStream ois) throws IOException {
41 +
        success = ois.readBoolean();
42 +
        rc = ois.readInt();
43 +
        errno = ois.readInt();
44 +
        errno2 = ois.readInt();
45 +
        errnoMsg = ois.readUTF();
46 +
        stringRet = ois.readUTF();
47 +
        objectRet = this;
48 +
    }
49 +
50 +
    private void writeObject(ObjectOutputStream oos) throws IOException {
51 +
        oos.writeBoolean(success);
52 +
        oos.writeInt(rc);
53 +
        oos.writeInt(errno);
54 +
        oos.writeInt(errno2);
55 +
        oos.writeUTF(errnoMsg);
56 +
        oos.writeUTF(stringRet);
57 +
    }
58 +
34 59
}
Files Complexity Coverage
zowe-rest-api-commons-spring/src/main/java/org/zowe/commons 62.43% 70.18%
...-api-sample-kotlin-spring/src/main/kotlin/org/zowe/sample/kotlin/apiservice 84.62% 83.33%
zowe-rest-api-sample-spring/src/main/java/org/zowe/sample/apiservice 69.57% 73.38%
jarpatcher/src/main/java/jarpatcher/JarPatcher.java 73.85% 89.19%
Project Totals (79 files) 65.18% 73.52%
1
coverage:
2
  range: 50..100
3
  status:
4
    patch:
5
      default:
6
        target: 70
7
    project:
8
      default:
9
        target: 70
10

11
  ignore:
12
  - "**/PlatformErrno2.java"
Sunburst
The inner-most circle is the entire project, moving away from the center are folders then, finally, a single file. The size and color of each slice is representing the number of statements and the coverage, respectively.
Icicle
The top section represents the entire project. Proceeding with folders and finally individual files. The size and color of each slice is representing the number of statements and the coverage, respectively.
Grid
Each block represents a single file in the project. The size and color of each block is represented by the number of statements and the coverage, respectively.
Loading