def soap_login(soap_url, request_body, headers, proxies, session=None): """Process SOAP specific login workflow.""" response = (session or requests).post( soap_url, request_body, headers=headers, proxies=proxies) if response.status_code != 200: except_code = getUniqueElementValueFromXmlString( response.content, 'sf:exceptionCode') except_msg = getUniqueElementValueFromXmlString( response.content, 'sf:exceptionMessage') raise SalesforceAuthenticationFailed(except_code, except_msg) session_id = getUniqueElementValueFromXmlString( response.content, 'sessionId') server_url = getUniqueElementValueFromXmlString( response.content, 'serverUrl') sf_instance = (server_url .replace('http://', '') .replace('https://', '') .split('/')[0] .replace('-api', '')) return session_id, sf_instance
def SalesforceLogin( username=None, password=None, security_token=None, refresh_token=None, consumer_id=None, consumer_secret=None, organizationId=None, sandbox=False, sf_version=DEFAULT_API_VERSION, proxies=None, session=None, client_id=None): """Return a tuple of `(session_id, sf_instance)` where `session_id` is the session ID to use for authentication to Salesforce and `sf_instance` is the domain of the instance of Salesforce to use for the session. Arguments: * username -- the Salesforce username to use for authentication * password -- the password for the username * security_token -- the security token for the username NOTE: next 3 parameters are optional, but should all be passed if logging in with Connected App and refresh token * refresh_token -- the refresh token provided to the Connected App (used in some OAuth schemes) * consumer_id -- the consumer ID for the Connected App that was granted user's refresh token * consumer_secret -- the consumer secret for the Connected App that was granted the user's refresh token. * organizationId -- the ID of your organization NOTE: security_token an organizationId are mutually exclusive * sandbox -- True if you want to login to `test.salesforce.com`, False if you want to login to `login.salesforce.com`. * sf_version -- the version of the Salesforce API to use, for example "27.0" * proxies -- the optional map of scheme to proxy server * session -- Custom requests session, created in calling code. This enables the use of requets Session features not otherwise exposed by simple_salesforce. * client_id -- the ID of this client """ soap_url = 'https://{domain}.salesforce.com/services/Soap/u/{sf_version}' rest_url = 'https://{domain}.salesforce.com/services/oauth2/token' domain = 'test' if sandbox else 'login' if client_id: client_id = "{prefix}/{app_name}".format( prefix=DEFAULT_CLIENT_ID_PREFIX, app_name=client_id) else: client_id = DEFAULT_CLIENT_ID_PREFIX soap_url = soap_url.format(domain=domain, sf_version=sf_version) rest_url = rest_url.format(domain=domain, sf_version=sf_version) # Let's see if this flow is appropriate first as it's quite different # than the rest of the flows if all(arg is not None for arg in ( refresh_token, consumer_id, consumer_secret)): # Use client credentials and refresh_token provided to Connected App by # Salesforce during OAuth process to get a new session/access_token data = { 'grant_type': 'refresh_token', 'client_id' : consumer_id, 'client_secret' : consumer_secret, 'refresh_token': refresh_token } headers = { 'content-type': 'application/x-www-form-urlencoded' } response = (session or requests).post( url=rest_url, data=data, headers=headers, proxies=proxies) response_data = response.json() if response.status_code != 200: # Something's gone wrong :( # TODO: Could there be a case where this isn't a list? Or the error # is not always in the first element? Not sure. if len(response_data) > 0: response_data = response_data[0] raise SalesforceAuthenticationFailed( response_data['errorCode'], response_data['message']) session_id = response_data.get('access_token') sf_instance = cleanseInstanceUrl(response_data.get('instance_url')) return session_id, sf_instance # pylint: disable=deprecated-method username = escape(username) # pylint: disable=deprecated-method password = escape(password) # Check if token authentication is used if security_token is not None: # Security Token Soap request body login_soap_request_body = """<?xml version="1.0" encoding="utf-8" ?> <env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:partner.soap.sforce.com"> <env:Header> <urn:CallOptions> <urn:client>{client_id}</urn:client> <urn:defaultNamespace>sf</urn:defaultNamespace> </urn:CallOptions> </env:Header> <env:Body> <n1:login xmlns:n1="urn:partner.soap.sforce.com"> <n1:username>{username}</n1:username> <n1:password>{password}{token}</n1:password> </n1:login> </env:Body> </env:Envelope>""".format( username=username, password=password, token=security_token, client_id=client_id) # Check if IP Filtering is used in conjuction with organizationId elif organizationId is not None: # IP Filtering Login Soap request body login_soap_request_body = """<?xml version="1.0" encoding="utf-8" ?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:partner.soap.sforce.com"> <soapenv:Header> <urn:CallOptions> <urn:client>{client_id}</urn:client> <urn:defaultNamespace>sf</urn:defaultNamespace> </urn:CallOptions> <urn:LoginScopeHeader> <urn:organizationId>{organizationId}</urn:organizationId> </urn:LoginScopeHeader> </soapenv:Header> <soapenv:Body> <urn:login> <urn:username>{username}</urn:username> <urn:password>{password}</urn:password> </urn:login> </soapenv:Body> </soapenv:Envelope>""".format( username=username, password=password, organizationId=organizationId, client_id=client_id) elif username is not None and password is not None: # IP Filtering for non self-service users login_soap_request_body = """<?xml version="1.0" encoding="utf-8" ?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:partner.soap.sforce.com"> <soapenv:Header> <urn:CallOptions> <urn:client>{client_id}</urn:client> <urn:defaultNamespace>sf</urn:defaultNamespace> </urn:CallOptions> </soapenv:Header> <soapenv:Body> <urn:login> <urn:username>{username}</urn:username> <urn:password>{password}</urn:password> </urn:login> </soapenv:Body> </soapenv:Envelope>""".format( username=username, password=password, client_id=client_id) else: except_code = 'INVALID AUTH' except_msg = ( 'You must submit either a security token or organizationId for ' 'authentication' ) raise SalesforceAuthenticationFailed(except_code, except_msg) login_soap_request_headers = { 'content-type': 'text/xml', 'charset': 'UTF-8', 'SOAPAction': 'login' } response = (session or requests).post( soap_url, login_soap_request_body, headers=login_soap_request_headers, proxies=proxies) if response.status_code != 200: except_code = getUniqueElementValueFromXmlString( response.content, 'sf:exceptionCode') except_msg = getUniqueElementValueFromXmlString( response.content, 'sf:exceptionMessage') raise SalesforceAuthenticationFailed(except_code, except_msg) session_id = getUniqueElementValueFromXmlString( response.content, 'sessionId') server_url = getUniqueElementValueFromXmlString( response.content, 'serverUrl') sf_instance = cleanseInstanceUrl(server_url) return session_id, sf_instance
def SalesforceLogin(username, password, security_token, sandbox=False, sf_version='23.0'): '''Return a tuple of `(session_id, sf_instance)` where `session_id` is the session ID to use for authentication to Salesforce and `sf_instance` is the domain of the instance of Salesforce to use for the session. Arguments: * username -- the Salesforce username to use for authentication * password -- the password for the username * security_token -- the security token for the username * sandbox -- True if you want to login to `test.salesforce.com`, False if you want to login to `login.salesforce.com`. * sf_version -- the version of the Salesforce API to use, for example "27.0" ''' soap_url = 'https://{domain}.salesforce.com/services/Soap/u/{sf_version}' domain = 'test' if not sandbox: domain = 'login' soap_url = soap_url.format(domain=domain, sf_version=sf_version) login_soap_request_body = """<?xml version="1.0" encoding="utf-8" ?> <env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"> <env:Body> <n1:login xmlns:n1="urn:partner.soap.sforce.com"> <n1:username>{username}</n1:username> <n1:password>{password}{token}</n1:password> </n1:login> </env:Body> </env:Envelope>""".format(username=username, password=password, token=security_token) login_soap_request_headers = { 'content-type': 'text/xml', 'charset': 'UTF-8', 'SOAPAction': 'login' } response = requests.post(soap_url, login_soap_request_body, headers=login_soap_request_headers) if response.status_code != 200: except_code = getUniqueElementValueFromXmlString( response.content, 'sf:exceptionCode') except_msg = getUniqueElementValueFromXmlString( response.content, 'sf:exceptionMessage') raise SalesforceAuthenticationFailed('%s: %s' % (except_code, except_msg)) session_id = getUniqueElementValueFromXmlString(response.content, 'sessionId') server_url = getUniqueElementValueFromXmlString(response.content, 'serverUrl') sf_instance = (server_url.replace('http://', '').replace( 'https://', '').split('/')[0].replace('-api', '')) return (session_id, sf_instance)
def SalesforceLogin(**kwargs): '''Return a tuple of `(session_id, sf_instance)` where `session_id` is the session ID to use for authentication to Salesforce and `sf_instance` is the domain of the instance of Salesforce to use for the session. Arguments: * username -- the Salesforce username to use for authentication * password -- the password for the username * security_token -- the security token for the username * organizationId -- the ID of your organization NOTE: security_token an organizationId are mutually exclusive * sandbox -- True if you want to login to `test.salesforce.com`, False if you want to login to `login.salesforce.com`. * sf_version -- the version of the Salesforce API to use, for example "27.0" ''' if 'sandbox' not in kwargs: sandbox = False else: sandbox = kwargs['sandbox'] if 'sf_version' not in kwargs: sf_version = '23.0' else: sf_version = kwargs['sf_version'] username = kwargs['username'] password = kwargs['password'] soap_url = 'https://{domain}.salesforce.com/services/Soap/u/{sf_version}' domain = 'test' if not sandbox: domain = 'login' soap_url = soap_url.format(domain=domain, sf_version=sf_version) username = cgi.escape(username) password = cgi.escape(password) # Check if token authentication is used if ('security_token' in kwargs): security_token = kwargs['security_token'] # Security Token Soap request body login_soap_request_body = """<?xml version="1.0" encoding="utf-8" ?> <env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"> <env:Body> <n1:login xmlns:n1="urn:partner.soap.sforce.com"> <n1:username>{username}</n1:username> <n1:password>{password}{token}</n1:password> </n1:login> </env:Body> </env:Envelope>""".format(username=username, password=password, token=security_token) # Check if IP Filtering is used in cojuction with organizationId elif 'organizationId' in kwargs: organizationId = kwargs['organizationId'] # IP Filtering Login Soap request body login_soap_request_body = """<?xml version="1.0" encoding="utf-8" ?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:partner.soap.sforce.com"> <soapenv:Header> <urn:CallOptions> <urn:client>RestForce</urn:client> <urn:defaultNamespace>sf</urn:defaultNamespace> </urn:CallOptions> <urn:LoginScopeHeader> <urn:organizationId>{organizationId}</urn:organizationId> </urn:LoginScopeHeader> </soapenv:Header> <soapenv:Body> <urn:login> <urn:username>{username}</urn:username> <urn:password>{password}</urn:password> </urn:login> </soapenv:Body> </soapenv:Envelope>""".format(username=username, password=password, organizationId=organizationId) else: except_code = 'INVALID AUTH' except_msg = 'You must submit either a security token or organizationId for authentication' raise SalesforceAuthenticationFailed('%s: %s' % (except_code, except_msg)) login_soap_request_headers = { 'content-type': 'text/xml', 'charset': 'UTF-8', 'SOAPAction': 'login' } response = requests.post(soap_url, login_soap_request_body, headers=login_soap_request_headers) if response.status_code != 200: except_code = getUniqueElementValueFromXmlString(response.content, 'sf:exceptionCode') except_msg = getUniqueElementValueFromXmlString(response.content, 'sf:exceptionMessage') raise SalesforceAuthenticationFailed('%s: %s' % (except_code, except_msg)) session_id = getUniqueElementValueFromXmlString(response.content, 'sessionId') server_url = getUniqueElementValueFromXmlString(response.content, 'serverUrl') sf_instance = (server_url .replace('http://', '') .replace('https://', '') .split('/')[0] .replace('-api', '')) return (session_id, sf_instance)
def SalesforceLogin( username=None, password=None, security_token=None, organizationId=None, sandbox=None, sf_version=DEFAULT_API_VERSION, proxies=None, session=None, client_id=None, domain=None): """Return a tuple of `(session_id, sf_instance)` where `session_id` is the session ID to use for authentication to Salesforce and `sf_instance` is the domain of the instance of Salesforce to use for the session. Arguments: * username -- the Salesforce username to use for authentication * password -- the password for the username * security_token -- the security token for the username * organizationId -- the ID of your organization NOTE: security_token an organizationId are mutually exclusive * sandbox -- DEPRECATED: Use domain instead. * sf_version -- the version of the Salesforce API to use, for example "27.0" * proxies -- the optional map of scheme to proxy server * session -- Custom requests session, created in calling code. This enables the use of requets Session features not otherwise exposed by simple_salesforce. * client_id -- the ID of this client * domain -- The domain to using for connecting to Salesforce. Use common domains, such as 'login' or 'test', or Salesforce My domain. If not used, will default to 'login'. """ if (sandbox is not None) and (domain is not None): raise ValueError("Both 'sandbox' and 'domain' arguments were " "supplied. Either may be supplied, but not " "both.") if sandbox is not None: warnings.warn("'sandbox' argument is deprecated. Use " "'domain' instead. Overriding 'domain' " "with 'sandbox' value.", DeprecationWarning) domain = 'test' if sandbox else 'login' if domain is None: domain = 'login' soap_url = 'https://{domain}.salesforce.com/services/Soap/u/{sf_version}' if client_id: client_id = "{prefix}/{app_name}".format( prefix=DEFAULT_CLIENT_ID_PREFIX, app_name=client_id) else: client_id = DEFAULT_CLIENT_ID_PREFIX soap_url = soap_url.format(domain=domain, sf_version=sf_version) # pylint: disable=E0012,deprecated-method username = escape(username) password = escape(password) # Check if token authentication is used if security_token is not None: # Security Token Soap request body login_soap_request_body = """<?xml version="1.0" encoding="utf-8" ?> <env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:partner.soap.sforce.com"> <env:Header> <urn:CallOptions> <urn:client>{client_id}</urn:client> <urn:defaultNamespace>sf</urn:defaultNamespace> </urn:CallOptions> </env:Header> <env:Body> <n1:login xmlns:n1="urn:partner.soap.sforce.com"> <n1:username>{username}</n1:username> <n1:password>{password}{token}</n1:password> </n1:login> </env:Body> </env:Envelope>""".format( username=username, password=password, token=security_token, client_id=client_id) # Check if IP Filtering is used in conjunction with organizationId elif organizationId is not None: # IP Filtering Login Soap request body login_soap_request_body = """<?xml version="1.0" encoding="utf-8" ?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:partner.soap.sforce.com"> <soapenv:Header> <urn:CallOptions> <urn:client>{client_id}</urn:client> <urn:defaultNamespace>sf</urn:defaultNamespace> </urn:CallOptions> <urn:LoginScopeHeader> <urn:organizationId>{organizationId}</urn:organizationId> </urn:LoginScopeHeader> </soapenv:Header> <soapenv:Body> <urn:login> <urn:username>{username}</urn:username> <urn:password>{password}</urn:password> </urn:login> </soapenv:Body> </soapenv:Envelope>""".format( username=username, password=password, organizationId=organizationId, client_id=client_id) elif username is not None and password is not None: # IP Filtering for non self-service users login_soap_request_body = """<?xml version="1.0" encoding="utf-8" ?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:partner.soap.sforce.com"> <soapenv:Header> <urn:CallOptions> <urn:client>{client_id}</urn:client> <urn:defaultNamespace>sf</urn:defaultNamespace> </urn:CallOptions> </soapenv:Header> <soapenv:Body> <urn:login> <urn:username>{username}</urn:username> <urn:password>{password}</urn:password> </urn:login> </soapenv:Body> </soapenv:Envelope>""".format( username=username, password=password, client_id=client_id) else: except_code = 'INVALID AUTH' except_msg = ( 'You must submit either a security token or organizationId for ' 'authentication' ) raise SalesforceAuthenticationFailed(except_code, except_msg) login_soap_request_headers = { 'content-type': 'text/xml', 'charset': 'UTF-8', 'SOAPAction': 'login' } response = (session or requests).post( soap_url, login_soap_request_body, headers=login_soap_request_headers, proxies=proxies) if response.status_code != 200: except_code = getUniqueElementValueFromXmlString( response.content, 'sf:exceptionCode') except_msg = getUniqueElementValueFromXmlString( response.content, 'sf:exceptionMessage') raise SalesforceAuthenticationFailed(except_code, except_msg) session_id = getUniqueElementValueFromXmlString( response.content, 'sessionId') server_url = getUniqueElementValueFromXmlString( response.content, 'serverUrl') sf_instance = (server_url .replace('http://', '') .replace('https://', '') .split('/')[0] .replace('-api', '')) return session_id, sf_instance
def convert_lead(self, lead_id: str, account_id: str, converted_lead_status: str = None, create_opp: bool = False, send_email: bool = False): sf_instance = self.client.sf_instance sf_version = self.client.sf_version session_id = self.client.session_id session = self.client.session if not converted_lead_status and not self.converted_status: converted_lead_status = self.converted_status = self.get_converted_status( ) soap_url = f'https://{sf_instance}/services/Soap/u/{sf_version}' login_soap_request_headers = { 'content-type': 'text/xml', 'charset': 'UTF-8', 'SOAPAction': 'convertLead' } login_soap_request_body = f""" <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:partner.soap.sforce.com"> <soapenv:Header> <urn:SessionHeader> <urn:sessionId>{session_id}</urn:sessionId> </urn:SessionHeader> </soapenv:Header> <soapenv:Body> <urn:convertLead> <urn:leadConverts> <!-- Zero or more repetitions --> <urn:convertedStatus>{converted_lead_status}</urn:convertedStatus> <urn:leadId>{lead_id}</urn:leadId> <urn:accountId>{account_id}</urn:accountId> <urn:sendNotificationEmail>{send_email}</urn:sendNotificationEmail> <urn:doNotCreateOpportunity>{not create_opp}</urn:doNotCreateOpportunity> </urn:leadConverts> </urn:convertLead> </soapenv:Body> </soapenv:Envelope> """ response = session.post(soap_url, login_soap_request_body, headers=login_soap_request_headers) if response.status_code != 200: except_code = util.getUniqueElementValueFromXmlString( response.content, 'sf:exceptionCode') except_msg = util.getUniqueElementValueFromXmlString( response.content, 'sf:exceptionMessage') raise SalesforceAuthenticationFailed(except_code, except_msg) else: contact_id = util.getUniqueElementValueFromXmlString( response.content, 'contactId') success = util.getUniqueElementValueFromXmlString( response.content, 'success') status_code = util.getUniqueElementValueFromXmlString( response.content, 'statusCode') if success == 'true': logging.info( f"Lead Id {lead_id} converted to Contact Id {contact_id}") return True, contact_id else: logging.error( f"Unable to convert Lead Id {lead_id}. Status Code: {status_code}" ) return False, status_code
def test_returns_valid_value(self): """Test that when given the correct XML a valid response is returned""" result = getUniqueElementValueFromXmlString( '<?xml version="1.0" encoding="UTF-8"?><foo>bar</foo>', 'foo') self.assertEqual(result, 'bar')
def SalesforceLogin(username=None, password=None, security_token=None, organizationId=None, sandbox=False, sf_version=DEFAULT_API_VERSION, proxies=None, session=None): """Return a tuple of `(session_id, sf_instance)` where `session_id` is the session ID to use for authentication to Salesforce and `sf_instance` is the domain of the instance of Salesforce to use for the session. Arguments: * username -- the Salesforce username to use for authentication * password -- the password for the username * security_token -- the security token for the username * organizationId -- the ID of your organization NOTE: security_token an organizationId are mutually exclusive * sandbox -- True if you want to login to `test.salesforce.com`, False if you want to login to `login.salesforce.com`. * sf_version -- the version of the Salesforce API to use, for example "27.0" * proxies -- the optional map of scheme to proxy server * session -- Custom requests session, created in calling code. This enables the use of requets Session features not otherwise exposed by simple_salesforce. """ soap_url = 'https://{domain}.salesforce.com/services/Soap/u/{sf_version}' domain = 'test' if sandbox else 'login' soap_url = soap_url.format(domain=domain, sf_version=sf_version) username = escape(username) password = escape(password) # Check if token authentication is used if security_token is not None: # Security Token Soap request body login_soap_request_body = """<?xml version="1.0" encoding="utf-8" ?> <env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"> <env:Body> <n1:login xmlns:n1="urn:partner.soap.sforce.com"> <n1:username>{username}</n1:username> <n1:password>{password}{token}</n1:password> </n1:login> </env:Body> </env:Envelope>""".format(username=username, password=password, token=security_token) # Check if IP Filtering is used in cojuction with organizationId elif organizationId is not None: # IP Filtering Login Soap request body login_soap_request_body = """<?xml version="1.0" encoding="utf-8" ?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:partner.soap.sforce.com"> <soapenv:Header> <urn:CallOptions> <urn:client>RestForce</urn:client> <urn:defaultNamespace>sf</urn:defaultNamespace> </urn:CallOptions> <urn:LoginScopeHeader> <urn:organizationId>{organizationId}</urn:organizationId> </urn:LoginScopeHeader> </soapenv:Header> <soapenv:Body> <urn:login> <urn:username>{username}</urn:username> <urn:password>{password}</urn:password> </urn:login> </soapenv:Body> </soapenv:Envelope>""".format(username=username, password=password, organizationId=organizationId) elif 'organizationId' in kwargs: # IP Filtering for non self-service users login_soap_request_body = """<?xml version="1.0" encoding="utf-8" ?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:partner.soap.sforce.com"> <soapenv:Header> <urn:CallOptions> <urn:client>RestForce</urn:client> <urn:defaultNamespace>sf</urn:defaultNamespace> </urn:CallOptions> </soapenv:Header> <soapenv:Body> <urn:login> <urn:username>{username}</urn:username> <urn:password>{password}</urn:password> </urn:login> </soapenv:Body> </soapenv:Envelope>""".format(username=username, password=password) else: except_code = 'INVALID AUTH' except_msg = 'You must submit either a security token or organizationId for authentication' raise SalesforceAuthenticationFailed(except_code, except_msg) login_soap_request_headers = { 'content-type': 'text/xml', 'charset': 'UTF-8', 'SOAPAction': 'login' } response = (session or requests).post(soap_url, login_soap_request_body, headers=login_soap_request_headers, proxies=proxies) if response.status_code != 200: except_code = getUniqueElementValueFromXmlString( response.content, 'sf:exceptionCode') except_msg = getUniqueElementValueFromXmlString( response.content, 'sf:exceptionMessage') raise SalesforceAuthenticationFailed(except_code, except_msg) session_id = getUniqueElementValueFromXmlString(response.content, 'sessionId') server_url = getUniqueElementValueFromXmlString(response.content, 'serverUrl') sf_instance = (server_url.replace('http://', '').replace( 'https://', '').split('/')[0].replace('-api', '')) return session_id, sf_instance
def SalesforceLogin( username=None, password=None, security_token=None, organizationId=None, sandbox=False, sf_version=DEFAULT_API_VERSION, proxies=None, session=None): """Return a tuple of `(session_id, sf_instance)` where `session_id` is the session ID to use for authentication to Salesforce and `sf_instance` is the domain of the instance of Salesforce to use for the session. Arguments: * username -- the Salesforce username to use for authentication * password -- the password for the username * security_token -- the security token for the username * organizationId -- the ID of your organization NOTE: security_token an organizationId are mutually exclusive * sandbox -- True if you want to login to `test.salesforce.com`, False if you want to login to `login.salesforce.com`. * sf_version -- the version of the Salesforce API to use, for example "27.0" * proxies -- the optional map of scheme to proxy server * session -- Custom requests session, created in calling code. This enables the use of requets Session features not otherwise exposed by simple_salesforce. """ soap_url = 'https://{domain}.salesforce.com/services/Soap/u/{sf_version}' domain = 'test' if sandbox else 'login' soap_url = soap_url.format(domain=domain, sf_version=sf_version) username = escape(username) password = escape(password) # Check if token authentication is used if security_token is not None: # Security Token Soap request body login_soap_request_body = """<?xml version="1.0" encoding="utf-8" ?> <env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"> <env:Body> <n1:login xmlns:n1="urn:partner.soap.sforce.com"> <n1:username>{username}</n1:username> <n1:password>{password}{token}</n1:password> </n1:login> </env:Body> </env:Envelope>""".format(username=username, password=password, token=security_token) # Check if IP Filtering is used in cojuction with organizationId elif organizationId is not None: # IP Filtering Login Soap request body login_soap_request_body = """<?xml version="1.0" encoding="utf-8" ?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:partner.soap.sforce.com"> <soapenv:Header> <urn:CallOptions> <urn:client>RestForce</urn:client> <urn:defaultNamespace>sf</urn:defaultNamespace> </urn:CallOptions> <urn:LoginScopeHeader> <urn:organizationId>{organizationId}</urn:organizationId> </urn:LoginScopeHeader> </soapenv:Header> <soapenv:Body> <urn:login> <urn:username>{username}</urn:username> <urn:password>{password}</urn:password> </urn:login> </soapenv:Body> </soapenv:Envelope>""".format( username=username, password=password, organizationId=organizationId) elif 'organizationId' in kwargs: # IP Filtering for non self-service users login_soap_request_body = """<?xml version="1.0" encoding="utf-8" ?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:partner.soap.sforce.com"> <soapenv:Header> <urn:CallOptions> <urn:client>RestForce</urn:client> <urn:defaultNamespace>sf</urn:defaultNamespace> </urn:CallOptions> </soapenv:Header> <soapenv:Body> <urn:login> <urn:username>{username}</urn:username> <urn:password>{password}</urn:password> </urn:login> </soapenv:Body> </soapenv:Envelope>""".format( username=username, password=password) else: except_code = 'INVALID AUTH' except_msg = 'You must submit either a security token or organizationId for authentication' raise SalesforceAuthenticationFailed(except_code, except_msg) login_soap_request_headers = { 'content-type': 'text/xml', 'charset': 'UTF-8', 'SOAPAction': 'login' } response = (session or requests).post(soap_url, login_soap_request_body, headers=login_soap_request_headers, proxies=proxies) if response.status_code != 200: except_code = getUniqueElementValueFromXmlString( response.content, 'sf:exceptionCode') except_msg = getUniqueElementValueFromXmlString( response.content, 'sf:exceptionMessage') raise SalesforceAuthenticationFailed(except_code, except_msg) session_id = getUniqueElementValueFromXmlString(response.content, 'sessionId') server_url = getUniqueElementValueFromXmlString(response.content, 'serverUrl') sf_instance = (server_url .replace('http://', '') .replace('https://', '') .split('/')[0] .replace('-api', '')) return session_id, sf_instance
def SalesforceLogin(username, password, security_token, sandbox=False, sf_version='23.0'): '''Return a tuple of `(session_id, sf_instance)` where `session_id` is the session ID to use for authentication to Salesforce and `sf_instance` is the domain of the instance of Salesforce to use for the session. Arguments: * username -- the Salesforce username to use for authentication * password -- the password for the username * security_token -- the security token for the username * sandbox -- True if you want to login to `test.salesforce.com`, False if you want to login to `login.salesforce.com`. * sf_version -- the version of the Salesforce API to use, for example "27.0" ''' soap_url = 'https://{domain}.salesforce.com/services/Soap/u/{sf_version}' domain = 'test' if not sandbox: domain = 'login' soap_url = soap_url.format(domain=domain, sf_version=sf_version) login_soap_request_body = """<?xml version="1.0" encoding="utf-8" ?> <env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"> <env:Body> <n1:login xmlns:n1="urn:partner.soap.sforce.com"> <n1:username>{username}</n1:username> <n1:password>{password}{token}</n1:password> </n1:login> </env:Body> </env:Envelope>""".format(username=username, password=escape(password), token=security_token) login_soap_request_headers = { 'content-type': 'text/xml', 'charset': 'UTF-8', 'SOAPAction': 'login' } response = requests.post(soap_url, login_soap_request_body, headers=login_soap_request_headers) if response.status_code != 200: except_code = getUniqueElementValueFromXmlString(response.content, 'sf:exceptionCode') except_msg = getUniqueElementValueFromXmlString(response.content, 'sf:exceptionMessage') raise SalesforceAuthenticationFailed('%s: %s' % (except_code, except_msg)) session_id = getUniqueElementValueFromXmlString(response.content, 'sessionId') server_url = getUniqueElementValueFromXmlString(response.content, 'serverUrl') sf_instance = (server_url .replace('http://', '') .replace('https://', '') .split('/')[0] .replace('-api', '')) return (session_id, sf_instance)
def SalesforceLogin( username=None, password=None, security_token=None, organizationId=None, sandbox=False, sf_version=DEFAULT_API_VERSION, session=None, client_id=None, timeout=60, **kwargs): """Return a tuple of `(session_id, sf_instance)` where `session_id` is the session ID to use for authentication to Salesforce and `sf_instance` is the domain of the instance of Salesforce to use for the session. Arguments: * username -- the Salesforce username to use for authentication * password -- the password for the username * security_token -- the security token for the username * organizationId -- the ID of your organization NOTE: security_token an organizationId are mutually exclusive * sandbox -- True if you want to login to `test.salesforce.com`, False if you want to login to `login.salesforce.com`. * sf_version -- the version of the Salesforce API to use, for example "27.0" * proxies -- the optional map of scheme to proxy server * session -- Custom requests session, created in calling code. This enables the use of requets Session features not otherwise exposed by simple_salesforce. * client_id -- the ID of this client * timeout -- How long to wait for the server to send data before giving up, as a float, or a `(connect timeout, read timeout)` tuple. (default 60) Keyword Args: Parameters passed down to requests.post method """ soap_url = 'https://{domain}.salesforce.com/services/Soap/u/{sf_version}' domain = 'test' if sandbox else 'login' if client_id: client_id = "{prefix}/{app_name}".format( prefix=DEFAULT_CLIENT_ID_PREFIX, app_name=client_id) else: client_id = DEFAULT_CLIENT_ID_PREFIX soap_url = soap_url.format(domain=domain, sf_version=sf_version) # pylint: disable=deprecated-method username = escape(username) # pylint: disable=deprecated-method password = escape(password) # Check if token authentication is used if security_token is not None: # Security Token Soap request body login_soap_request_body = """<?xml version="1.0" encoding="utf-8" ?> <env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:partner.soap.sforce.com"> <env:Header> <urn:CallOptions> <urn:client>{client_id}</urn:client> <urn:defaultNamespace>sf</urn:defaultNamespace> </urn:CallOptions> </env:Header> <env:Body> <n1:login xmlns:n1="urn:partner.soap.sforce.com"> <n1:username>{username}</n1:username> <n1:password>{password}{token}</n1:password> </n1:login> </env:Body> </env:Envelope>""".format( username=username, password=password, token=security_token, client_id=client_id) # Check if IP Filtering is used in conjuction with organizationId elif organizationId is not None: # IP Filtering Login Soap request body login_soap_request_body = """<?xml version="1.0" encoding="utf-8" ?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:partner.soap.sforce.com"> <soapenv:Header> <urn:CallOptions> <urn:client>{client_id}</urn:client> <urn:defaultNamespace>sf</urn:defaultNamespace> </urn:CallOptions> <urn:LoginScopeHeader> <urn:organizationId>{organizationId}</urn:organizationId> </urn:LoginScopeHeader> </soapenv:Header> <soapenv:Body> <urn:login> <urn:username>{username}</urn:username> <urn:password>{password}</urn:password> </urn:login> </soapenv:Body> </soapenv:Envelope>""".format( username=username, password=password, organizationId=organizationId, client_id=client_id) elif username is not None and password is not None: # IP Filtering for non self-service users login_soap_request_body = """<?xml version="1.0" encoding="utf-8" ?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:partner.soap.sforce.com"> <soapenv:Header> <urn:CallOptions> <urn:client>{client_id}</urn:client> <urn:defaultNamespace>sf</urn:defaultNamespace> </urn:CallOptions> </soapenv:Header> <soapenv:Body> <urn:login> <urn:username>{username}</urn:username> <urn:password>{password}</urn:password> </urn:login> </soapenv:Body> </soapenv:Envelope>""".format( username=username, password=password, client_id=client_id) else: except_code = 'INVALID AUTH' except_msg = ( 'You must submit either a security token or organizationId for ' 'authentication' ) raise SalesforceAuthenticationFailed(except_code, except_msg) login_soap_request_headers = { 'content-type': 'text/xml', 'charset': 'UTF-8', 'SOAPAction': 'login' } login_soap_request_headers.update(kwargs.pop('headers', dict())) response = (session or requests).post( url=soap_url, data=login_soap_request_body, headers=login_soap_request_headers, timeout=timeout, **kwargs) if response.status_code != 200: except_code = getUniqueElementValueFromXmlString( response.content, 'sf:exceptionCode') except_msg = getUniqueElementValueFromXmlString( response.content, 'sf:exceptionMessage') raise SalesforceAuthenticationFailed(except_code, except_msg) session_id = getUniqueElementValueFromXmlString( response.content, 'sessionId') server_url = getUniqueElementValueFromXmlString( response.content, 'serverUrl') sf_instance = (server_url .replace('http://', '') .replace('https://', '') .split('/')[0] .replace('-api', '')) return session_id, sf_instance
def convert_lead( session, session_id, lead_id, sf_instance, account_id=None, lead_status="Closed Won", sandbox=False, proxies=None, sf_version="38.0", ): soap_url = "https://{sf_instance}/services/Soap/u/{sf_version}" domain = "test" if sandbox else "login" soap_url = soap_url.format(domain=domain, sf_version=sf_version, sf_instance=sf_instance) account_id_block = "" if account_id: account_id_block = "<urn:accountId>{account_id}</urn:accountId>".format( account_id=account_id) login_soap_request_body = """ <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:partner.soap.sforce.com"> <soapenv:Header> <urn:SessionHeader> <urn:sessionId>{session_id}</urn:sessionId> </urn:SessionHeader> </soapenv:Header> <soapenv:Body> <urn:convertLead> <urn:leadConverts> <!-- Zero or more repetitions --> <urn:convertedStatus>{lead_status}</urn:convertedStatus> <urn:leadId>{lead_id}</urn:leadId> {account_id_block} <urn:convertedStatus>{lead_status}</urn:convertedStatus> <urn:sendNotificationEmail>true</urn:sendNotificationEmail> <urn:doNotCreateOpportunity>true</urn:doNotCreateOpportunity> </urn:leadConverts> </urn:convertLead> </soapenv:Body> </soapenv:Envelope> """.format( lead_id=lead_id, account_id_block=account_id_block, session_id=session_id, lead_status=lead_status, ) login_soap_request_headers = { "content-type": "text/xml", "charset": "UTF-8", "SOAPAction": "convertLead", } response = session.post( soap_url, login_soap_request_body, headers=login_soap_request_headers, proxies=proxies, ) if response.status_code != 200: except_code = getUniqueElementValueFromXmlString( response.content, "sf:exceptionCode") except_msg = getUniqueElementValueFromXmlString( response.content, "sf:exceptionMessage") raise SalesforceAuthenticationFailed(except_code, except_msg) else: contact_id = getUniqueElementValueFromXmlString( response.content, "contactId") success = getUniqueElementValueFromXmlString(response.content, "success") status_code = getUniqueElementValueFromXmlString( response.content, "statusCode") if success == "true": return True, contact_id else: return False, status_code
def SalesforceLogin(username=None, password=None, security_token=None, organizationId=None, sandbox=None, sf_version=DEFAULT_API_VERSION, proxies=None, session=None, client_id=None, domain=None): """Return a tuple of `(session_id, sf_instance)` where `session_id` is the session ID to use for authentication to Salesforce and `sf_instance` is the domain of the instance of Salesforce to use for the session. Arguments: * username -- the Salesforce username to use for authentication * password -- the password for the username * security_token -- the security token for the username * organizationId -- the ID of your organization NOTE: security_token an organizationId are mutually exclusive * sandbox -- DEPRECATED: Use domain instead. * sf_version -- the version of the Salesforce API to use, for example "27.0" * proxies -- the optional map of scheme to proxy server * session -- Custom requests session, created in calling code. This enables the use of requets Session features not otherwise exposed by simple_salesforce. * client_id -- the ID of this client * domain -- The domain to using for connecting to Salesforce. Use common domains, such as 'login' or 'test', or Salesforce My domain. If not used, will default to 'login'. """ if (sandbox is not None) and (domain is not None): raise ValueError("Both 'sandbox' and 'domain' arguments were " "supplied. Either may be supplied, but not " "both.") if sandbox is not None: warnings.warn( "'sandbox' argument is deprecated. Use " "'domain' instead. Overriding 'domain' " "with 'sandbox' value.", DeprecationWarning) domain = 'test' if sandbox else 'login' if domain is None: domain = 'login' soap_url = 'https://{domain}.salesforce.com/services/Soap/u/{sf_version}' if client_id: client_id = "{prefix}/{app_name}".format( prefix=DEFAULT_CLIENT_ID_PREFIX, app_name=client_id) else: client_id = DEFAULT_CLIENT_ID_PREFIX soap_url = soap_url.format(domain=domain, sf_version=sf_version) # pylint: disable=E0012,deprecated-method username = escape(username) password = escape(password) # Check if token authentication is used if security_token is not None: # Security Token Soap request body login_soap_request_body = """<?xml version="1.0" encoding="utf-8" ?> <env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:partner.soap.sforce.com"> <env:Header> <urn:CallOptions> <urn:client>{client_id}</urn:client> <urn:defaultNamespace>sf</urn:defaultNamespace> </urn:CallOptions> </env:Header> <env:Body> <n1:login xmlns:n1="urn:partner.soap.sforce.com"> <n1:username>{username}</n1:username> <n1:password>{password}{token}</n1:password> </n1:login> </env:Body> </env:Envelope>""".format(username=username, password=password, token=security_token, client_id=client_id) # Check if IP Filtering is used in conjunction with organizationId elif organizationId is not None: # IP Filtering Login Soap request body login_soap_request_body = """<?xml version="1.0" encoding="utf-8" ?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:partner.soap.sforce.com"> <soapenv:Header> <urn:CallOptions> <urn:client>{client_id}</urn:client> <urn:defaultNamespace>sf</urn:defaultNamespace> </urn:CallOptions> <urn:LoginScopeHeader> <urn:organizationId>{organizationId}</urn:organizationId> </urn:LoginScopeHeader> </soapenv:Header> <soapenv:Body> <urn:login> <urn:username>{username}</urn:username> <urn:password>{password}</urn:password> </urn:login> </soapenv:Body> </soapenv:Envelope>""".format(username=username, password=password, organizationId=organizationId, client_id=client_id) elif username is not None and password is not None: # IP Filtering for non self-service users login_soap_request_body = """<?xml version="1.0" encoding="utf-8" ?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:partner.soap.sforce.com"> <soapenv:Header> <urn:CallOptions> <urn:client>{client_id}</urn:client> <urn:defaultNamespace>sf</urn:defaultNamespace> </urn:CallOptions> </soapenv:Header> <soapenv:Body> <urn:login> <urn:username>{username}</urn:username> <urn:password>{password}</urn:password> </urn:login> </soapenv:Body> </soapenv:Envelope>""".format(username=username, password=password, client_id=client_id) else: except_code = 'INVALID AUTH' except_msg = ( 'You must submit either a security token or organizationId for ' 'authentication') raise SalesforceAuthenticationFailed(except_code, except_msg) login_soap_request_headers = { 'content-type': 'text/xml', 'charset': 'UTF-8', 'SOAPAction': 'login' } response = (session or requests).post(soap_url, login_soap_request_body, headers=login_soap_request_headers, proxies=proxies) if response.status_code != 200: except_code = getUniqueElementValueFromXmlString( response.content, 'sf:exceptionCode') except_msg = getUniqueElementValueFromXmlString( response.content, 'sf:exceptionMessage') raise SalesforceAuthenticationFailed(except_code, except_msg) session_id = getUniqueElementValueFromXmlString(response.content, 'sessionId') server_url = getUniqueElementValueFromXmlString(response.content, 'serverUrl') sf_instance = (server_url.replace('http://', '').replace( 'https://', '').split('/')[0].replace('-api', '')) return session_id, sf_instance