| /* |
| * 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 static org.mockito.ArgumentMatchers.anyString; |
| import static org.mockito.ArgumentMatchers.nullable; |
| |
| import java.lang.reflect.Field; |
| import java.net.InetAddress; |
| import java.util.HashMap; |
| import java.util.Map; |
| |
| import javax.servlet.http.HttpServletRequest; |
| import javax.servlet.http.HttpServletResponse; |
| import javax.servlet.http.HttpSession; |
| |
| import org.apache.cloudstack.api.ApiConstants; |
| import org.apache.cloudstack.api.ApiErrorCode; |
| 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.api.response.LoginCmdResponse; |
| import org.apache.cloudstack.saml.SAML2AuthManager; |
| 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 com.cloud.domain.DomainVO; |
| import com.cloud.domain.dao.DomainDao; |
| import com.cloud.user.Account; |
| import com.cloud.user.AccountService; |
| import com.cloud.user.User; |
| 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.HttpUtils; |
| |
| import junit.framework.TestCase; |
| |
| @RunWith(MockitoJUnitRunner.class) |
| public class ListAndSwitchSAMLAccountCmdTest extends TestCase { |
| @Mock |
| ApiServerService apiServer; |
| |
| @Mock |
| SAML2AuthManager samlAuthManager; |
| |
| @Mock |
| AccountService accountService; |
| |
| @Mock |
| UserAccountDao userAccountDao; |
| |
| @Mock |
| UserDao userDao; |
| |
| @Mock |
| DomainDao domainDao; |
| |
| @Mock |
| HttpSession session; |
| |
| @Mock |
| HttpServletResponse resp; |
| |
| @Mock |
| HttpServletRequest req; |
| |
| @Test |
| public void testListAndSwitchSAMLAccountCmd() throws Exception { |
| // Setup |
| final Map<String, Object[]> params = new HashMap<String, Object[]>(); |
| final String sessionKeyValue = "someSessionIDValue"; |
| Mockito.when(session.getAttribute(ApiConstants.SESSIONKEY)).thenReturn(sessionKeyValue); |
| Mockito.when(session.getAttribute("userid")).thenReturn(2L); |
| params.put(ApiConstants.USER_ID, new String[]{"2"}); |
| params.put(ApiConstants.DOMAIN_ID, new String[]{"1"}); |
| Mockito.when(userDao.findByUuid(anyString())).thenReturn(new UserVO(2L)); |
| Mockito.when(domainDao.findByUuid(anyString())).thenReturn(new DomainVO()); |
| |
| // Mock/field setup |
| ListAndSwitchSAMLAccountCmd cmd = new ListAndSwitchSAMLAccountCmd(); |
| Field apiServerField = ListAndSwitchSAMLAccountCmd.class.getDeclaredField("_apiServer"); |
| apiServerField.setAccessible(true); |
| apiServerField.set(cmd, apiServer); |
| |
| Field managerField = ListAndSwitchSAMLAccountCmd.class.getDeclaredField("_samlAuthManager"); |
| managerField.setAccessible(true); |
| managerField.set(cmd, samlAuthManager); |
| |
| Field accountServiceField = BaseCmd.class.getDeclaredField("_accountService"); |
| accountServiceField.setAccessible(true); |
| accountServiceField.set(cmd, accountService); |
| |
| Field userAccountDaoField = ListAndSwitchSAMLAccountCmd.class.getDeclaredField("_userAccountDao"); |
| userAccountDaoField.setAccessible(true); |
| userAccountDaoField.set(cmd, userAccountDao); |
| |
| Field userDaoField = ListAndSwitchSAMLAccountCmd.class.getDeclaredField("_userDao"); |
| userDaoField.setAccessible(true); |
| userDaoField.set(cmd, userDao); |
| |
| Field domainDaoField = ListAndSwitchSAMLAccountCmd.class.getDeclaredField("_domainDao"); |
| domainDaoField.setAccessible(true); |
| domainDaoField.set(cmd, domainDao); |
| |
| // invalid session test |
| try { |
| cmd.authenticate("command", params, null, null, HttpUtils.RESPONSE_TYPE_JSON, new StringBuilder(), req, resp); |
| } catch (ServerApiException exception) { |
| assertEquals(exception.getErrorCode(), ApiErrorCode.UNAUTHORIZED); |
| } finally { |
| Mockito.verify(accountService, Mockito.times(0)).getUserAccountById(Mockito.anyLong()); |
| } |
| |
| // invalid sessionkey value test |
| params.put(ApiConstants.SESSIONKEY, new String[]{"someOtherValue"}); |
| try { |
| Mockito.when(session.isNew()).thenReturn(false); |
| cmd.authenticate("command", params, session, null, HttpUtils.RESPONSE_TYPE_JSON, new StringBuilder(), req, resp); |
| } catch (ServerApiException exception) { |
| assertEquals(exception.getErrorCode(), ApiErrorCode.UNAUTHORIZED); |
| } finally { |
| Mockito.verify(accountService, Mockito.times(0)).getUserAccountById(Mockito.anyLong()); |
| } |
| |
| // valid sessionkey value test |
| params.put(ApiConstants.SESSIONKEY, new String[]{sessionKeyValue}); |
| try { |
| cmd.authenticate("command", params, session, null, HttpUtils.RESPONSE_TYPE_JSON, new StringBuilder(), req, resp); |
| } catch (ServerApiException exception) { |
| assertEquals(exception.getErrorCode(), ApiErrorCode.ACCOUNT_ERROR); |
| } finally { |
| Mockito.verify(accountService, Mockito.times(1)).getUserAccountById(Mockito.anyLong()); |
| } |
| |
| // valid sessionkey, invalid useraccount type (non-saml) value test |
| UserAccountVO mockedUserAccount = new UserAccountVO(); |
| mockedUserAccount.setId(2L); |
| mockedUserAccount.setAccountState(Account.State.ENABLED.toString()); |
| mockedUserAccount.setUsername("someUsername"); |
| mockedUserAccount.setExternalEntity("some IDP ID"); |
| mockedUserAccount.setDomainId(0L); |
| mockedUserAccount.setSource(User.Source.UNKNOWN); |
| Mockito.when(accountService.getUserAccountById(Mockito.anyLong())).thenReturn(mockedUserAccount); |
| try { |
| cmd.authenticate("command", params, session, null, HttpUtils.RESPONSE_TYPE_JSON, new StringBuilder(), req, resp); |
| } catch (ServerApiException exception) { |
| assertEquals(exception.getErrorCode(), ApiErrorCode.ACCOUNT_ERROR); |
| } finally { |
| // accountService should have been called twice by now, for this case and the case above |
| Mockito.verify(accountService, Mockito.times(2)).getUserAccountById(Mockito.anyLong()); |
| } |
| |
| // all valid test |
| mockedUserAccount.setSource(User.Source.SAML2); |
| Mockito.when(accountService.getUserAccountById(Mockito.anyLong())).thenReturn(mockedUserAccount); |
| Mockito.when(apiServer.verifyUser(Mockito.anyLong())).thenReturn(true); |
| LoginCmdResponse loginCmdResponse = new LoginCmdResponse(); |
| loginCmdResponse.setUserId("1"); |
| loginCmdResponse.setDomainId("1"); |
| loginCmdResponse.setType("1"); |
| loginCmdResponse.setUsername("userName"); |
| loginCmdResponse.setAccount("someAccount"); |
| loginCmdResponse.setFirstName("firstName"); |
| loginCmdResponse.setLastName("lastName"); |
| loginCmdResponse.setSessionKey("newSessionKeyString"); |
| loginCmdResponse.set2FAenabled("false"); |
| Mockito.when(apiServer.loginUser(nullable(HttpSession.class), nullable(String.class), nullable(String.class), |
| nullable(Long.class), nullable(String.class), nullable(InetAddress.class), nullable(Map.class))).thenReturn(loginCmdResponse); |
| Mockito.doNothing().when(resp).sendRedirect(nullable(String.class)); |
| try { |
| cmd.authenticate("command", params, session, null, HttpUtils.RESPONSE_TYPE_JSON, new StringBuilder(), req, resp); |
| } catch (ServerApiException exception) { |
| fail("SAML list and switch account API failed to pass for all valid data: " + exception.getMessage()); |
| } finally { |
| // accountService should have been called 4 times by now, for this case twice and 2 for cases above |
| Mockito.verify(accountService, Mockito.times(4)).getUserAccountById(Mockito.anyLong()); |
| Mockito.verify(resp, Mockito.times(1)).sendRedirect(anyString()); |
| } |
| } |
| |
| @Test |
| public void testGetAPIType() { |
| Assert.assertTrue(new ListAndSwitchSAMLAccountCmd().getAPIType() == APIAuthenticationType.READONLY_API); |
| } |
| |
| } |