exchangeOrgToken attaches an org token to a request to the appURL and returns an app token. This uses the Access SSO flow to automatically generate and return an app token without the login page.
(appURL *url.URL, orgToken string)
| 435 | // exchangeOrgToken attaches an org token to a request to the appURL and returns an app token. This uses the Access SSO |
| 436 | // flow to automatically generate and return an app token without the login page. |
| 437 | func exchangeOrgToken(appURL *url.URL, orgToken string) (string, error) { |
| 438 | client := &http.Client{ |
| 439 | CheckRedirect: func(req *http.Request, via []*http.Request) error { |
| 440 | return handleRedirects(req, via, orgToken) |
| 441 | }, |
| 442 | Timeout: time.Second * 7, |
| 443 | } |
| 444 | |
| 445 | appTokenRequest, err := http.NewRequest("HEAD", appURL.String(), nil) |
| 446 | if err != nil { |
| 447 | return "", errors.Wrap(err, "failed to create app token request") |
| 448 | } |
| 449 | appTokenRequest.Header.Add("User-Agent", userAgent) |
| 450 | resp, err := client.Do(appTokenRequest) // nolint: gosec |
| 451 | if err != nil { |
| 452 | return "", errors.Wrap(err, "failed to get app token") |
| 453 | } |
| 454 | _ = resp.Body.Close() |
| 455 | var appToken string |
| 456 | for _, c := range resp.Cookies() { |
| 457 | //if Org token revoked on exchange, getTokensFromEdge instead |
| 458 | validAppToken := c.Name == tokenCookie && time.Now().Before(c.Expires) |
| 459 | if validAppToken { |
| 460 | appToken = c.Value |
| 461 | break |
| 462 | } |
| 463 | } |
| 464 | |
| 465 | if len(appToken) > 0 { |
| 466 | return appToken, nil |
| 467 | } |
| 468 | return "", fmt.Errorf("response from %s did not contain app token", resp.Request.URL.String()) |
| 469 | } |
| 470 | |
| 471 | func GetOrgTokenIfExists(authDomain string) (string, error) { |
| 472 | path, err := generateOrgTokenFilePathFromURL(authDomain) |