/**
* Waffle (https://github.com/Waffle/waffle)
*
* Copyright (c) 2010-2016 Application Security, Inc.
*
* All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse
* Public License v1.0 which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-v10.html.
*
* Contributors: Application Security, Inc.
*/
package waffle.jaas;
import java.security.Principal;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import javax.security.auth.Subject;
import javax.security.auth.login.LoginException;
import org.assertj.core.api.Assertions;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import waffle.mock.MockWindowsAuthProvider;
import waffle.windows.auth.impl.WindowsAccountImpl;
/**
* The Class WindowsLoginModuleTests.
*
* @author dblock[at]dblock[dot]org
*/
public class WindowsLoginModuleTests {
/** The login module. */
WindowsLoginModule loginModule;
/** The provider. */
MockWindowsAuthProvider provider;
/**
* Sets the up.
*/
@Before
public void setUp() {
this.provider = new MockWindowsAuthProvider();
this.loginModule = new WindowsLoginModule();
this.loginModule.setAuth(this.provider);
}
/**
* Test initialize.
*/
@Test
public void testInitialize() {
final Subject subject = new Subject();
final UsernamePasswordCallbackHandler callbackHandler = new UsernamePasswordCallbackHandler("", "");
final Map<String, String> options = new HashMap<>();
options.put("debug", "true");
this.loginModule.initialize(subject, callbackHandler, null, options);
Assert.assertTrue(this.loginModule.isDebug());
}
/**
* Test get set auth.
*/
@Test
public void testGetSetAuth() {
Assert.assertNotNull(this.loginModule.getAuth());
this.loginModule.setAuth(null);
Assert.assertNull(this.loginModule.getAuth());
}
/**
* Test login.
*
* @throws LoginException
* the login exception
*/
@Test
public void testLogin() throws LoginException {
final Subject subject = new Subject();
final UsernamePasswordCallbackHandler callbackHandler = new UsernamePasswordCallbackHandler(
WindowsAccountImpl.getCurrentUsername(), "password");
final Map<String, String> options = new HashMap<>();
options.put("debug", "true");
this.loginModule.initialize(subject, callbackHandler, null, options);
Assert.assertTrue(this.loginModule.login());
Assert.assertEquals(0, subject.getPrincipals().size());
Assert.assertTrue(this.loginModule.commit());
Assert.assertEquals(2, subject.getPrincipals().size());
Assert.assertTrue(subject.getPrincipals().contains(new GroupPrincipal("Roles")));
for (final Principal principal : subject.getPrincipals()) {
if (principal instanceof GroupPrincipal) {
Assert.assertTrue(((GroupPrincipal) principal).isMember(new RolePrincipal("Everyone")));
Assert.assertTrue(((GroupPrincipal) principal).isMember(new RolePrincipal("Users")));
}
}
Assert.assertTrue(subject.getPrincipals().contains(new UserPrincipal(WindowsAccountImpl.getCurrentUsername())));
Assert.assertTrue(this.loginModule.logout());
Assert.assertSame(Integer.valueOf(subject.getPrincipals().size()), Integer.valueOf(0));
}
/**
* Test no callback handler.
*
* @throws LoginException
* the login exception
*/
@Test(expected = LoginException.class)
public void testNoCallbackHandler() throws LoginException {
final Subject subject = new Subject();
final Map<String, String> options = new HashMap<>();
this.loginModule.initialize(subject, null, null, options);
this.loginModule.login();
}
/**
* Test login no username.
*
* @throws LoginException
* the login exception
*/
@Test(expected = LoginException.class)
public void testLoginNoUsername() throws LoginException {
final Subject subject = new Subject();
final UsernamePasswordCallbackHandler callbackHandler = new UsernamePasswordCallbackHandler("", "");
final Map<String, String> options = new HashMap<>();
options.put("debug", "true");
this.loginModule.initialize(subject, callbackHandler, null, options);
Assert.assertFalse(this.loginModule.login());
Assert.fail("Expected LoginException");
}
/**
* Test role format none.
*
* @throws LoginException
* the login exception
*/
@Test
public void testRoleFormatNone() throws LoginException {
final Subject subject = new Subject();
final UsernamePasswordCallbackHandler callbackHandler = new UsernamePasswordCallbackHandler(
WindowsAccountImpl.getCurrentUsername(), "password");
final Map<String, String> options = new HashMap<>();
options.put("debug", "true");
options.put("roleFormat", "none");
this.loginModule.initialize(subject, callbackHandler, null, options);
Assert.assertTrue(this.loginModule.login());
Assert.assertTrue(this.loginModule.commit());
Assert.assertEquals(1, subject.getPrincipals().size());
}
/**
* Test role format both.
*
* @throws LoginException
* the login exception
*/
@Test
public void testRoleFormatBoth() throws LoginException {
final Subject subject = new Subject();
final UsernamePasswordCallbackHandler callbackHandler = new UsernamePasswordCallbackHandler(
WindowsAccountImpl.getCurrentUsername(), "password");
final Map<String, String> options = new HashMap<>();
options.put("debug", "true");
options.put("roleFormat", "both");
this.loginModule.initialize(subject, callbackHandler, null, options);
Assert.assertTrue(this.loginModule.login());
Assert.assertTrue(this.loginModule.commit());
Assert.assertEquals(2, subject.getPrincipals().size());
Assert.assertTrue(subject.getPrincipals().contains(new GroupPrincipal("Roles")));
for (final Principal principal : subject.getPrincipals()) {
if (principal instanceof GroupPrincipal) {
int size = 0;
int sidSize = 0;
Enumeration<? extends Principal> groupPrincipal = ((GroupPrincipal) principal).members();
while (groupPrincipal.hasMoreElements()) {
if (groupPrincipal.nextElement().getName().startsWith("S-")) {
sidSize++;
}
size++;
}
Assert.assertEquals(4, size);
Assert.assertTrue(((GroupPrincipal) principal).isMember(new RolePrincipal("Everyone")));
Assert.assertTrue(((GroupPrincipal) principal).isMember(new RolePrincipal("Users")));
Assert.assertEquals(2, sidSize);
}
}
}
/**
* Test principal format both.
*
* @throws LoginException
* the login exception
*/
@Test
public void testPrincipalFormatBoth() throws LoginException {
final Subject subject = new Subject();
final UsernamePasswordCallbackHandler callbackHandler = new UsernamePasswordCallbackHandler(
WindowsAccountImpl.getCurrentUsername(), "password");
final Map<String, String> options = new HashMap<>();
options.put("debug", "true");
options.put("principalFormat", "both");
options.put("roleFormat", "none");
this.loginModule.initialize(subject, callbackHandler, null, options);
Assert.assertTrue(this.loginModule.login());
Assert.assertTrue(this.loginModule.commit());
Assert.assertEquals(2, subject.getPrincipals().size());
}
/**
* Test role format sid.
*
* @throws LoginException
* the login exception
*/
@Test
public void testRoleFormatSid() throws LoginException {
final Subject subject = new Subject();
final UsernamePasswordCallbackHandler callbackHandler = new UsernamePasswordCallbackHandler(
WindowsAccountImpl.getCurrentUsername(), "password");
final Map<String, String> options = new HashMap<>();
options.put("debug", "true");
options.put("roleFormat", "sid");
this.loginModule.initialize(subject, callbackHandler, null, options);
Assert.assertTrue(this.loginModule.login());
Assert.assertTrue(this.loginModule.commit());
Assert.assertEquals(2, subject.getPrincipals().size());
Assert.assertTrue(subject.getPrincipals().contains(new GroupPrincipal("Roles")));
for (final Principal principal : subject.getPrincipals()) {
if (principal instanceof GroupPrincipal) {
int size = 0;
Enumeration<? extends Principal> groupPrincipal = ((GroupPrincipal) principal).members();
while (groupPrincipal.hasMoreElements()) {
if (groupPrincipal.nextElement().getName().startsWith("S-")) {
size++;
}
}
Assert.assertEquals(2, size);
} else {
Assert.assertTrue(principal.getName().equals(WindowsAccountImpl.getCurrentUsername()));
}
}
}
/**
* Test role unique.
*
* @throws LoginException
* the login exception
*/
@Test
public void testRoleUnique() throws LoginException {
final Subject subject = new Subject();
// the mock has an "Everyone" group
final UsernamePasswordCallbackHandler callbackHandler = new UsernamePasswordCallbackHandler(
WindowsAccountImpl.getCurrentUsername(), "password");
this.provider.addGroup("Group 1");
this.provider.addGroup("Group 1");
final Map<String, String> options = new HashMap<>();
options.put("debug", "true");
this.loginModule.initialize(subject, callbackHandler, null, options);
Assert.assertTrue(this.loginModule.login());
Assert.assertTrue(this.loginModule.commit());
Assert.assertEquals(2, subject.getPrincipals().size());
Assert.assertTrue(subject.getPrincipals().contains(new GroupPrincipal("Roles")));
for (final Principal principal : subject.getPrincipals()) {
if (principal instanceof GroupPrincipal) {
int size = 0;
Enumeration<? extends Principal> groupPrincipal = ((GroupPrincipal) principal).members();
while (groupPrincipal.hasMoreElements()) {
groupPrincipal.nextElement();
size++;
}
Assert.assertEquals(3, size);
Assert.assertTrue(((GroupPrincipal) principal).isMember(new RolePrincipal("Everyone")));
Assert.assertTrue(((GroupPrincipal) principal).isMember(new RolePrincipal("Users")));
Assert.assertTrue(((GroupPrincipal) principal).isMember(new RolePrincipal("Group 1")));
}
}
}
/**
* Test guest login.
*
* @throws LoginException
* the login exception
*/
@Test(expected = LoginException.class)
public void testGuestLogin() throws LoginException {
final Subject subject = new Subject();
final UsernamePasswordCallbackHandler callbackHandler = new UsernamePasswordCallbackHandler("Guest",
"password");
final Map<String, String> options = new HashMap<>();
options.put("debug", "true");
this.loginModule.initialize(subject, callbackHandler, null, options);
Assert.assertTrue(this.loginModule.isAllowGuestLogin());
Assert.assertTrue(this.loginModule.login());
Assert.assertEquals(0, subject.getPrincipals().size());
Assert.assertTrue(this.loginModule.commit());
Assert.assertEquals(2, subject.getPrincipals().size());
Assert.assertTrue(subject.getPrincipals().contains(new GroupPrincipal("Roles")));
for (final Principal principal : subject.getPrincipals()) {
if (principal instanceof GroupPrincipal) {
Assert.assertTrue(((GroupPrincipal) principal).isMember(new RolePrincipal("Everyone")));
Assert.assertTrue(((GroupPrincipal) principal).isMember(new RolePrincipal("Users")));
}
}
this.loginModule.setAllowGuestLogin(false);
Assert.assertTrue(this.loginModule.login());
Assert.fail("expected LoginException");
}
/**
* Test abort.
*
* @throws LoginException
* the login exception
*/
@Test
public void testAbort() throws LoginException {
final Subject subject = new Subject();
final UsernamePasswordCallbackHandler callbackHandler = new UsernamePasswordCallbackHandler("Guest",
"password");
final Map<String, String> options = new HashMap<>();
options.put("debug", "true");
this.loginModule.initialize(subject, callbackHandler, null, options);
Assert.assertTrue(this.loginModule.login());
this.loginModule.abort();
Assertions.assertThat(subject.getPrincipals().size()).isEqualTo(0);
}
}