feat: added support for longterm access tokens.
This commit is contained in:
parent
dfa4fcb54e
commit
ebd4866455
2 changed files with 36 additions and 29 deletions
63
api/api.go
63
api/api.go
|
@ -29,7 +29,8 @@ type ClientOptions struct {
|
|||
ClientSecret string `json:"client_secret"`
|
||||
|
||||
AccessToken string `json:"access_token"`
|
||||
ExpirationAt time.Time `json:"expiration_at"`
|
||||
|
||||
ExpirationAt time.Time `json:"expiration_at,omitempty"`
|
||||
RefreshToken string `json:"refresh_token"`
|
||||
}
|
||||
|
||||
|
@ -66,6 +67,7 @@ func NewApi(secretPath string) (*Client, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fmt.Println("opts:", options)
|
||||
|
||||
if options.Url == "" || options.RedirectUrl == "" {
|
||||
return nil, errors.New("AmoCrm: Invalid options: Url")
|
||||
|
@ -87,7 +89,7 @@ func NewApi(secretPath string) (*Client, error) {
|
|||
exchangeErr error
|
||||
exchanged bool
|
||||
)
|
||||
if ret.options.AccessToken == "" || ret.options.RefreshToken == "" {
|
||||
if ret.options.AccessToken == "" && ret.options.RefreshToken == "" {
|
||||
if ret.options.ClientSecret == "" ||
|
||||
ret.options.ClientId == "" ||
|
||||
ret.options.AuthCode == "" {
|
||||
|
@ -97,7 +99,7 @@ func NewApi(secretPath string) (*Client, error) {
|
|||
exchanged = true
|
||||
}
|
||||
|
||||
if !exchanged || exchangeErr != nil {
|
||||
if (!exchanged || exchangeErr != nil) && options.RefreshToken != "" {
|
||||
// Refreshing token before the work.
|
||||
// Should think of how often should refresh
|
||||
// the token. (see the ExpiresIn)
|
||||
|
@ -147,7 +149,7 @@ func (api *Client) writeSecret() error {
|
|||
return err
|
||||
}
|
||||
|
||||
func (api *Client) doRequest(resourceUrl string, requestParams requestOptions, result interface{}) error {
|
||||
func (api *Client) rdoRequest(resourceUrl string, requestParams requestOptions, result interface{}) error {
|
||||
var (
|
||||
requestUrl *url.URL
|
||||
err error
|
||||
|
@ -190,6 +192,9 @@ func (api *Client) doRequest(resourceUrl string, requestParams requestOptions, r
|
|||
if api.Debug {
|
||||
fmt.Printf("\nAmo request: %+v\nAmo repsonse: %+v\n", request, response)
|
||||
}
|
||||
if response == nil {
|
||||
return NoInternetErr
|
||||
}
|
||||
if err != nil {
|
||||
return errors.New(fmt.Sprintf(
|
||||
"Request error: %s %d %s %s",
|
||||
|
@ -205,17 +210,9 @@ func (api *Client) doRequest(resourceUrl string, requestParams requestOptions, r
|
|||
}
|
||||
|
||||
if response.StatusCode >= 400 {
|
||||
/*if response.StatusCode == 401 {
|
||||
_, err := api.RefreshToken()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return api.doRequest(
|
||||
resourceUrl,
|
||||
requestParams,
|
||||
result,
|
||||
)
|
||||
}*/
|
||||
if response.StatusCode == 401 {
|
||||
return NoAuthErr
|
||||
}
|
||||
|
||||
bodyBytes, _ := ioutil.ReadAll(response.Body)
|
||||
return errors.New(fmt.Sprintf(
|
||||
|
@ -237,7 +234,23 @@ func (api *Client) doRequest(resourceUrl string, requestParams requestOptions, r
|
|||
|
||||
return nil
|
||||
}
|
||||
func (api *Client) doRequest(
|
||||
resourceUrl string, requestParams requestOptions, result any,
|
||||
) error {
|
||||
var err error
|
||||
err = api.rdoRequest(resourceUrl, requestParams, result)
|
||||
if err == NoAuthErr && api.options.RefreshToken != "" {
|
||||
_, err = api.RefreshToken()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return api.rdoRequest(resourceUrl, requestParams, result)
|
||||
} else if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (api *Client) ExchangeAuth() (*TokenPair, error) {
|
||||
result := &OauthTokenResponse{}
|
||||
|
@ -249,7 +262,7 @@ func (api *Client) ExchangeAuth() (*TokenPair, error) {
|
|||
"redirect_uri": api.options.RedirectUrl,
|
||||
}
|
||||
|
||||
err := api.doRequest("/oauth2/access_token", requestOptions{
|
||||
err := api.rdoRequest("/oauth2/access_token", requestOptions{
|
||||
HttpMethod: http.MethodPost,
|
||||
Body: request,
|
||||
Headers: getHeaders(""),
|
||||
|
@ -277,6 +290,10 @@ func (api *Client) ExchangeAuth() (*TokenPair, error) {
|
|||
}
|
||||
|
||||
func (api *Client) RefreshTokenIfExpired() error {
|
||||
if api.options.RefreshToken == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
if now.After(api.options.ExpirationAt) || now.Equal(api.options.ExpirationAt){
|
||||
_, err := api.RefreshToken()
|
||||
|
@ -297,7 +314,7 @@ func (api *Client) RefreshToken() (*OauthTokenResponse, error) {
|
|||
"redirect_uri": api.options.RedirectUrl,
|
||||
}
|
||||
|
||||
err := api.doRequest("/oauth2/access_token", requestOptions{
|
||||
err := api.rdoRequest("/oauth2/access_token", requestOptions{
|
||||
HttpMethod: http.MethodPost,
|
||||
Body: request,
|
||||
Headers: getHeaders(""),
|
||||
|
@ -325,10 +342,6 @@ func (api *Client) Get(resource string, result interface{}, abs ...bool) error {
|
|||
if len(abs) > 0 {
|
||||
a = abs[0]
|
||||
}
|
||||
err := api.RefreshTokenIfExpired()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return api.doRequest(resource, requestOptions{
|
||||
HttpMethod: http.MethodGet,
|
||||
Body: nil,
|
||||
|
@ -338,10 +351,6 @@ func (api *Client) Get(resource string, result interface{}, abs ...bool) error {
|
|||
}
|
||||
|
||||
func (api *Client) Post(resource string, request interface{}, result interface{}) error {
|
||||
err := api.RefreshTokenIfExpired()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return api.doRequest(resource, requestOptions{
|
||||
HttpMethod: http.MethodPost,
|
||||
Body: request,
|
||||
|
@ -350,10 +359,6 @@ func (api *Client) Post(resource string, request interface{}, result interface{}
|
|||
}
|
||||
|
||||
func (api *Client) Patch(resource string, request interface{}, result interface{}) error {
|
||||
err := api.RefreshTokenIfExpired()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return api.doRequest(resource, requestOptions{
|
||||
HttpMethod: http.MethodPatch,
|
||||
Body: request,
|
||||
|
|
|
@ -6,4 +6,6 @@ import (
|
|||
|
||||
var (
|
||||
NoContentErr = errors.New("no content")
|
||||
NoAuthErr = errors.New("not authorized")
|
||||
NoInternetErr = errors.New("no Internet provided")
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue