Example #1
0
 def test_protocols_by_ssl_labs(self):
     session = requests.Session()
     session.mount('https://', SslHttpAdapter())
     response = session.get(
         'https://www.ssllabs.com/ssltest/viewMyClient.html')
     self.assertIn("Your user agent has good protocol support",
                   response.text)
Example #2
0
    def verify_rejected_ssl(url):
        """
		The utility verifies that the url raises SSLError if the remote server
		supports only weak ciphers.
		"""
        session = requests.Session()
        session.mount('https://', SslHttpAdapter())
        try:
            response = session.get(url)
            return False
        except requests.exceptions.SSLError as e:
            return True
Example #3
0
    def test_to_server_without_tls_10(self):
        """
		Verify that connection is possible to SFDC servers that disabled TLS 1.0
		"""
        session = requests.Session()
        session.mount('https://', SslHttpAdapter())
        try:
            response = session.get('https://tls1test.salesforce.com')
            exc = None
        except requests.exceptions.SSLError as e:
            exc = e
        if exc:
            messages = ["Can not connect to server with disabled TLS 1.0"]
            response = None
            if SslHttpAdapter().sf_ssl_version != ssl.PROTOCOL_SSLv23:
                adapter = SslHttpAdapter(ssl_version=ssl.PROTOCOL_SSLv23)
                session = requests.Session()
                session.mount('https://', adapter)
                try:
                    response = session.get('https://tls1test.salesforce.com')
                except requests.exceptions.SSLError as e:
                    pass
            if response:
                messages.append(
                    "This can be fixed by setting "
                    "\"import ssl; SF_SSL = {'ssl_version': ssl.PROTOCOL_SSLv23}\" "
                )
                if self.verify_rejected_ssl(
                        "https://ssl3.zmap.io/sslv3test.js"):
                    messages.append("The setting should be fixed just now.")
                else:
                    messages.append(
                        "but this would enable the insecure SSLv3 protocol")
            else:
                messages.append(
                    "The system should be updated to enable newer TLS protocols."
                )
            messages.append("see README")
            raise type(exc)(exc.args[0], '\n' + '\n'.join(messages))
        self.assertIn('TLS 1.0 Deactivation Test Passed', response.text)
Example #4
0
 def make_session(self):
     """Authenticate and get the name of assigned SFDC data server"""
     with connect_lock:
         if self._sf_session is None:
             sf_session = requests.Session()
             sf_session.auth = SalesforceAuth(
                 db_alias=self.alias, settings_dict=self.settings_dict)
             if self.settings_dict['USER'] == 'dynamic auth':
                 sf_instance_url = self._sf_session or self.settings_dict[
                     'HOST']
             else:
                 sf_instance_url = sf_session.auth.authenticate(
                 )['instance_url']
             sf_requests_adapter = SslHttpAdapter(max_retries=MAX_RETRIES)
             sf_session.mount(sf_instance_url, sf_requests_adapter)
             # Additional header works, but the improvement unmeasurable for me.
             # (less than SF speed fluctuation)
             #sf_session.header = {'accept-encoding': 'gzip, deflate', 'connection': 'keep-alive'}
             self._sf_session = sf_session
Example #5
0
    def authenticate(self):
        """
        Authenticate to the Salesforce API with the provided credentials.

            Params:
                db_alias:  The database alias e.g. the default SF alias 'salesforce'.
                settings_dict: It is only important for the first connection.
                        Should be taken from django.conf.DATABASES['salesforce'],
                        because it is not known in connection.settings_dict initially.
                _session: only for tests

        This function can be called multiple times, but will only make
        an external request once per the lifetime of the auth token. Subsequent
        calls to authenticate() will return the original oauth response.

        This function is thread-safe.
        """
        # if another thread is in this method, wait for it to finish.
        # always release the lock no matter what happens in the block
        db_alias = self.db_alias
        if not db_alias in connections:
            raise KeyError(
                "authenticate function signature has been changed. "
                "The db_alias parameter more important than settings_dict")
        with oauth_lock:
            if not db_alias in oauth_data:
                settings_dict = self.settings_dict
                if settings_dict['USER'] == 'dynamic auth':
                    oauth_data[db_alias] = {
                        'instance_url': settings_dict['HOST']
                    }
                else:
                    url = ''.join(
                        [settings_dict['HOST'], '/services/oauth2/token'])

                    log.info("attempting authentication to %s" %
                             settings_dict['HOST'])
                    self._session.mount(
                        settings_dict['HOST'],
                        SslHttpAdapter(max_retries=MAX_RETRIES))
                    response = self._session.post(
                        url,
                        data=dict(
                            grant_type='password',
                            client_id=settings_dict['CONSUMER_KEY'],
                            client_secret=settings_dict['CONSUMER_SECRET'],
                            username=settings_dict['USER'],
                            password=settings_dict['PASSWORD'],
                        ))
                    if response.status_code == 200:
                        response_data = response.json()
                        calc_signature = (base64.b64encode(
                            hmac.new(
                                key=settings_dict['CONSUMER_SECRET'].encode(
                                    'ascii'),
                                msg=(response_data['id'] +
                                     response_data['issued_at']
                                     ).encode('ascii'),
                                digestmod=hashlib.sha256).digest())
                                          ).decode('ascii')
                        if calc_signature == response_data['signature']:
                            log.info("successfully authenticated %s" %
                                     settings_dict['USER'])
                            oauth_data[db_alias] = response_data
                        else:
                            raise RuntimeError(
                                'Invalid auth signature received')
                    else:
                        raise LookupError(
                            "oauth failed: %s: %s" %
                            (settings_dict['USER'], response.text))

            return oauth_data[db_alias]