Search in sources :

Example 1 with LoginCmdResponse

use of org.apache.cloudstack.api.response.LoginCmdResponse in project cloudstack by apache.

the class SAML2LoginAPIAuthenticatorCmd method authenticate.

@Override
public String authenticate(final String command, final Map<String, Object[]> params, final HttpSession session, final InetAddress remoteAddress, final String responseType, final StringBuilder auditTrailSb, final HttpServletRequest req, final HttpServletResponse resp) throws ServerApiException {
    try {
        if (!params.containsKey(SAMLPluginConstants.SAML_RESPONSE) && !params.containsKey("SAMLart")) {
            String idpId = null;
            String domainPath = null;
            if (params.containsKey(ApiConstants.IDP_ID)) {
                idpId = ((String[]) params.get(ApiConstants.IDP_ID))[0];
            }
            if (params.containsKey(ApiConstants.DOMAIN)) {
                domainPath = ((String[]) params.get(ApiConstants.DOMAIN))[0];
            }
            if (domainPath != null && !domainPath.isEmpty()) {
                if (!domainPath.startsWith("/")) {
                    domainPath = "/" + domainPath;
                }
                if (!domainPath.endsWith("/")) {
                    domainPath = domainPath + "/";
                }
            }
            SAMLProviderMetadata spMetadata = samlAuthManager.getSPMetadata();
            SAMLProviderMetadata idpMetadata = samlAuthManager.getIdPMetadata(idpId);
            if (idpMetadata == null) {
                throw new ServerApiException(ApiErrorCode.PARAM_ERROR, apiServer.getSerializedApiError(ApiErrorCode.PARAM_ERROR.getHttpCode(), "IdP ID (" + idpId + ") is not found in our list of supported IdPs, cannot proceed.", params, responseType));
            }
            if (idpMetadata.getSsoUrl() == null || idpMetadata.getSsoUrl().isEmpty()) {
                throw new ServerApiException(ApiErrorCode.PARAM_ERROR, apiServer.getSerializedApiError(ApiErrorCode.PARAM_ERROR.getHttpCode(), "IdP ID (" + idpId + ") has no Single Sign On URL defined please contact " + idpMetadata.getContactPersonName() + " <" + idpMetadata.getContactPersonEmail() + ">, cannot proceed.", params, responseType));
            }
            String authnId = SAMLUtils.generateSecureRandomId();
            samlAuthManager.saveToken(authnId, domainPath, idpMetadata.getEntityId());
            s_logger.debug("Sending SAMLRequest id=" + authnId);
            String redirectUrl = SAMLUtils.buildAuthnRequestUrl(authnId, spMetadata, idpMetadata, SAML2AuthManager.SAMLSignatureAlgorithm.value());
            resp.sendRedirect(redirectUrl);
            return "";
        }
        if (params.containsKey("SAMLart")) {
            throw new ServerApiException(ApiErrorCode.UNSUPPORTED_ACTION_ERROR, apiServer.getSerializedApiError(ApiErrorCode.UNSUPPORTED_ACTION_ERROR.getHttpCode(), "SAML2 HTTP Artifact Binding is not supported", params, responseType));
        } else {
            final String samlResponse = ((String[]) params.get(SAMLPluginConstants.SAML_RESPONSE))[0];
            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(), "Identity Provider send a non-successful authentication status code", params, responseType));
            }
            String username = null;
            Issuer issuer = processedSAMLResponse.getIssuer();
            SAMLProviderMetadata spMetadata = samlAuthManager.getSPMetadata();
            SAMLProviderMetadata idpMetadata = samlAuthManager.getIdPMetadata(issuer.getValue());
            String responseToId = processedSAMLResponse.getInResponseTo();
            s_logger.debug("Received SAMLResponse in response to id=" + responseToId);
            SAMLTokenVO token = samlAuthManager.getToken(responseToId);
            if (token != null) {
                if (!(token.getEntity().equalsIgnoreCase(issuer.getValue()))) {
                    throw new ServerApiException(ApiErrorCode.ACCOUNT_ERROR, apiServer.getSerializedApiError(ApiErrorCode.ACCOUNT_ERROR.getHttpCode(), "The SAML response contains Issuer Entity ID that is different from the original SAML request", params, responseType));
                }
            } else {
                throw new ServerApiException(ApiErrorCode.ACCOUNT_ERROR, apiServer.getSerializedApiError(ApiErrorCode.ACCOUNT_ERROR.getHttpCode(), "Received SAML response for a SSO request that we may not have made or has expired, please try logging in again", params, responseType));
            }
            // Set IdpId for this session
            session.setAttribute(SAMLPluginConstants.SAML_IDPID, issuer.getValue());
            Signature sig = processedSAMLResponse.getSignature();
            if (idpMetadata.getSigningCertificate() != null && sig != null) {
                BasicX509Credential credential = new BasicX509Credential();
                credential.setEntityCertificate(idpMetadata.getSigningCertificate());
                SignatureValidator validator = new SignatureValidator(credential);
                try {
                    validator.validate(sig);
                } catch (ValidationException e) {
                    s_logger.error("SAML Response's signature failed to be validated by IDP signing key:" + e.getMessage());
                    throw new ServerApiException(ApiErrorCode.ACCOUNT_ERROR, apiServer.getSerializedApiError(ApiErrorCode.ACCOUNT_ERROR.getHttpCode(), "SAML Response's signature failed to be validated by IDP signing key", params, responseType));
                }
            }
            if (username == null) {
                username = SAMLUtils.getValueFromAssertions(processedSAMLResponse.getAssertions(), SAML2AuthManager.SAMLUserAttributeName.value());
            }
            for (Assertion assertion : processedSAMLResponse.getAssertions()) {
                if (assertion != null && assertion.getSubject() != null && assertion.getSubject().getNameID() != null) {
                    session.setAttribute(SAMLPluginConstants.SAML_NAMEID, assertion.getSubject().getNameID().getValue());
                    break;
                }
            }
            if (idpMetadata.getEncryptionCertificate() != null && spMetadata != null && spMetadata.getKeyPair() != null && spMetadata.getKeyPair().getPrivate() != null) {
                Credential credential = SecurityHelper.getSimpleCredential(idpMetadata.getEncryptionCertificate().getPublicKey(), spMetadata.getKeyPair().getPrivate());
                StaticKeyInfoCredentialResolver keyInfoResolver = new StaticKeyInfoCredentialResolver(credential);
                EncryptedKeyResolver keyResolver = new InlineEncryptedKeyResolver();
                Decrypter decrypter = new Decrypter(null, keyInfoResolver, keyResolver);
                decrypter.setRootInNewDocument(true);
                List<EncryptedAssertion> encryptedAssertions = processedSAMLResponse.getEncryptedAssertions();
                if (encryptedAssertions != null) {
                    for (EncryptedAssertion encryptedAssertion : encryptedAssertions) {
                        Assertion assertion = null;
                        try {
                            assertion = decrypter.decrypt(encryptedAssertion);
                        } catch (DecryptionException e) {
                            s_logger.warn("SAML EncryptedAssertion error: " + e.toString());
                        }
                        if (assertion == null) {
                            continue;
                        }
                        Signature encSig = assertion.getSignature();
                        if (idpMetadata.getSigningCertificate() != null && encSig != null) {
                            BasicX509Credential sigCredential = new BasicX509Credential();
                            sigCredential.setEntityCertificate(idpMetadata.getSigningCertificate());
                            SignatureValidator validator = new SignatureValidator(sigCredential);
                            try {
                                validator.validate(encSig);
                            } catch (ValidationException e) {
                                s_logger.error("SAML Response's signature failed to be validated by IDP signing key:" + e.getMessage());
                                throw new ServerApiException(ApiErrorCode.ACCOUNT_ERROR, apiServer.getSerializedApiError(ApiErrorCode.ACCOUNT_ERROR.getHttpCode(), "SAML Response's signature failed to be validated by IDP signing key", params, responseType));
                            }
                        }
                        if (assertion.getSubject() != null && assertion.getSubject().getNameID() != null) {
                            session.setAttribute(SAMLPluginConstants.SAML_NAMEID, assertion.getSubject().getNameID().getValue());
                        }
                        if (username == null) {
                            username = SAMLUtils.getValueFromAttributeStatements(assertion.getAttributeStatements(), SAML2AuthManager.SAMLUserAttributeName.value());
                        }
                    }
                }
            }
            if (username == null) {
                throw new ServerApiException(ApiErrorCode.ACCOUNT_ERROR, apiServer.getSerializedApiError(ApiErrorCode.ACCOUNT_ERROR.getHttpCode(), "Failed to find admin configured username attribute in the SAML Response. Please ask your administrator to check SAML user attribute name.", params, responseType));
            }
            UserAccount userAccount = null;
            List<UserAccountVO> possibleUserAccounts = userAccountDao.getAllUsersByNameAndEntity(username, issuer.getValue());
            if (possibleUserAccounts != null && possibleUserAccounts.size() > 0) {
                // Users can switch to other allowed accounts later
                for (UserAccountVO possibleUserAccount : possibleUserAccounts) {
                    if (possibleUserAccount.getAccountState().equals(Account.State.enabled.toString())) {
                        userAccount = possibleUserAccount;
                        break;
                    }
                }
            }
            whenFailToAuthenticateThrowExceptionOrRedirectToUrl(params, responseType, resp, issuer, userAccount);
            try {
                if (apiServer.verifyUser(userAccount.getId())) {
                    LoginCmdResponse loginResponse = (LoginCmdResponse) apiServer.loginUser(session, userAccount.getUsername(), userAccount.getUsername() + userAccount.getSource().toString(), userAccount.getDomainId(), null, remoteAddress, params);
                    SAMLUtils.setupSamlUserCookies(loginResponse, resp);
                    resp.sendRedirect(SAML2AuthManager.SAMLCloudStackRedirectionUrl.value());
                    return ApiResponseSerializer.toSerializedString(loginResponse, responseType);
                }
            } catch (CloudAuthenticationException | IOException exception) {
                s_logger.debug("SAML Login failed to log in the user due to: " + exception.getMessage());
            }
        }
    } catch (IOException e) {
        auditTrailSb.append("SP initiated SAML authentication using HTTP redirection failed:");
        auditTrailSb.append(e.getMessage());
    }
    throw new ServerApiException(ApiErrorCode.ACCOUNT_ERROR, apiServer.getSerializedApiError(ApiErrorCode.ACCOUNT_ERROR.getHttpCode(), "Unable to authenticate user while performing SAML based SSO. Please make sure your user/account has been added, enable and authorized by the admin before you can authenticate. Please contact your administrator.", params, responseType));
}
Also used : ValidationException(org.opensaml.xml.validation.ValidationException) Issuer(org.opensaml.saml2.core.Issuer) SAMLTokenVO(org.apache.cloudstack.saml.SAMLTokenVO) CloudAuthenticationException(com.cloud.exception.CloudAuthenticationException) StaticKeyInfoCredentialResolver(org.opensaml.xml.security.keyinfo.StaticKeyInfoCredentialResolver) ServerApiException(org.apache.cloudstack.api.ServerApiException) SAMLProviderMetadata(org.apache.cloudstack.saml.SAMLProviderMetadata) BasicX509Credential(org.opensaml.xml.security.x509.BasicX509Credential) Credential(org.opensaml.xml.security.credential.Credential) Assertion(org.opensaml.saml2.core.Assertion) EncryptedAssertion(org.opensaml.saml2.core.EncryptedAssertion) Decrypter(org.opensaml.saml2.encryption.Decrypter) IOException(java.io.IOException) LoginCmdResponse(org.apache.cloudstack.api.response.LoginCmdResponse) Response(org.opensaml.saml2.core.Response) HttpServletResponse(javax.servlet.http.HttpServletResponse) UserAccountVO(com.cloud.user.UserAccountVO) BasicX509Credential(org.opensaml.xml.security.x509.BasicX509Credential) EncryptedAssertion(org.opensaml.saml2.core.EncryptedAssertion) Signature(org.opensaml.xml.signature.Signature) SignatureValidator(org.opensaml.xml.signature.SignatureValidator) InlineEncryptedKeyResolver(org.opensaml.xml.encryption.InlineEncryptedKeyResolver) DecryptionException(org.opensaml.xml.encryption.DecryptionException) UserAccount(com.cloud.user.UserAccount) LoginCmdResponse(org.apache.cloudstack.api.response.LoginCmdResponse) InlineEncryptedKeyResolver(org.opensaml.xml.encryption.InlineEncryptedKeyResolver) EncryptedKeyResolver(org.opensaml.xml.encryption.EncryptedKeyResolver)

Example 2 with LoginCmdResponse

use of org.apache.cloudstack.api.response.LoginCmdResponse in project cloudstack by apache.

the class ListAndSwitchSAMLAccountCmdTest method testListAndSwitchSAMLAccountCmd.

@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");
    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());
    }
}
Also used : HashMap(java.util.HashMap) HttpSession(javax.servlet.http.HttpSession) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) DomainVO(com.cloud.domain.DomainVO) Field(java.lang.reflect.Field) UserAccountVO(com.cloud.user.UserAccountVO) UserVO(com.cloud.user.UserVO) ServerApiException(org.apache.cloudstack.api.ServerApiException) InetAddress(java.net.InetAddress) HashMap(java.util.HashMap) Map(java.util.Map) LoginCmdResponse(org.apache.cloudstack.api.response.LoginCmdResponse) Test(org.junit.Test)

Example 3 with LoginCmdResponse

use of org.apache.cloudstack.api.response.LoginCmdResponse in project cloudstack by apache.

the class ApiServer method createLoginResponse.

private ResponseObject createLoginResponse(HttpSession session) {
    LoginCmdResponse response = new LoginCmdResponse();
    response.setTimeout(session.getMaxInactiveInterval());
    final String user_UUID = (String) session.getAttribute("user_UUID");
    response.setUserId(user_UUID);
    final String domain_UUID = (String) session.getAttribute("domain_UUID");
    response.setDomainId(domain_UUID);
    synchronized (session) {
        session.removeAttribute("user_UUID");
        session.removeAttribute("domain_UUID");
    }
    final Enumeration attrNames = session.getAttributeNames();
    if (attrNames != null) {
        while (attrNames.hasMoreElements()) {
            final String attrName = (String) attrNames.nextElement();
            final Object attrObj = session.getAttribute(attrName);
            if (ApiConstants.USERNAME.equalsIgnoreCase(attrName)) {
                response.setUsername(attrObj.toString());
            }
            if (ApiConstants.ACCOUNT.equalsIgnoreCase(attrName)) {
                response.setAccount(attrObj.toString());
            }
            if (ApiConstants.FIRSTNAME.equalsIgnoreCase(attrName)) {
                response.setFirstName(attrObj.toString());
            }
            if (ApiConstants.LASTNAME.equalsIgnoreCase(attrName)) {
                response.setLastName(attrObj.toString());
            }
            if (ApiConstants.TYPE.equalsIgnoreCase(attrName)) {
                response.setType((attrObj.toString()));
            }
            if (ApiConstants.TIMEZONE.equalsIgnoreCase(attrName)) {
                response.setTimeZone(attrObj.toString());
            }
            if (ApiConstants.TIMEZONEOFFSET.equalsIgnoreCase(attrName)) {
                response.setTimeZoneOffset(attrObj.toString());
            }
            if (ApiConstants.REGISTERED.equalsIgnoreCase(attrName)) {
                response.setRegistered(attrObj.toString());
            }
            if (ApiConstants.SESSIONKEY.equalsIgnoreCase(attrName)) {
                response.setSessionKey(attrObj.toString());
            }
        }
    }
    response.setResponseName("loginresponse");
    return response;
}
Also used : Enumeration(java.util.Enumeration) ExceptionProxyObject(com.cloud.utils.exception.ExceptionProxyObject) ResponseObject(org.apache.cloudstack.api.ResponseObject) LoginCmdResponse(org.apache.cloudstack.api.response.LoginCmdResponse)

Example 4 with LoginCmdResponse

use of org.apache.cloudstack.api.response.LoginCmdResponse in project cloudstack by apache.

the class ListAndSwitchSAMLAccountCmd method authenticate.

@Override
public String authenticate(final String command, final Map<String, Object[]> params, final HttpSession session, InetAddress remoteAddress, final String responseType, final StringBuilder auditTrailSb, final HttpServletRequest req, final HttpServletResponse resp) throws ServerApiException {
    if (session == null || session.isNew()) {
        throw new ServerApiException(ApiErrorCode.UNAUTHORIZED, _apiServer.getSerializedApiError(ApiErrorCode.UNAUTHORIZED.getHttpCode(), "Only authenticated saml users can request this API", params, responseType));
    }
    if (!HttpUtils.validateSessionKey(session, params, req.getCookies(), ApiConstants.SESSIONKEY)) {
        throw new ServerApiException(ApiErrorCode.UNAUTHORIZED, _apiServer.getSerializedApiError(ApiErrorCode.UNAUTHORIZED.getHttpCode(), "Unauthorized session, please re-login", params, responseType));
    }
    final long currentUserId = (Long) session.getAttribute("userid");
    final UserAccount currentUserAccount = _accountService.getUserAccountById(currentUserId);
    if (currentUserAccount == null || currentUserAccount.getSource() != User.Source.SAML2) {
        throw new ServerApiException(ApiErrorCode.ACCOUNT_ERROR, _apiServer.getSerializedApiError(ApiErrorCode.ACCOUNT_ERROR.getHttpCode(), "Only authenticated saml users can request this API", params, responseType));
    }
    String userUuid = null;
    String domainUuid = null;
    if (params.containsKey(ApiConstants.USER_ID)) {
        userUuid = ((String[]) params.get(ApiConstants.USER_ID))[0];
    }
    if (params.containsKey(ApiConstants.DOMAIN_ID)) {
        domainUuid = ((String[]) params.get(ApiConstants.DOMAIN_ID))[0];
    }
    if (userUuid != null && domainUuid != null) {
        final User user = _userDao.findByUuid(userUuid);
        final Domain domain = _domainDao.findByUuid(domainUuid);
        final UserAccount nextUserAccount = _accountService.getUserAccountById(user.getId());
        if (nextUserAccount != null && !nextUserAccount.getAccountState().equals(Account.State.enabled.toString())) {
            throw new ServerApiException(ApiErrorCode.ACCOUNT_ERROR, _apiServer.getSerializedApiError(ApiErrorCode.PARAM_ERROR.getHttpCode(), "The requested user account is locked and cannot be switched to, please contact your administrator.", params, responseType));
        }
        if (nextUserAccount == null || !nextUserAccount.getAccountState().equals(Account.State.enabled.toString()) || !nextUserAccount.getUsername().equals(currentUserAccount.getUsername()) || !nextUserAccount.getExternalEntity().equals(currentUserAccount.getExternalEntity()) || (nextUserAccount.getDomainId() != domain.getId()) || (nextUserAccount.getSource() != User.Source.SAML2)) {
            throw new ServerApiException(ApiErrorCode.PARAM_ERROR, _apiServer.getSerializedApiError(ApiErrorCode.PARAM_ERROR.getHttpCode(), "User account is not allowed to switch to the requested account", params, responseType));
        }
        try {
            if (_apiServer.verifyUser(nextUserAccount.getId())) {
                final LoginCmdResponse loginResponse = (LoginCmdResponse) _apiServer.loginUser(session, nextUserAccount.getUsername(), nextUserAccount.getUsername() + nextUserAccount.getSource().toString(), nextUserAccount.getDomainId(), null, remoteAddress, params);
                SAMLUtils.setupSamlUserCookies(loginResponse, resp);
                resp.sendRedirect(SAML2AuthManager.SAMLCloudStackRedirectionUrl.value());
                return ApiResponseSerializer.toSerializedString(loginResponse, responseType);
            }
        } catch (CloudAuthenticationException | IOException exception) {
            s_logger.debug("Failed to switch to request SAML user account due to: " + exception.getMessage());
        }
    } else {
        List<UserAccountVO> switchableAccounts = _userAccountDao.getAllUsersByNameAndEntity(currentUserAccount.getUsername(), currentUserAccount.getExternalEntity());
        if (switchableAccounts != null && switchableAccounts.size() > 0 && currentUserId != User.UID_SYSTEM) {
            List<SamlUserAccountResponse> accountResponses = new ArrayList<SamlUserAccountResponse>();
            for (UserAccountVO userAccount : switchableAccounts) {
                User user = _userDao.getUser(userAccount.getId());
                Domain domain = _domainService.getDomain(userAccount.getDomainId());
                SamlUserAccountResponse accountResponse = new SamlUserAccountResponse();
                accountResponse.setUserId(user.getUuid());
                accountResponse.setUserName(user.getUsername());
                accountResponse.setDomainId(domain.getUuid());
                accountResponse.setDomainName(domain.getName());
                accountResponse.setDomainPath(domain.getPath());
                accountResponse.setAccountName(userAccount.getAccountName());
                accountResponse.setIdpId(user.getExternalEntity());
                accountResponses.add(accountResponse);
            }
            ListResponse<SamlUserAccountResponse> response = new ListResponse<SamlUserAccountResponse>();
            response.setResponses(accountResponses);
            response.setResponseName(getCommandName());
            return ApiResponseSerializer.toSerializedString(response, responseType);
        }
    }
    throw new ServerApiException(ApiErrorCode.ACCOUNT_ERROR, _apiServer.getSerializedApiError(ApiErrorCode.ACCOUNT_ERROR.getHttpCode(), "Unable to switch to requested SAML account. Please make sure your user/account is enabled. Please contact your administrator.", params, responseType));
}
Also used : User(com.cloud.user.User) ListResponse(org.apache.cloudstack.api.response.ListResponse) CloudAuthenticationException(com.cloud.exception.CloudAuthenticationException) SamlUserAccountResponse(org.apache.cloudstack.api.response.SamlUserAccountResponse) ArrayList(java.util.ArrayList) IOException(java.io.IOException) UserAccountVO(com.cloud.user.UserAccountVO) ServerApiException(org.apache.cloudstack.api.ServerApiException) Domain(com.cloud.domain.Domain) UserAccount(com.cloud.user.UserAccount) LoginCmdResponse(org.apache.cloudstack.api.response.LoginCmdResponse)

Aggregations

LoginCmdResponse (org.apache.cloudstack.api.response.LoginCmdResponse)4 UserAccountVO (com.cloud.user.UserAccountVO)3 ServerApiException (org.apache.cloudstack.api.ServerApiException)3 CloudAuthenticationException (com.cloud.exception.CloudAuthenticationException)2 UserAccount (com.cloud.user.UserAccount)2 IOException (java.io.IOException)2 Domain (com.cloud.domain.Domain)1 DomainVO (com.cloud.domain.DomainVO)1 User (com.cloud.user.User)1 UserVO (com.cloud.user.UserVO)1 ExceptionProxyObject (com.cloud.utils.exception.ExceptionProxyObject)1 Field (java.lang.reflect.Field)1 InetAddress (java.net.InetAddress)1 ArrayList (java.util.ArrayList)1 Enumeration (java.util.Enumeration)1 HashMap (java.util.HashMap)1 Map (java.util.Map)1 HttpServletResponse (javax.servlet.http.HttpServletResponse)1 HttpSession (javax.servlet.http.HttpSession)1 ResponseObject (org.apache.cloudstack.api.ResponseObject)1