1/* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18/** 19* @author Stepan M. Mishura 20*/ 21 22package org.apache.harmony.auth.tests.javax.security.auth.login; 23 24import java.io.File; 25import java.security.Security; 26import java.util.ArrayList; 27import java.util.HashMap; 28import java.util.Hashtable; 29import java.util.Map; 30import java.util.Properties; 31 32import javax.security.auth.Subject; 33import javax.security.auth.callback.Callback; 34import javax.security.auth.callback.CallbackHandler; 35import javax.security.auth.login.AppConfigurationEntry; 36import javax.security.auth.login.Configuration; 37import javax.security.auth.login.LoginContext; 38import javax.security.auth.login.LoginException; 39import javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag; 40import javax.security.auth.spi.LoginModule; 41 42import junit.framework.TestCase; 43 44import org.apache.harmony.auth.tests.support.TestUtils; 45 46import tests.support.Support_Exec; 47 48/** 49 * Tests LoginContext class 50 */ 51public class LoginContextTest extends TestCase { 52 53 // system property to specify another login configuration file 54 private static final String AUTH_LOGIN_CONFIG = "java.security.auth.login.config"; 55 56 private static final String moduleName = "moduleName"; 57 58 private final Subject subject = new Subject(); 59 60 private final MyCallbackHandler handler = new MyCallbackHandler(); 61 62 @Override 63 protected void setUp() throws Exception { 64 super.setUp(); 65 66 Configuration.setConfiguration(new MyConfig()); 67 } 68 69 /** 70 * Constructor: LoginContext(java.lang.String) 71 * 72 * Parameters: valid app. name 73 * 74 * Expected: no exceptions 75 */ 76 public final void testLC_String() throws Exception { 77 78 // configuration contains requested login module 79 LoginContext context = new LoginContext(moduleName); 80 81 assertTrue("Requested module", MyConfig.getLastAppName() == moduleName); 82 83 //FIXME lazy subject initialization? should it be initialized in ctor? 84 assertNull("Instantiated subject", context.getSubject()); 85 } 86 87 /** 88 * Constructor: LoginContext(java.lang.String) 89 * 90 * Parameters: invalid (null app. name) 91 * 92 * Expected: LoginException 93 */ 94 public final void testLC_String_NullApp() { 95 96 try { 97 new LoginContext(null); 98 fail("No expected LoginException"); 99 } catch (LoginException e) { 100 } 101 } 102 103 /** 104 * Constructor: LoginContext(java.lang.String) 105 * 106 * Precondition: app. name absent in the current configuration 107 * 108 * Expected: LoginException 109 */ 110 public final void testLC_String_NoApp() { 111 112 // configuration doesn't contain requested application name 113 MyConfig.resetConfiguration(); 114 115 try { 116 new LoginContext(moduleName); 117 fail("No expected LoginException"); 118 } catch (LoginException e) { 119 assertEquals("Default module", "other", MyConfig.getLastAppName()); 120 } 121 } 122 123 /** 124 * Constructor: LoginContext(java.lang.String) 125 * 126 * Precondition: configuration contains requested login module and 127 * default callback handler is specified via security 128 * property but its class is not accessible 129 * 130 * Expected: LoginException 131 */ 132 public final void testLC_String_InaccessibleCallbackHandler() { 133 134 try { 135 Security.setProperty("auth.login.defaultCallbackHandler", 136 "absentCallBackhandlerClassName"); 137 138 new LoginContext(moduleName); 139 fail("No expected LoginException"); 140 } catch (LoginException e) { 141 assertTrue("Default module", 142 MyConfig.getLastAppName() == moduleName); 143 } finally { 144 //FIXME how to reset security property correctly? 145 Security.setProperty("auth.login.defaultCallbackHandler", ""); 146 } 147 } 148 149 /** 150 * Constructor: LoginContext(java.lang.String) 151 * 152 * Precondition: configuration contains requested login module and 153 * default callback handler is specified via security 154 * property but its class doesn't implement 155 * CallbackHandler interface 156 * 157 * Expected: LoginException 158 */ 159 public final void testLC_String_InvalidCallbackHandler() throws Exception { 160 161 try { 162 Security.setProperty("auth.login.defaultCallbackHandler", 163 LoginContextTest.class.getName()); 164 165 new LoginContext(moduleName); 166 fail("No expected ClassCastException"); 167 } catch (ClassCastException e) { 168 } finally { 169 //FIXME how to reset security property correctly? 170 Security.setProperty("auth.login.defaultCallbackHandler", ""); 171 } 172 } 173 174 /** 175 * Constructor: LoginContext(java.lang.String) 176 * 177 * Expected: creation of default callback handler 178 */ 179 public final void testLC_String_InitCallbackHandler() throws Exception { 180 181 // checks initialization of specified callback handler 182 MyCallbackHandler.initialized = false; 183 try { 184 Security 185 .setProperty("auth.login.defaultCallbackHandler", 186 MyCallbackHandler.class.getName()); 187 188 new LoginContext(moduleName); 189 190 assertTrue("Initialization", MyCallbackHandler.initialized); 191 } finally { 192 //FIXME how to reset security property correctly? 193 Security.setProperty("auth.login.defaultCallbackHandler", ""); 194 } 195 } 196 197 /** 198 * Constructor: LoginContext(java.lang.String) 199 * 200 * Precondition: parameters for login module initialization 201 * are created in the constructor above 202 * 203 * Expected: not null subject, null callback handler or 204 * wrapped default callback handler, not null shared 205 * state and not null options. 206 */ 207 public final void testLC_String_LoginModuleInitialize() throws Exception { 208 209 Hashtable<String, Object> options = new Hashtable<String, Object>(); 210 211 // add required module to the current configuration 212 MyConfig.addRequired("MyLoginModule", options); 213 214 // reset initialized login modules list 215 MyLoginModule.reset(); 216 217 LoginContext context = new LoginContext(moduleName); 218 219 context.login(); 220 221 // only one module must be created 222 assertEquals("Number of modules", 1, MyLoginModule.list.size()); 223 224 MyLoginModule module = MyLoginModule.list.get(0); 225 226 // login context instantiates subject object itself. 227 assertNotNull("Subject", module.subject); 228 assertTrue("getSubject", module.subject == context.getSubject()); 229 230 // login context doesn't have callback handler 231 assertNull("Handler", module.handler); 232 233 // login context provides login module with shared state object 234 assertNotNull("Shared state", module.sharedState); 235 236 // login context provides login module with module's options 237 assertTrue("Option references", module.options != options); 238 assertEquals("Option objects", module.options, options); 239 240 // checks initialization of specified callback handler 241 MyLoginModule.reset(); 242 try { 243 Security 244 .setProperty("auth.login.defaultCallbackHandler", 245 MyCallbackHandler.class.getName()); 246 247 context = new LoginContext(moduleName); 248 249 context.login(); 250 251 // TODO how to test default callback handler wrapping for LoginContext(java.lang.String)? 252 253 // FIXME wrap a handler 254 //assertFalse("Handler", MyLoginModule.handler.getClass().equals( 255 // MyCallbackHandler.class)); 256 } finally { 257 // FIXME how to reset security property correctly? 258 Security.setProperty("auth.login.defaultCallbackHandler", ""); 259 } 260 } 261 262 /** 263 * Constructor: LoginContext(String, CallbackHandler) 264 * 265 * Parameters: are valid 266 * 267 * Expected: no exceptions 268 */ 269 public final void testLC_StringCallbackHandler() throws Exception { 270 271 LoginContext context = new LoginContext(moduleName, handler); 272 273 assertTrue("Requested module", MyConfig.getLastAppName() == moduleName); 274 275 //FIXME lazy subject initialization? should it be initialized in ctor? 276 assertNull("Instantiated subject", context.getSubject()); 277 } 278 279 /** 280 * Constructor: LoginContext(String, CallbackHandler) 281 * 282 * Parameters: invalid (null app. name) 283 * 284 * Expected: LoginException 285 */ 286 public final void testLC_StringCallbackHandler_NullApp() { 287 288 try { 289 new LoginContext(null, handler); 290 fail("No expected LoginException"); 291 } catch (LoginException e) { 292 } 293 } 294 295 /** 296 * Constructor: LoginContext(String, CallbackHandler) 297 * 298 * Parameters: invalid (null callback handler) 299 * 300 * Expected: LoginException 301 */ 302 public final void testLC_StringCallbackHandler_NullCallbackHandler() { 303 304 try { 305 new LoginContext(moduleName, (CallbackHandler) null); 306 fail("No expected LoginException"); 307 } catch (LoginException e) { 308 } 309 } 310 311 /** 312 * Constructor: LoginContext(String, CallbackHandler) 313 * 314 * Precondition: app. name absent in the current configuration 315 * 316 * Expected: LoginException 317 */ 318 public final void testLC_StringCallbackHandler_NoApp() { 319 320 // configuration doesn't contain requested application name 321 MyConfig.resetConfiguration(); 322 323 try { 324 new LoginContext(moduleName, handler); 325 fail("No expected LoginException"); 326 } catch (LoginException e) { 327 assertEquals("Default module", "other", MyConfig.getLastAppName()); 328 } 329 } 330 331 /** 332 * Constructor: LoginContext(String, CallbackHandler) 333 * 334 * Precondition: configuration contains requested login module and 335 * default callback handler is specified via security property 336 * 337 * Expected: no default callback handler initialization 338 */ 339 public final void testLC_StringCallbackHandler_NoInit() throws Exception { 340 341 // checks initialization of specified callback handler 342 MyCallbackHandler.initialized = false; 343 try { 344 Security 345 .setProperty("auth.login.defaultCallbackHandler", 346 MyCallbackHandler.class.getName()); 347 348 new LoginContext(moduleName, handler); 349 350 assertFalse("Initialization", MyCallbackHandler.initialized); 351 } finally { 352 //FIXME how to reset security property correctly? 353 Security.setProperty("auth.login.defaultCallbackHandler", ""); 354 } 355 } 356 357 /** 358 * Constructor: LoginContext(String, CallbackHandler) 359 * 360 * Precondition: parameters for login module initialization 361 * are created in the constructor above 362 * 363 * Expected: not null subject, wrapped provided callback handler, 364 * not null shared state and not null options. 365 */ 366 public final void testLC_StringCallbackHandler_LoginModuleInitialize() 367 throws Exception { 368 369 Hashtable<String, Object> options = new Hashtable<String, Object>(); 370 371 // add required module to the current configuration 372 MyConfig.addRequired("MyLoginModule", options); 373 374 // reset initialized login modules list 375 MyLoginModule.reset(); 376 377 LoginContext context = new LoginContext(moduleName, handler); 378 379 context.login(); 380 381 // only one module must be created 382 assertEquals("Number of modules", 1, MyLoginModule.list.size()); 383 384 MyLoginModule module = MyLoginModule.list.get(0); 385 386 // login context instantiates subject object itself. 387 assertNotNull("Subject", module.subject); 388 assertTrue("getSubject", module.subject == context.getSubject()); 389 390 // TODO how to test callback handler wrapping for LoginContext(String, CallbackHandler)? 391 392 // FIXME wrap a handler 393 //assertFalse("Handler", MyLoginModule.handler.getClass().equals( 394 // handler.getClass())); 395 396 // login context provides login module with shared state object 397 assertNotNull("Shared state", module.sharedState); 398 399 // login context provides login module with module's options 400 assertTrue("Option references", module.options != options); 401 assertEquals("Option objects", module.options, options); 402 } 403 404 /** 405 * Constructor: LoginContext(String, Subject) 406 * 407 * Parameters: are valid 408 * 409 * Expected: no exceptions 410 */ 411 public final void testLC_StringSubject() throws Exception { 412 413 LoginContext context = new LoginContext(moduleName, subject); 414 415 assertTrue("Requested module", MyConfig.getLastAppName() == moduleName); 416 assertTrue("Instantiated subject", context.getSubject() == subject); 417 } 418 419 /** 420 * Constructor: LoginContext(String, Subject) 421 * 422 * Parameters: invalid (null app. name) 423 * 424 * Expected: LoginException 425 */ 426 public final void testLC_StringSubject_NullApp() { 427 428 try { 429 new LoginContext(null, subject); 430 fail("No expected LoginException"); 431 } catch (LoginException e) { 432 } 433 } 434 435 /** 436 * Constructor: LoginContext(String, Subject) 437 * 438 * Parameters: invalid (null subject) 439 * 440 * Expected: LoginException 441 */ 442 public final void testLC_StringSubject_NullSubject() { 443 444 try { 445 new LoginContext(moduleName, (Subject) null); 446 fail("No expected LoginException"); 447 } catch (LoginException e) { 448 } 449 } 450 451 /** 452 * Constructor: LoginContext(String, Subject) 453 * 454 * Precondition: app. name absent in the current configuration 455 * 456 * Expected: LoginException 457 */ 458 public final void testLC_StringSubject_NoApp() throws Exception { 459 460 MyConfig.resetConfiguration(); 461 try { 462 new LoginContext(moduleName, subject); 463 fail("No expected LoginException"); 464 } catch (LoginException e) { 465 assertEquals("Default module", "other", MyConfig.getLastAppName()); 466 } 467 } 468 469 /** 470 * Constructor: LoginContext(String, Subject) 471 * 472 * Precondition: configuration contains requested login module and 473 * default callback handler is specified via security 474 * property but its class is not accessible 475 * 476 * Expected: LoginException 477 */ 478 public final void testLC_StringSubject_InaccessibleCallbackHandler() { 479 480 try { 481 Security.setProperty("auth.login.defaultCallbackHandler", 482 "absentCallBackhandlerClassName"); 483 484 new LoginContext(moduleName, subject); 485 fail("No expected LoginException"); 486 } catch (LoginException e) { 487 assertTrue("Default module", 488 MyConfig.getLastAppName() == moduleName); 489 } finally { 490 // FIXME how to reset security property correctly? 491 Security.setProperty("auth.login.defaultCallbackHandler", ""); 492 } 493 } 494 495 /** 496 * Constructor: LoginContext(String, Subject) 497 * 498 * Expected: creation of default callback handler 499 */ 500 public final void testLC_StringSubject_InitCallbackHandler() 501 throws Exception { 502 503 // checks initialization of specified callback handler 504 MyCallbackHandler.initialized = false; 505 try { 506 Security 507 .setProperty("auth.login.defaultCallbackHandler", 508 MyCallbackHandler.class.getName()); 509 510 new LoginContext(moduleName, subject); 511 512 assertTrue("Initialization", MyCallbackHandler.initialized); 513 } finally { 514 // FIXME how to reset security property correctly? 515 Security.setProperty("auth.login.defaultCallbackHandler", ""); 516 } 517 } 518 519 /** 520 * Constructor: LoginContext(String, Subject) 521 * 522 * Precondition: parameters for login module initialization 523 * are created in the constructor above 524 * 525 * Expected: provided subject, null callback handler or 526 * wrapped default callback handler, not null shared 527 * state and not null options. 528 */ 529 public final void testLC_StringSubject_LoginModuleInitialize() 530 throws Exception { 531 532 Hashtable<String, Object> options = new Hashtable<String, Object>(); 533 534 // add required module to the current configuration 535 MyConfig.addRequired("MyLoginModule", options); 536 537 // reset initialized login modules list 538 MyLoginModule.reset(); 539 540 LoginContext context = new LoginContext(moduleName, subject); 541 542 context.login(); 543 544 // only one module must be created 545 assertEquals("Number of modules", 1, MyLoginModule.list.size()); 546 547 MyLoginModule module = MyLoginModule.list.get(0); 548 549 // login context has provided subject 550 assertTrue("Subject", module.subject == subject); 551 assertTrue("getSubject", module.subject == context.getSubject()); 552 553 // login context doesn't have callback handler 554 assertNull("Handler", module.handler); 555 556 // login context provides login module with shared state object 557 assertNotNull("Shared state", module.sharedState); 558 559 // login context provides login module with module's options 560 assertTrue("Option references", module.options != options); 561 assertEquals("Option objects", module.options, options); 562 563 // checks initialization of specified callback handler 564 MyLoginModule.reset(); 565 try { 566 Security 567 .setProperty("auth.login.defaultCallbackHandler", 568 MyCallbackHandler.class.getName()); 569 570 context = new LoginContext(moduleName, subject); 571 572 context.login(); 573 574 // TODO how to test callback handler wrapping for LoginContext(String, Subject)? 575 576 // FIXME wrap a handler 577 //assertFalse("Handler", MyLoginModule.handler.getClass().equals( 578 // MyCallbackHandler.class)); 579 } finally { 580 Security.setProperty("auth.login.defaultCallbackHandler", ""); 581 } 582 } 583 584 /** 585 * Constructor: LoginContext(String, Subject, CallbackHandler) 586 * 587 * Parameters: are valid 588 * 589 * Expected: no exceptions 590 */ 591 public final void testLC_StringSubjectCallbackHandler() throws Exception { 592 593 LoginContext context = new LoginContext(moduleName, subject, handler); 594 595 assertTrue("Requested module", MyConfig.getLastAppName() == moduleName); 596 assertTrue("Instantiated subject", context.getSubject() == subject); 597 } 598 599 /** 600 * Constructor: LoginContext(String, Subject, CallbackHandler) 601 * 602 * Parameters: invalid (null app. name) 603 * 604 * Expected: LoginException 605 */ 606 607 public final void testLC_StringSubjectCallbackHandler_NullApp() { 608 try { 609 new LoginContext(null, subject, handler); 610 fail("No expected LoginException"); 611 } catch (LoginException e) { 612 } 613 } 614 615 /** 616 * Constructor: LoginContext(String, Subject, CallbackHandler) 617 * 618 * Parameters: invalid (null subject) 619 * 620 * Expected: LoginException 621 */ 622 public final void testLC_StringSubjectCallbackHandler_NullSubject() { 623 try { 624 new LoginContext(moduleName, null, handler); 625 fail("No expected LoginException"); 626 } catch (LoginException e) { 627 } 628 } 629 630 /** 631 * Constructor: LoginContext(String, Subject, CallbackHandler) 632 * 633 * Parameters: invalid (null callback handler) 634 * 635 * Expected: LoginException 636 */ 637 public final void testLC_StringSubjectCallbackHandler_NullCallbackHandler() { 638 try { 639 new LoginContext(moduleName, subject, null); 640 fail("No expected LoginException"); 641 } catch (LoginException e) { 642 } 643 } 644 645 /** 646 * Constructor: LoginContext(String, Subject, CallbackHandler) 647 * 648 * Precondition: app. name absent in the current configuration 649 * 650 * Expected: LoginException 651 */ 652 public final void testLC_StringSubjectCallbackHandler_NoApp() { 653 654 // configuration doesn't contain requested login module 655 MyConfig.resetConfiguration(); 656 657 try { 658 new LoginContext(moduleName, subject, handler); 659 fail("No expected LoginException"); 660 } catch (LoginException e) { 661 assertEquals("Default module", "other", MyConfig.getLastAppName()); 662 } 663 } 664 665 /** 666 * Constructor: LoginContext(String, Subject, CallbackHandler) 667 * 668 * Precondition: parameters for login module initialization 669 * are created in the constructor above 670 * 671 * Expected: provided subject, wrapped default callback handler, 672 * not null shared state and not null options. 673 */ 674 675 public final void testLC_StringSubjectCallbackHandler_LoginModuleInitialize() 676 throws Exception { 677 678 Hashtable<String, Object> options = new Hashtable<String, Object>(); 679 680 // add required module to the current configuration 681 MyConfig.addRequired("MyLoginModule", options); 682 683 // reset initialized login modules list 684 MyLoginModule.reset(); 685 686 LoginContext context = new LoginContext(moduleName, subject, handler); 687 688 context.login(); 689 690 // only one module must be created 691 assertEquals("Number of modules", 1, MyLoginModule.list.size()); 692 693 MyLoginModule module = MyLoginModule.list.get(0); 694 695 // login context has provided subject 696 assertTrue("Subject", module.subject == subject); 697 assertTrue("getSubject", module.subject == context.getSubject()); 698 699 // TODO how to test callback handler wrapping for LoginContext(String, Subject, CallbackHandler)? 700 701 // FIXME wrap a handler 702 //assertFalse("Handler", MyLoginModule.handler.getClass().equals( 703 // handler.getClass())); 704 705 // login context provides login module with shared state object 706 assertNotNull("Shared state", module.sharedState); 707 708 // login context provides login module with module's options 709 assertTrue("Option references", module.options != options); 710 assertEquals("Option objects", module.options, options); 711 } 712 713 /** 714 * Method: LoginContext.login() 715 * 716 * Precondition: returned list of login modules is empty 717 * 718 * Expected: LoginException 719 */ 720 public final void testLogin_EmptyModulesList() throws Exception { 721 722 LoginContext context = new LoginContext(moduleName); 723 724 try { 725 context.login(); 726 fail("No expected LoginException"); 727 } catch (LoginException e) { 728 } 729 } 730 731 /* 732 * Method: LoginContext.login() 733 * 734 public final void testLogin_() throws Exception { 735 736 Hashtable options = new Hashtable(); 737 738 // add required module to the current configuration 739 MyConfig.addRequired("MyLoginModule", options); 740 741 LoginContext context = new LoginContext(moduleName); 742 743 context.login(); 744 context.login(); 745 } 746 */ 747 748 public final void testLogout() { 749 //TODO Implement logout(). 750 } 751 752 public final void testGetSubject() { 753 //TODO Implement getSubject(). 754 // test failed login 755 } 756 757 /** 758 * @tests javax.security.auth.login.LoginContext 759 */ 760 public void test_LoginContext_defaultConfigProvider() throws Exception { 761 762 // test: LoginContext constructor fails because there are no config 763 // files to be read (the test is modification of test case 764 // in ConfigurationTest) 765 766 // no login.config.url.N security properties should be set 767 String javaSecurityFile = TestUtils 768 .createJavaPropertiesFile(new Properties()); 769 770 // tmp user home to avoid presence of ${user.home}/.java.login.config 771 String tmpUserHome = System.getProperty("java.io.tmpdir") 772 + File.separatorChar + "tmpUserHomeForLoginContextTest"; 773 File dir = new File(tmpUserHome); 774 if (!dir.exists()) { 775 dir.mkdirs(); 776 dir.deleteOnExit(); 777 } 778 String javaLoginConfig = tmpUserHome + File.separatorChar 779 + ".java.login.config"; 780 assertFalse("There should be no login config file: " + javaLoginConfig, 781 new File(javaLoginConfig).exists()); 782 783 String[] arg = new String[] { "-Duser.home=" + tmpUserHome, 784 "-Djava.security.properties=" + javaSecurityFile, 785 NoConfigFileToBeRead.class.getName() }; 786 787 Support_Exec.execJava(arg, null, true); 788 } 789 790 public static class NoConfigFileToBeRead { 791 792 // the test is based on assumption that security properties 793 // login.config.url.N are unset and there is no file 794 // ${user.home}/.java.login.config 795 public static void main(String[] args) throws LoginException { 796 797 //reset path to alternative configuration file 798 TestUtils.setSystemProperty(AUTH_LOGIN_CONFIG, null); 799 800 Configuration.setConfiguration(null); // reset default config 801 try { 802 // Regression for HARMONY-771 803 new LoginContext("0"); 804 fail("No expected SecurityException"); 805 } catch (SecurityException e) { 806 } 807 } 808 } 809 /** 810 * @tests javax.security.auth.login.LoginContext.login() 811 */ 812 public void test_login_resourcesLeakage() throws Exception { 813 814 // This is a compatibility test. 815 // The test verifies that LoginContext allows to invoke login() method 816 // multiple times without invoking logout() before. In testing scenario 817 // each login() invocation adds new credentials to the passed subject. 818 Configuration.setConfiguration(new Configuration() { 819 820 @Override 821 public AppConfigurationEntry[] getAppConfigurationEntry(String name) { 822 return new AppConfigurationEntry[] { new AppConfigurationEntry( 823 MyModule.class.getName(), 824 LoginModuleControlFlag.REQUIRED, 825 new HashMap<String, Object>()) }; 826 } 827 828 @Override 829 public void refresh() { 830 } 831 }); 832 833 LoginContext context = new LoginContext("moduleName", new Subject()); 834 835 context.login(); 836 context.login(); 837 838 Subject subject = context.getSubject(); 839 840 assertEquals(2, subject.getPrivateCredentials().size()); 841 assertEquals(2, subject.getPublicCredentials().size()); 842 } 843 844 public static class MyModule implements LoginModule { 845 846 Subject sub; 847 848 public boolean abort() throws LoginException { 849 return false; 850 } 851 852 public boolean commit() throws LoginException { 853 sub.getPrivateCredentials().add(new Object()); 854 return true; 855 } 856 857 public void initialize(Subject arg0, CallbackHandler arg1, 858 Map<String, ?> arg2, Map<String, ?> arg3) { 859 sub = arg0; 860 } 861 862 public boolean login() throws LoginException { 863 sub.getPublicCredentials().add(new Object()); 864 return true; 865 } 866 867 public boolean logout() throws LoginException { 868 return false; 869 } 870 } 871 872 private static class MyConfig extends Configuration { 873 874 private String appName; 875 876 private ArrayList<AppConfigurationEntry> entries; 877 878 public MyConfig() { 879 entries = new ArrayList<AppConfigurationEntry>(); 880 } 881 882 @Override 883 public AppConfigurationEntry[] getAppConfigurationEntry(String applicationName) { 884 appName = applicationName; 885 if (entries != null) { 886 if (entries.size() == 0) { 887 return new AppConfigurationEntry[0]; 888 } 889 AppConfigurationEntry[] appEntries = new AppConfigurationEntry[entries.size()]; 890 entries.toArray(appEntries); 891 return appEntries; 892 } 893 return null; 894 } 895 896 @Override 897 public void refresh() { 898 } 899 900 /** 901 * Returns the last application name requested by LoginContext constructor 902 * 903 * @return the last application name 904 */ 905 public static String getLastAppName() { 906 return ((MyConfig) Configuration.getConfiguration()).appName; 907 } 908 909 /** 910 * Reset configuration. 911 * 912 * After invocation the configuration doesn't have login modules 913 * and the method Configuration.getAppConfigurationEntry(String) 914 * always returns null; 915 */ 916 public static void resetConfiguration() { 917 ((MyConfig) Configuration.getConfiguration()).entries = null; 918 } 919 920 /** 921 * Appends required login module to the current configuration 922 */ 923 public static void addRequired(String name, Map<String, ?> options) { 924 ArrayList<AppConfigurationEntry> list = ((MyConfig) Configuration.getConfiguration()).entries; 925 926 AppConfigurationEntry entry = new AppConfigurationEntry( 927 LoginContextTest.class.getName() + '$' + name, 928 javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, 929 options); 930 931 list.add(entry); 932 } 933 } 934 935 public static class MyCallbackHandler implements CallbackHandler { 936 937 public static boolean initialized; 938 939 public MyCallbackHandler() { 940 initialized = true; 941 } 942 943 public void handle(Callback[] callbacks) { 944 } 945 } 946 947 public static class MyLoginModule implements LoginModule { 948 949 public static ArrayList<MyLoginModule> list = new ArrayList<MyLoginModule>(); 950 951 public static void reset() { 952 list = new ArrayList<MyLoginModule>(); 953 } 954 955 public boolean aborted; 956 957 public boolean commited; 958 959 public boolean initialized; 960 961 public boolean logined; 962 963 public boolean logouted; 964 965 public Subject subject; 966 967 public CallbackHandler handler; 968 969 public Map<String, ?> sharedState; 970 971 public Map<String, ?> options; 972 973 public MyLoginModule() { 974 list.add(this); 975 } 976 977 public boolean abort() throws LoginException { 978 979 if (!initialized || !logined) { 980 throw new AssertionError( 981 "MUST initialize and try to login first before abort"); 982 } 983 aborted = true; 984 return true; 985 } 986 987 public boolean commit() throws LoginException { 988 989 if (!initialized || !logined) { 990 throw new AssertionError( 991 "MUST initialize and try to login first before abort"); 992 } 993 commited = true; 994 return true; 995 } 996 997 public void initialize(Subject subject, CallbackHandler handler, 998 Map<String, ?> sharedState, Map<String, ?> options) { 999 1000 if (logined || commited || aborted) { 1001 throw new AssertionError("MUST be initialized first"); 1002 } 1003 1004 this.subject = subject; 1005 this.handler = handler; 1006 this.sharedState = sharedState; 1007 this.options = options; 1008 1009 initialized = true; 1010 } 1011 1012 public boolean login() throws LoginException { 1013 1014 if (!initialized) { 1015 throw new AssertionError("MUST be initialized first"); 1016 } 1017 if (commited || aborted) { 1018 throw new AssertionError( 1019 "MUST try to login first before commit/abort"); 1020 } 1021 logined = true; 1022 return true; 1023 } 1024 1025 public boolean logout() throws LoginException { 1026 logouted = true; 1027 return true; 1028 } 1029 } 1030 1031 public static class TestLoginModule implements LoginModule { 1032 1033 public boolean abort() throws LoginException { 1034 return false; 1035 } 1036 1037 public boolean commit() throws LoginException { 1038 return false; 1039 } 1040 1041 public void initialize(Subject arg0, CallbackHandler arg1, Map<String, ?> arg2, 1042 Map<String, ?> arg3) { 1043 } 1044 1045 public boolean login() throws LoginException { 1046 return false; 1047 } 1048 1049 public boolean logout() throws LoginException { 1050 return false; 1051 } 1052 } 1053} 1054