saml: Add unit tests for saml plugin - Fixes signatures on plugin manager for ease of testing - Fixes authenticator - Adds unit testing for getType and authenticate methods for all cmd classes - Adds SAMLAuthenticator test
Signed-off-by: Rohit Yadav <rohit.ya...@shapeblue.com> Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/1d809ffa Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/1d809ffa Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/1d809ffa Branch: refs/heads/saml2 Commit: 1d809ffa6c15a0b552440842b93a8b18312656ab Parents: 26b17fa Author: Rohit Yadav <rohit.ya...@shapeblue.com> Authored: Mon Aug 25 17:32:13 2014 +0200 Committer: Rohit Yadav <rohit.ya...@shapeblue.com> Committed: Mon Aug 25 17:33:30 2014 +0200 ---------------------------------------------------------------------- .../command/SAML2LoginAPIAuthenticatorCmd.java | 12 +- .../command/SAML2LogoutAPIAuthenticatorCmd.java | 2 +- .../cloudstack/saml/SAML2UserAuthenticator.java | 6 +- .../cloudstack/SAML2UserAuthenticatorTest.java | 51 +++++- .../GetServiceProviderMetaDataCmdTest.java | 94 ++++++++++ .../SAML2LoginAPIAuthenticatorCmdTest.java | 175 +++++++++++++++++++ .../SAML2LogoutAPIAuthenticatorCmdTest.java | 93 ++++++++++ 7 files changed, 419 insertions(+), 14 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1d809ffa/plugins/user-authenticators/saml2/src/org/apache/cloudstack/api/command/SAML2LoginAPIAuthenticatorCmd.java ---------------------------------------------------------------------- diff --git a/plugins/user-authenticators/saml2/src/org/apache/cloudstack/api/command/SAML2LoginAPIAuthenticatorCmd.java b/plugins/user-authenticators/saml2/src/org/apache/cloudstack/api/command/SAML2LoginAPIAuthenticatorCmd.java index 6c46b04..07cfa39 100644 --- a/plugins/user-authenticators/saml2/src/org/apache/cloudstack/api/command/SAML2LoginAPIAuthenticatorCmd.java +++ b/plugins/user-authenticators/saml2/src/org/apache/cloudstack/api/command/SAML2LoginAPIAuthenticatorCmd.java @@ -89,7 +89,7 @@ public class SAML2LoginAPIAuthenticatorCmd extends BaseCmd implements APIAuthent @Inject ConfigurationDao _configDao; @Inject - private DomainManager _domainMgr; + DomainManager _domainMgr; SAML2AuthManager _samlAuthManager; @@ -141,7 +141,7 @@ public class SAML2LoginAPIAuthenticatorCmd extends BaseCmd implements APIAuthent return redirectUrl; } - private Response processSAMLResponse(String responseMessage) { + public Response processSAMLResponse(String responseMessage) { Response responseObject = null; try { DefaultBootstrap.bootstrap(); @@ -162,12 +162,12 @@ public class SAML2LoginAPIAuthenticatorCmd extends BaseCmd implements APIAuthent if (idps != null && idps.length > 0) { idpUrl = idps[0]; } - String redirectUrl = buildAuthnRequestUrl(idpUrl); + String redirectUrl = this.buildAuthnRequestUrl(idpUrl); resp.sendRedirect(redirectUrl); return ""; } else { final String samlResponse = ((String[])params.get(SAMLUtils.SAML_RESPONSE))[0]; - Response processedSAMLResponse = processSAMLResponse(samlResponse); + Response processedSAMLResponse = this.processSAMLResponse(samlResponse); String statusCode = processedSAMLResponse.getStatus().getStatusCode().getValue(); if (!statusCode.equals(StatusCode.SUCCESS_URI)) { throw new ServerApiException(ApiErrorCode.ACCOUNT_ERROR, _apiServer.getSerializedApiError(ApiErrorCode.ACCOUNT_ERROR.getHttpCode(), @@ -209,7 +209,7 @@ public class SAML2LoginAPIAuthenticatorCmd extends BaseCmd implements APIAuthent } String username = null; - String password = ""; + String password = SAMLUtils.generateSecureRandomId(); // Random password String firstName = ""; String lastName = ""; String timeZone = ""; @@ -229,8 +229,6 @@ public class SAML2LoginAPIAuthenticatorCmd extends BaseCmd implements APIAuthent } } - String issuer = assertion.getIssuer().getValue(); - String audience = assertion.getConditions().getAudienceRestrictions().get(0).getAudiences().get(0).getAudienceURI(); AttributeStatement attributeStatement = assertion.getAttributeStatements().get(0); List<Attribute> attributes = attributeStatement.getAttributes(); http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1d809ffa/plugins/user-authenticators/saml2/src/org/apache/cloudstack/api/command/SAML2LogoutAPIAuthenticatorCmd.java ---------------------------------------------------------------------- diff --git a/plugins/user-authenticators/saml2/src/org/apache/cloudstack/api/command/SAML2LogoutAPIAuthenticatorCmd.java b/plugins/user-authenticators/saml2/src/org/apache/cloudstack/api/command/SAML2LogoutAPIAuthenticatorCmd.java index 1c96f0b..5b94766 100644 --- a/plugins/user-authenticators/saml2/src/org/apache/cloudstack/api/command/SAML2LogoutAPIAuthenticatorCmd.java +++ b/plugins/user-authenticators/saml2/src/org/apache/cloudstack/api/command/SAML2LogoutAPIAuthenticatorCmd.java @@ -99,7 +99,7 @@ public class SAML2LogoutAPIAuthenticatorCmd extends BaseCmd implements APIAuthen params, responseType)); } - if (params.containsKey("SAMLResponse")) { + if (params != null && params.containsKey("SAMLResponse")) { try { final String samlResponse = ((String[])params.get(SAMLUtils.SAML_RESPONSE))[0]; Response processedSAMLResponse = SAMLUtils.decodeSAMLResponse(samlResponse); http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1d809ffa/plugins/user-authenticators/saml2/src/org/apache/cloudstack/saml/SAML2UserAuthenticator.java ---------------------------------------------------------------------- diff --git a/plugins/user-authenticators/saml2/src/org/apache/cloudstack/saml/SAML2UserAuthenticator.java b/plugins/user-authenticators/saml2/src/org/apache/cloudstack/saml/SAML2UserAuthenticator.java index 5cd9b52..e623fc2 100644 --- a/plugins/user-authenticators/saml2/src/org/apache/cloudstack/saml/SAML2UserAuthenticator.java +++ b/plugins/user-authenticators/saml2/src/org/apache/cloudstack/saml/SAML2UserAuthenticator.java @@ -49,7 +49,7 @@ public class SAML2UserAuthenticator extends DefaultUserAuthenticator { } else { User user = _userDao.getUser(userAccount.getId()); if (user != null && SAMLUtils.checkSAMLUserId(user.getUuid()) && - requestParameters.containsKey(SAMLUtils.SAML_RESPONSE)) { + requestParameters != null && requestParameters.containsKey(SAMLUtils.SAML_RESPONSE)) { return new Pair<Boolean, ActionOnFailedAuthentication>(true, null); } } @@ -59,8 +59,6 @@ public class SAML2UserAuthenticator extends DefaultUserAuthenticator { @Override public String encode(final String password) { - // TODO: Complete method - StringBuilder sb = new StringBuilder(32); - return sb.toString(); + return SAMLUtils.generateSecureRandomId(); } } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1d809ffa/plugins/user-authenticators/saml2/test/org/apache/cloudstack/SAML2UserAuthenticatorTest.java ---------------------------------------------------------------------- diff --git a/plugins/user-authenticators/saml2/test/org/apache/cloudstack/SAML2UserAuthenticatorTest.java b/plugins/user-authenticators/saml2/test/org/apache/cloudstack/SAML2UserAuthenticatorTest.java index 8298c6c..6f5150b 100644 --- a/plugins/user-authenticators/saml2/test/org/apache/cloudstack/SAML2UserAuthenticatorTest.java +++ b/plugins/user-authenticators/saml2/test/org/apache/cloudstack/SAML2UserAuthenticatorTest.java @@ -19,21 +19,68 @@ package org.apache.cloudstack; +import com.cloud.server.auth.UserAuthenticator.ActionOnFailedAuthentication; +import com.cloud.user.UserAccountVO; +import com.cloud.user.UserVO; +import com.cloud.user.dao.UserAccountDao; +import com.cloud.user.dao.UserDao; +import com.cloud.utils.Pair; +import org.apache.cloudstack.saml.SAML2UserAuthenticator; +import org.apache.cloudstack.utils.auth.SAMLUtils; +import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; - +import org.mockito.Mock; +import org.mockito.Mockito; import org.mockito.runners.MockitoJUnitRunner; +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.Map; + @RunWith(MockitoJUnitRunner.class) public class SAML2UserAuthenticatorTest { + @Mock + UserAccountDao userAccountDao; + @Mock + UserDao userDao; + @Test public void encode() { - + Assert.assertTrue(new SAML2UserAuthenticator().encode("random String").length() == 32); } @Test public void authenticate() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { + SAML2UserAuthenticator authenticator = new SAML2UserAuthenticator(); + + Field daoField = SAML2UserAuthenticator.class.getDeclaredField("_userAccountDao"); + daoField.setAccessible(true); + daoField.set(authenticator, userAccountDao); + + Field userDaoField = SAML2UserAuthenticator.class.getDeclaredField("_userDao"); + userDaoField.setAccessible(true); + userDaoField.set(authenticator, userDao); + + UserAccountVO account = new UserAccountVO(); + account.setPassword("5f4dcc3b5aa765d61d8327deb882cf99"); + account.setId(1L); + + UserVO user = new UserVO(); + user.setUuid(SAMLUtils.createSAMLId("someUID")); + + Mockito.when(userAccountDao.getUserAccount(Mockito.anyString(), Mockito.anyLong())).thenReturn(account); + Mockito.when(userDao.getUser(Mockito.anyLong())).thenReturn(user); + + // When there is no SAMLRequest in params + Pair<Boolean, ActionOnFailedAuthentication> pair1 = authenticator.authenticate(SAMLUtils.createSAMLId("user1234"), "random", 1l, null); + Assert.assertFalse(pair1.first()); + // When there is SAMLRequest in params + Map<String, Object[]> params = new HashMap<String, Object[]>(); + params.put(SAMLUtils.SAML_RESPONSE, new Object[]{}); + Pair<Boolean, ActionOnFailedAuthentication> pair2 = authenticator.authenticate(SAMLUtils.createSAMLId("user1234"), "random", 1l, params); + Assert.assertTrue(pair2.first()); } } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1d809ffa/plugins/user-authenticators/saml2/test/org/apache/cloudstack/api/command/GetServiceProviderMetaDataCmdTest.java ---------------------------------------------------------------------- diff --git a/plugins/user-authenticators/saml2/test/org/apache/cloudstack/api/command/GetServiceProviderMetaDataCmdTest.java b/plugins/user-authenticators/saml2/test/org/apache/cloudstack/api/command/GetServiceProviderMetaDataCmdTest.java new file mode 100644 index 0000000..0f956ae --- /dev/null +++ b/plugins/user-authenticators/saml2/test/org/apache/cloudstack/api/command/GetServiceProviderMetaDataCmdTest.java @@ -0,0 +1,94 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.cloudstack.api.command; + +import com.cloud.utils.HttpUtils; +import org.apache.cloudstack.api.ApiServerService; +import org.apache.cloudstack.api.auth.APIAuthenticationType; +import org.apache.cloudstack.saml.SAML2AuthManager; +import org.apache.cloudstack.utils.auth.SAMLUtils; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.runners.MockitoJUnitRunner; + +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import java.lang.reflect.Field; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.SignatureException; +import java.security.cert.CertificateEncodingException; +import java.security.cert.CertificateParsingException; +import java.security.cert.X509Certificate; + +@RunWith(MockitoJUnitRunner.class) +public class GetServiceProviderMetaDataCmdTest { + + @Mock + ApiServerService apiServer; + + @Mock + SAML2AuthManager samlAuthManager; + + @Mock + HttpSession session; + + @Mock + HttpServletResponse resp; + + @Test + public void testAuthenticate() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, CertificateParsingException, CertificateEncodingException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { + GetServiceProviderMetaDataCmd cmd = new GetServiceProviderMetaDataCmd(); + + Field apiServerField = GetServiceProviderMetaDataCmd.class.getDeclaredField("_apiServer"); + apiServerField.setAccessible(true); + apiServerField.set(cmd, apiServer); + + Field managerField = GetServiceProviderMetaDataCmd.class.getDeclaredField("_samlAuthManager"); + managerField.setAccessible(true); + managerField.set(cmd, samlAuthManager); + + String spId = "someSPID"; + String url = "someUrl"; + X509Certificate cert = SAMLUtils.generateRandomX509Certification(); + Mockito.when(samlAuthManager.getServiceProviderId()).thenReturn(spId); + Mockito.when(samlAuthManager.getIdpSigningKey()).thenReturn(cert); + Mockito.when(samlAuthManager.getIdpSingleLogOutUrl()).thenReturn(url); + Mockito.when(samlAuthManager.getSpSingleLogOutUrl()).thenReturn(url); + + String result = cmd.authenticate("command", null, session, "random", HttpUtils.RESPONSE_TYPE_JSON, new StringBuilder(), resp); + Assert.assertTrue(result.contains("md:EntityDescriptor")); + + Mockito.verify(samlAuthManager, Mockito.atLeast(1)).getServiceProviderId(); + Mockito.verify(samlAuthManager, Mockito.atLeast(1)).getSpSingleSignOnUrl(); + Mockito.verify(samlAuthManager, Mockito.atLeast(1)).getSpSingleLogOutUrl(); + Mockito.verify(samlAuthManager, Mockito.never()).getIdpSingleSignOnUrl(); + Mockito.verify(samlAuthManager, Mockito.never()).getIdpSingleLogOutUrl(); + } + + @Test + public void testGetAPIType() { + Assert.assertTrue(new GetServiceProviderMetaDataCmd().getAPIType() == APIAuthenticationType.LOGIN_API); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1d809ffa/plugins/user-authenticators/saml2/test/org/apache/cloudstack/api/command/SAML2LoginAPIAuthenticatorCmdTest.java ---------------------------------------------------------------------- diff --git a/plugins/user-authenticators/saml2/test/org/apache/cloudstack/api/command/SAML2LoginAPIAuthenticatorCmdTest.java b/plugins/user-authenticators/saml2/test/org/apache/cloudstack/api/command/SAML2LoginAPIAuthenticatorCmdTest.java new file mode 100644 index 0000000..7747065 --- /dev/null +++ b/plugins/user-authenticators/saml2/test/org/apache/cloudstack/api/command/SAML2LoginAPIAuthenticatorCmdTest.java @@ -0,0 +1,175 @@ +package org.apache.cloudstack.api.command; + +import com.cloud.domain.Domain; +import com.cloud.user.AccountService; +import com.cloud.user.DomainManager; +import com.cloud.user.User; +import com.cloud.user.UserVO; +import com.cloud.utils.HttpUtils; +import com.cloud.utils.db.EntityManager; +import org.apache.cloudstack.api.ApiServerService; +import org.apache.cloudstack.api.BaseCmd; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.auth.APIAuthenticationType; +import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.cloudstack.saml.SAML2AuthManager; +import org.apache.cloudstack.utils.auth.SAMLUtils; +import org.joda.time.DateTime; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.runners.MockitoJUnitRunner; +import org.opensaml.common.SAMLVersion; +import org.opensaml.saml2.core.Assertion; +import org.opensaml.saml2.core.AttributeStatement; +import org.opensaml.saml2.core.AuthnStatement; +import org.opensaml.saml2.core.NameID; +import org.opensaml.saml2.core.NameIDType; +import org.opensaml.saml2.core.Response; +import org.opensaml.saml2.core.Status; +import org.opensaml.saml2.core.StatusCode; +import org.opensaml.saml2.core.Subject; +import org.opensaml.saml2.core.impl.AssertionBuilder; +import org.opensaml.saml2.core.impl.AttributeStatementBuilder; +import org.opensaml.saml2.core.impl.AuthnStatementBuilder; +import org.opensaml.saml2.core.impl.NameIDBuilder; +import org.opensaml.saml2.core.impl.ResponseBuilder; +import org.opensaml.saml2.core.impl.StatusBuilder; +import org.opensaml.saml2.core.impl.StatusCodeBuilder; +import org.opensaml.saml2.core.impl.SubjectBuilder; + +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import java.lang.reflect.Field; +import java.security.cert.X509Certificate; +import java.util.HashMap; +import java.util.Map; + +@RunWith(MockitoJUnitRunner.class) +public class SAML2LoginAPIAuthenticatorCmdTest { + + @Mock + ApiServerService apiServer; + + @Mock + SAML2AuthManager samlAuthManager; + + @Mock + ConfigurationDao configDao; + + @Mock + EntityManager entityMgr; + + @Mock + DomainManager domainMgr; + + @Mock + AccountService accountService; + + @Mock + Domain domain; + + @Mock + HttpSession session; + + @Mock + HttpServletResponse resp; + + private Response buildMockResponse() throws Exception { + Response samlMessage = new ResponseBuilder().buildObject(); + samlMessage.setID("foo"); + samlMessage.setVersion(SAMLVersion.VERSION_20); + samlMessage.setIssueInstant(new DateTime(0)); + Status status = new StatusBuilder().buildObject(); + StatusCode statusCode = new StatusCodeBuilder().buildObject(); + statusCode.setValue(StatusCode.SUCCESS_URI); + status.setStatusCode(statusCode); + samlMessage.setStatus(status); + Assertion assertion = new AssertionBuilder().buildObject(); + Subject subject = new SubjectBuilder().buildObject(); + NameID nameID = new NameIDBuilder().buildObject(); + nameID.setValue("SOME-UNIQUE-ID"); + nameID.setFormat(NameIDType.PERSISTENT); + subject.setNameID(nameID); + assertion.setSubject(subject); + AuthnStatement authnStatement = new AuthnStatementBuilder().buildObject(); + authnStatement.setSessionIndex("Some Session String"); + assertion.getAuthnStatements().add(authnStatement); + AttributeStatement attributeStatement = new AttributeStatementBuilder().buildObject(); + assertion.getAttributeStatements().add(attributeStatement); + samlMessage.getAssertions().add(assertion); + return samlMessage; + } + + @Test + public void testAuthenticate() throws Exception { + SAML2LoginAPIAuthenticatorCmd cmd = Mockito.spy(new SAML2LoginAPIAuthenticatorCmd()); + + Field apiServerField = SAML2LoginAPIAuthenticatorCmd.class.getDeclaredField("_apiServer"); + apiServerField.setAccessible(true); + apiServerField.set(cmd, apiServer); + + Field managerField = SAML2LoginAPIAuthenticatorCmd.class.getDeclaredField("_samlAuthManager"); + managerField.setAccessible(true); + managerField.set(cmd, samlAuthManager); + + Field accountServiceField = BaseCmd.class.getDeclaredField("_accountService"); + accountServiceField.setAccessible(true); + accountServiceField.set(cmd, accountService); + + Field entityMgrField = SAML2LoginAPIAuthenticatorCmd.class.getDeclaredField("_entityMgr"); + entityMgrField.setAccessible(true); + entityMgrField.set(cmd, entityMgr); + + Field domainMgrField = SAML2LoginAPIAuthenticatorCmd.class.getDeclaredField("_domainMgr"); + domainMgrField.setAccessible(true); + domainMgrField.set(cmd, domainMgr); + + Field configDaoField = SAML2LoginAPIAuthenticatorCmd.class.getDeclaredField("_configDao"); + configDaoField.setAccessible(true); + configDaoField.set(cmd, configDao); + + String spId = "someSPID"; + String url = "someUrl"; + X509Certificate cert = SAMLUtils.generateRandomX509Certification(); + Mockito.when(samlAuthManager.getServiceProviderId()).thenReturn(spId); + Mockito.when(samlAuthManager.getIdpSigningKey()).thenReturn(null); + Mockito.when(samlAuthManager.getIdpSingleSignOnUrl()).thenReturn(url); + Mockito.when(samlAuthManager.getSpSingleSignOnUrl()).thenReturn(url); + + Mockito.when(session.getAttribute(Mockito.anyString())).thenReturn(null); + Mockito.when(configDao.getValue(Mockito.anyString())).thenReturn("someString"); + + Mockito.when(domain.getId()).thenReturn(1L); + Mockito.when(domainMgr.getDomain(Mockito.anyString())).thenReturn(domain); + UserVO user = new UserVO(); + user.setUuid(SAMLUtils.createSAMLId("someUID")); + Mockito.when(entityMgr.findByUuid(Mockito.eq(User.class), Mockito.anyString())).thenReturn((User) user); + Mockito.when(apiServer.verifyUser(Mockito.anyLong())).thenReturn(false); + + Map<String, Object[]> params = new HashMap<String, Object[]>(); + + // SSO redirection test + cmd.authenticate("command", params, session, "random", HttpUtils.RESPONSE_TYPE_JSON, new StringBuilder(), resp); + Mockito.verify(resp, Mockito.times(1)).sendRedirect(Mockito.anyString()); + + // SSO SAMLResponse verification test, this should throw ServerApiException for auth failure + params.put(SAMLUtils.SAML_RESPONSE, new String[]{"Some String"}); + Mockito.stub(cmd.processSAMLResponse(Mockito.anyString())).toReturn(buildMockResponse()); + try { + cmd.authenticate("command", params, session, "random", HttpUtils.RESPONSE_TYPE_JSON, new StringBuilder(), resp); + } catch (ServerApiException ignored) { + } + Mockito.verify(configDao, Mockito.atLeastOnce()).getValue(Mockito.anyString()); + Mockito.verify(domainMgr, Mockito.times(1)).getDomain(Mockito.anyString()); + Mockito.verify(entityMgr, Mockito.times(1)).findByUuid(Mockito.eq(User.class), Mockito.anyString()); + Mockito.verify(apiServer, Mockito.times(1)).verifyUser(Mockito.anyLong()); + } + + @Test + public void testGetAPIType() { + Assert.assertTrue(new GetServiceProviderMetaDataCmd().getAPIType() == APIAuthenticationType.LOGIN_API); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1d809ffa/plugins/user-authenticators/saml2/test/org/apache/cloudstack/api/command/SAML2LogoutAPIAuthenticatorCmdTest.java ---------------------------------------------------------------------- diff --git a/plugins/user-authenticators/saml2/test/org/apache/cloudstack/api/command/SAML2LogoutAPIAuthenticatorCmdTest.java b/plugins/user-authenticators/saml2/test/org/apache/cloudstack/api/command/SAML2LogoutAPIAuthenticatorCmdTest.java new file mode 100644 index 0000000..d309abe --- /dev/null +++ b/plugins/user-authenticators/saml2/test/org/apache/cloudstack/api/command/SAML2LogoutAPIAuthenticatorCmdTest.java @@ -0,0 +1,93 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.cloudstack.api.command; + +import com.cloud.utils.HttpUtils; +import org.apache.cloudstack.api.ApiServerService; +import org.apache.cloudstack.api.auth.APIAuthenticationType; +import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.cloudstack.saml.SAML2AuthManager; +import org.apache.cloudstack.utils.auth.SAMLUtils; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.runners.MockitoJUnitRunner; + +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import java.lang.reflect.Field; +import java.security.cert.X509Certificate; + +@RunWith(MockitoJUnitRunner.class) +public class SAML2LogoutAPIAuthenticatorCmdTest { + + @Mock + ApiServerService apiServer; + + @Mock + SAML2AuthManager samlAuthManager; + + @Mock + ConfigurationDao configDao; + + @Mock + HttpSession session; + + @Mock + HttpServletResponse resp; + + @Test + public void testAuthenticate() throws Exception { + SAML2LogoutAPIAuthenticatorCmd cmd = new SAML2LogoutAPIAuthenticatorCmd(); + + Field apiServerField = SAML2LogoutAPIAuthenticatorCmd.class.getDeclaredField("_apiServer"); + apiServerField.setAccessible(true); + apiServerField.set(cmd, apiServer); + + Field managerField = SAML2LogoutAPIAuthenticatorCmd.class.getDeclaredField("_samlAuthManager"); + managerField.setAccessible(true); + managerField.set(cmd, samlAuthManager); + + Field configDaoField = SAML2LogoutAPIAuthenticatorCmd.class.getDeclaredField("_configDao"); + configDaoField.setAccessible(true); + configDaoField.set(cmd, configDao); + + String spId = "someSPID"; + String url = "someUrl"; + X509Certificate cert = SAMLUtils.generateRandomX509Certification(); + Mockito.when(samlAuthManager.getServiceProviderId()).thenReturn(spId); + Mockito.when(samlAuthManager.getIdpSigningKey()).thenReturn(cert); + Mockito.when(samlAuthManager.getIdpSingleLogOutUrl()).thenReturn(url); + Mockito.when(samlAuthManager.getSpSingleLogOutUrl()).thenReturn(url); + Mockito.when(session.getAttribute(Mockito.anyString())).thenReturn(null); + Mockito.when(configDao.getValue(Mockito.anyString())).thenReturn("someString"); + + cmd.authenticate("command", null, session, "random", HttpUtils.RESPONSE_TYPE_JSON, new StringBuilder(), resp); + Mockito.verify(resp, Mockito.times(1)).sendRedirect(Mockito.anyString()); + Mockito.verify(session, Mockito.atLeastOnce()).getAttribute(Mockito.anyString()); + } + + @Test + public void testGetAPIType() throws Exception { + Assert.assertTrue(new SAML2LogoutAPIAuthenticatorCmd().getAPIType() == APIAuthenticationType.LOGOUT_API); + } +} \ No newline at end of file