Path: blob/master/test/jdk/javax/security/auth/login/modules/JaasModularClientTest.java
51695 views
/*1* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223import java.nio.file.Files;24import java.nio.file.Path;25import java.nio.file.Paths;26import java.nio.file.StandardCopyOption;27import java.util.Collections;28import java.util.LinkedList;29import java.util.List;30import java.util.Arrays;31import java.io.File;32import java.io.OutputStream;33import java.lang.module.ModuleDescriptor;34import java.lang.module.ModuleDescriptor.Builder;35import jdk.internal.module.ModuleInfoWriter;36import java.util.stream.Stream;37import jdk.test.lib.process.ProcessTools;38import jdk.test.lib.process.OutputAnalyzer;39import jdk.test.lib.util.JarUtils;4041/*42* @test43* @bug 8078813 818331044* @summary Test custom JAAS login module with all possible modular option.45* @library /test/lib46* @modules java.base/jdk.internal.module47* @build jdk.test.lib.util.JarUtils48* @build TestLoginModule JaasClient49* @run main JaasModularClientTest false50* @run main JaasModularClientTest true51*/52public class JaasModularClientTest {5354private static final Path SRC = Paths.get(System.getProperty("test.src"));55private static final Path TEST_CLASSES56= Paths.get(System.getProperty("test.classes"));57private static final Path ARTIFACT_DIR = Paths.get("jars");58private static final String PS = File.pathSeparator;59private static final String L_TYPE = "login.TestLoginModule";60private static final String C_TYPE = "client.JaasClient";6162/**63* Here is the naming convention followed.64* l.jar - Unnamed login module jar.65* ml.jar - Modular login module jar.66* msl.jar - Modular login module jar provides login module service67* through module-info68* c.jar - Unnamed client jar.69* mc.jar - Modular client jar.70* mcs.jar - Modular client jar uses login module service through71* module-info.72* amc.jar - Modular client used for automatic login module jar.73* amcs.jar - Modular client used for automatic login module jar and uses74* login module service through module-info.75*/76private static final Path L_JAR = artifact("l.jar");77private static final Path ML_JAR = artifact("ml.jar");78private static final Path MSL_JAR = artifact("msl.jar");79private static final Path C_JAR = artifact("c.jar");80private static final Path MC_JAR = artifact("mc.jar");81private static final Path MCS_JAR = artifact("mcs.jar");82private static final Path AMC_JAR = artifact("amc.jar");83private static final Path AMCS_JAR = artifact("amcs.jar");8485private final String unnL;86private final String modL;87private final String unnC;88private final String modC;89private final String autoMC;90// Common set of VM arguments used in all test cases91private final List<String> commonArgs;9293public JaasModularClientTest(boolean service) {9495System.out.printf("%n*** Login Module defined as service in "96+ "module-info: %s ***%n%n", service);97List<String> argList = new LinkedList<>();98argList.add("-Djava.security.auth.login.config="99+ toAbsPath(SRC.resolve("jaas.conf")));100commonArgs = Collections.unmodifiableList(argList);101102// Based on Testcase, select unnamed/modular jar files to use.103unnL = toAbsPath(L_JAR);104modL = toAbsPath(service ? MSL_JAR : ML_JAR);105unnC = toAbsPath(C_JAR);106modC = toAbsPath(service ? MCS_JAR : MC_JAR);107autoMC = toAbsPath(service ? AMCS_JAR : AMC_JAR);108}109110/*111* Test cases are based on the following logic,112* for (definedAs : {"Service in module-info", "Class Type"}) {113* for (clientType : {"NAMED", "AUTOMATIC", "UNNAMED"}) {114* for (loginModuleType : {"NAMED", "AUTOMATIC", "UNNAMED"}) {115* Create and run java command for each possible case116* }117* }118* }119*/120public static void main(String[] args) throws Exception {121122// Generates unnamed and modular jars.123setUp();124boolean service = Boolean.valueOf(args[0]);125JaasModularClientTest test = new JaasModularClientTest(service);126test.process();127}128129private void process() throws Exception {130131// Case: NAMED-NAMED, NAMED-AUTOMATIC, NAMED-UNNAMED132System.out.println("Case: Modular Client and Modular Login module.");133execute(String.format("--module-path %s%s%s -m mc/%s",134modC, PS, modL, C_TYPE));135System.out.println("Case: Modular Client and automatic Login module.");136execute(String.format("--module-path %s%s%s --add-modules=l -m mc/%s",137autoMC, PS, unnL, C_TYPE));138System.out.println("Case: Modular Client and unnamed Login module.");139execute(String.format("--module-path %s -cp %s -m mc/%s", autoMC,140unnL, C_TYPE));141142// Case: AUTOMATIC-NAMED, AUTOMATIC-AUTOMATIC, AUTOMATIC-UNNAMED143System.out.println("Case: Automatic Client and modular Login module.");144execute(String.format("--module-path %s%s%s --add-modules=ml -m c/%s",145unnC, PS, modL, C_TYPE));146System.out.println("Case: Automatic Client and automatic Login module");147execute(String.format("--module-path %s%s%s --add-modules=l -m c/%s",148unnC, PS, unnL, C_TYPE));149System.out.println("Case: Automatic Client and unnamed Login module.");150execute(String.format("--module-path %s -cp %s -m c/%s", unnC,151unnL, C_TYPE));152153// Case: UNNAMED-NAMED, UNNAMED-AUTOMATIC, UNNAMED-UNNAMED154System.out.println("Case: Unnamed Client and modular Login module.");155execute(String.format("-cp %s --module-path %s --add-modules=ml %s",156unnC, modL, C_TYPE));157System.out.println("Case: Unnamed Client and automatic Login module.");158execute(String.format("-cp %s --module-path %s --add-modules=l %s",159unnC, unnL, C_TYPE));160System.out.println("Case: Unnamed Client and unnamed Login module.");161execute(String.format("-cp %s%s%s %s", unnC, PS, unnL, C_TYPE));162163// Case: unnamed jars in --module-path and modular jars in -cp.164System.out.println(165"Case: Unnamed Client and Login module from modulepath.");166execute(String.format("--module-path %s%s%s --add-modules=l -m c/%s",167unnC, PS, unnL, C_TYPE));168System.out.println(169"Case: Modular Client and Login module in classpath.");170execute(String.format("-cp %s%s%s %s", modC, PS, modL, C_TYPE));171}172173/**174* Execute with command arguments and process the result.175*/176private void execute(String args) throws Exception {177178String[] safeArgs = Stream.concat(commonArgs.stream(),179Stream.of(args.split("\\s+"))).filter(s -> {180if (s.contains(" ")) {181throw new RuntimeException("No spaces in args");182}183return !s.isEmpty();184}).toArray(String[]::new);185OutputAnalyzer out = ProcessTools.executeTestJvm(safeArgs);186// Handle response.187if (out.getExitValue() != 0) {188System.out.printf("OUTPUT: %s", out.getOutput());189throw new RuntimeException("FAIL: Unknown failure occured.");190} else {191System.out.println("Passed.");192}193}194195/**196* Creates Unnamed/modular jar files for TestClient and TestClassLoader.197*/198private static void setUp() throws Exception {199200if (ARTIFACT_DIR.toFile().exists()) {201System.out.println("Skipping setup: Artifacts already exists.");202return;203}204// Generate unnamed login module jar file.205JarUtils.createJarFile(L_JAR, TEST_CLASSES,206"login/TestLoginModule.class");207// Generate unnamed client jar.208JarUtils.createJarFile(C_JAR, TEST_CLASSES, "client/JaasClient.class",209"client/JaasClient$MyCallbackHandler.class");210211Builder mBuilder = ModuleDescriptor.newModule("ml")212.requires("jdk.security.auth");213// Modular jar exports package to let the login module type accessible.214generateJar(L_JAR, ML_JAR, mBuilder.exports("login").build());215216mBuilder = ModuleDescriptor.newModule("ml")217.requires("jdk.security.auth")218.provides("javax.security.auth.spi.LoginModule",219Arrays.asList(L_TYPE));220// Modular login module as Service in module-info does not need to221// export service package.222generateJar(L_JAR, MSL_JAR, mBuilder.build());223224mBuilder = ModuleDescriptor.newModule("mc").exports("client")225.requires("jdk.security.auth");226// Generate modular client jar to use automatic login module jar.227generateJar(C_JAR, AMC_JAR, mBuilder.build());228// Generate modular client jar to use modular login module jar.229generateJar(C_JAR, MC_JAR, mBuilder.requires("ml").build());230231mBuilder = ModuleDescriptor.newModule("mc").exports("client")232.requires("jdk.security.auth")233.uses("javax.security.auth.spi.LoginModule");234// Generate modular client jar to use automatic login module service.235generateJar(C_JAR, AMCS_JAR, mBuilder.build());236// Generate modular client jar using modular login module service.237generateJar(C_JAR, MCS_JAR, mBuilder.requires("ml").build());238}239240/**241* Update Unnamed jars and include module descriptor files.242*/243private static void generateJar(Path sjar, Path djar,244ModuleDescriptor mDesc) throws Exception {245246Files.copy(sjar, djar, StandardCopyOption.REPLACE_EXISTING);247Path dir = Files.createTempDirectory("tmp");248if (mDesc != null) {249Path mi = dir.resolve("module-info.class");250try (OutputStream out = Files.newOutputStream(mi)) {251ModuleInfoWriter.write(mDesc, out);252}253System.out.format("Added 'module-info.class' in '%s'%n", djar);254}255JarUtils.updateJarFile(djar, dir);256}257258/**259* Look for file path in generated jars.260*/261private static Path artifact(String file) {262return ARTIFACT_DIR.resolve(file);263}264265/**266* Convert to absolute file path.267*/268private static String toAbsPath(Path path) {269return path.toFile().getAbsolutePath();270}271}272273274