Esempio n. 1
0
    def _refresh_token(self, keychain, connected_app):
        if keychain:  # it might be none'd and caller adds connected_app
            connected_app = keychain.get_service("connected_app")
        if connected_app is None:
            raise AttributeError(
                "No connected app or keychain was passed to refresh_oauth_token."
            )
        client_id = self.client_id
        client_secret = self.client_secret
        if not client_id:
            client_id = connected_app.client_id
            client_secret = connected_app.client_secret
        sf_oauth = self.SalesforceOAuth2(
            client_id,
            client_secret,
            connected_app.
            callback_url,  # Callback url isn't really used for this call
            auth_site=self.instance_url,
        )

        resp = sf_oauth.refresh_token(self.refresh_token)
        if resp.status_code != 200:
            raise SalesforceCredentialsException(
                f"Error refreshing OAuth token: {resp.text}")
        return safe_json_from_response(resp)
Esempio n. 2
0
 def _load_userinfo(self):
     headers = {"Authorization": "Bearer " + self.access_token}
     response = requests.get(self.instance_url +
                             "/services/oauth2/userinfo",
                             headers=headers)
     if response != self.config.get("userinfo", {}):
         config_data = safe_json_from_response(response)
         self.config.update({"userinfo": config_data})
Esempio n. 3
0
 def __call__(self):
     url = self._get_redirect_url()
     self._launch_browser(url)
     self._create_httpd()
     print(
         f"Spawning HTTP server at {self.callback_url} with timeout of {self.httpd.timeout} seconds.\n"
         + "If you are unable to log in to Salesforce you can " +
         "press ctrl+c to kill the server and return to the command line.")
     self.httpd.handle_request()
     self._check_response(self.response)
     return safe_json_from_response(self.response)
Esempio n. 4
0
    def latest_api_version(self):
        if not self._latest_api_version:
            headers = {"Authorization": "Bearer " + self.access_token}
            response = requests.get(self.instance_url + "/services/data",
                                    headers=headers)
            try:
                version = safe_json_from_response(response)[-1]["version"]
            except (KeyError, IndexError, TypeError):
                raise CumulusCIException(
                    f"Cannot decode API Version `{response.text[0:100]}``")
            self._latest_api_version = str(version)

        return self._latest_api_version
Esempio n. 5
0
 def _call_api(self, method, path, collect_pages=False, **kwargs):
     next_url = self.base_url + path
     results = []
     while next_url is not None:
         response = self.api.request(method, next_url, **kwargs)
         if response.status_code == 400:
             raise requests.exceptions.HTTPError(response.content)
         response = safe_json_from_response(response)
         if "links" in response and collect_pages:
             results.extend(response["data"])
             next_url = response["links"]["next"]
         else:
             return response
     return results
Esempio n. 6
0
def get_pull_requests_by_commit(github, repo, commit_sha):
    endpoint = (
        github.session.base_url +
        f"/repos/{repo.owner.login}/{repo.name}/commits/{commit_sha}/pulls")
    response = github.session.get(
        endpoint,
        headers={"Accept": "application/vnd.github.groot-preview+json"})
    json_list = safe_json_from_response(response)

    # raises github3.exceptions.IncompleteResposne
    # when these are not present
    for json in json_list:
        json["body_html"] = ""
        json["body_text"] = ""

    return [ShortPullRequest(json, github) for json in json_list]
Esempio n. 7
0
    def _enqueue_test_run(self, class_ids):
        if isinstance(class_ids, dict):
            body = {
                "tests": [{
                    "classId": class_id,
                    "testMethods": class_ids[class_id]
                } for class_id in class_ids]
            }
        else:
            body = {"classids": ",".join(class_ids)}

        return safe_json_from_response(
            self.tooling._call_salesforce(
                method="POST",
                url=self.tooling.base_url + "runTestsAsynchronous",
                json=body,
            ))
Esempio n. 8
0
    def _check_result(self, result):
        # anon_results is an ExecuteAnonymous Result
        # https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/sforce_api_calls_executeanonymous_result.htm
        anon_results = safe_json_from_response(result)

        # A result of `None` (body == "null") with a 200 status code
        # means that a gack occurred.
        if anon_results is None:
            raise SalesforceException(
                "Anonymous Apex returned the result `null`. "
                "This often indicates a gack occurred."
            )
        if not anon_results["compiled"]:
            raise ApexCompilationException(
                anon_results["line"], anon_results["compileProblem"]
            )
        if not anon_results["success"]:
            raise ApexException(
                anon_results["exceptionMessage"], anon_results["exceptionStackTrace"]
            )
Esempio n. 9
0
def jwt_session(client_id, private_key, username, url=None, auth_url=None):
    """Complete the JWT Token Oauth flow to obtain an access token for an org.

    :param client_id: Client Id for the connected app
    :param private_key: Private key used to sign the connected app's certificate
    :param username: Username to authenticate as
    :param url: Org's instance_url
    """
    if auth_url:
        aud = (SANDBOX_LOGIN_URL
               if auth_url.startswith(SANDBOX_LOGIN_URL) else PROD_LOGIN_URL)
    else:
        aud = PROD_LOGIN_URL
        if url is None:
            url = PROD_LOGIN_URL
        else:
            m = SANDBOX_DOMAIN_RE.match(url)
            if m is not None:
                # sandbox
                aud = SANDBOX_LOGIN_URL
                # There can be a delay in syncing scratch org credentials
                # between instances, so let's use the specific one for this org.
                instance = m.group(2)
                url = f"https://{instance}.salesforce.com"

    payload = {
        "alg": "RS256",
        "iss": client_id,
        "sub": username,
        "aud": aud,
        "exp": timegm(datetime.utcnow().utctimetuple()),
    }
    encoded_jwt = jwt.encode(payload, private_key, algorithm="RS256")
    data = {
        "grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
        "assertion": encoded_jwt,
    }
    headers = {"Content-Type": "application/x-www-form-urlencoded"}
    token_url = urljoin(url, "services/oauth2/token")
    response = requests.post(url=token_url, data=data, headers=headers)
    return safe_json_from_response(response)
Esempio n. 10
0
    def __call__(self):
        url = self._get_redirect_url()
        self._launch_browser(url)
        self._create_httpd()
        print(
            f"Spawning HTTP server at {self.callback_url} with timeout of {self.httpd.timeout} seconds.\n"
            + "If you are unable to log in to Salesforce you can " +
            "press ctrl+c to kill the server and return to the command line.")
        # Implement the 300 second timeout
        timeout_thread = HTTPDTimeout(self.httpd, self.httpd_timeout)
        timeout_thread.start()
        # use serve_forever because it is smarter about polling for Ctrl-C
        # on Windows.
        #
        # There are two ways it can be shutdown.
        # 1. Get a callback from Salesforce.
        # 2. Timeout
        self.httpd.serve_forever()

        # timeout thread can stop polling and just finish
        timeout_thread.quit()
        self._check_response(self.response)
        return safe_json_from_response(self.response)