Exemple #1
0
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
Exemple #2
0
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
Exemple #3
0
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)
Exemple #4
0
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)
Exemple #5
0
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
Exemple #6
0
    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 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')
Exemple #9
0
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
Exemple #10
0
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
Exemple #11
0
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)
Exemple #12
0
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
Exemple #13
0
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
Exemple #14
0
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