Source code for q2_sdk.hq.models.sso_response

from enum import Enum
from dataclasses import dataclass, field
from typing import List, Optional
from lxml import etree


[docs] class ResponseType(Enum): """Enum of valid ResponseTypes expected by HQ""" LINK_OUT = "LinkOut" HTML = "RawHTML" EXCEPTION = "Exception"
[docs] @dataclass class UserLevelConfig: """Serializes key and value into HQ appropriate shapes""" key: str #: Must match a value in Q2_ThirdPartyDataElements.Name value: str #: Will set this in Q2_ThirdPartyData.DataValue def __post_init__(self): self.key = f"Session.{self.key.replace('Session.', '')}"
[docs] @dataclass class UserLevelConfigList: """ Serializes into HQ appropriate return shapes """ vendor_id: int #: self.vendor_id from an SSOHandler #: List of UserLevelConfig instances configs: List[UserLevelConfig] = field(default_factory=list) def __post_init__(self): err_msg = "configs must be a list of UserLevelConfig objects" assert isinstance(self.configs, list), err_msg assert all([isinstance(x, UserLevelConfig) for x in self.configs]), err_msg def to_json(self) -> dict: vendor_configs = [ { "VendorID": self.vendor_id, "DataType": "String", "ConfigName": x.key, "ConfigValue": x.value, } for x in self.configs ] return {"Q2_VendorConfigView": vendor_configs} def to_xml(self) -> etree.Element: root = etree.Element("AdaptorCfg") for cfg in self.configs: parent = etree.SubElement(root, "Q2_VendorConfigView") etree.SubElement(parent, "VendorID").text = str(self.vendor_id) etree.SubElement(parent, "DataType").text = "String" etree.SubElement(parent, "ConfigName").text = cfg.key etree.SubElement(parent, "ConfigValue").text = str(cfg.value) return root
[docs] class Q2SSOResponse: """The shape HQ expects back from an SSO call""" def __init__( self, response_type: ResponseType, response: str, success: bool = True, end_user_error_message="", user_level_config_list: Optional[UserLevelConfigList] = None, ): """ :param response_type: From ResponseType enum :param response: Actual response shown to the end user :param success: If False, will log failure into HQ :param end_user_error_message: In conjunction with success=False, customizes the error message :param user_level_config_list: If provided, will fill the Q2_ThirdPartyData table with user level key/value pairs for specified vendor """ self.response_type = response_type self.response = response self.success = success if user_level_config_list is not None: assert isinstance(user_level_config_list, UserLevelConfigList), ( "user_level_config_list must be UserLevelConfigList instance if supplied" ) if end_user_error_message: assert self.success is False, ( "Cannot provide an end_user_error_message when success=True" ) self.end_user_error_message = end_user_error_message self.user_level_config_list = user_level_config_list
[docs] def serialize(self) -> dict: """JSON response""" sso_return = { "Success": str(self.success), "ReturnType": self.response_type.value, "Data": self.response, } if self.end_user_error_message: sso_return["EndUserErrorMessage"] = self.end_user_error_message if self.user_level_config_list: sso_return["AdaptorCfg"] = self.user_level_config_list.to_json() return sso_return
[docs] def serialize_as_xml(self) -> etree.Element: """SOAP response""" root = etree.Element("LoginToAdapterResult") etree.SubElement(root, "Success").text = str(self.success).lower() etree.SubElement(root, "ReturnType").text = self.response_type.value etree.SubElement(root, "Data").text = self.response if self.end_user_error_message: etree.SubElement( root, "EndUserErrorMessage" ).text = self.end_user_error_message if self.user_level_config_list: root.append(self.user_level_config_list.to_xml()) return root