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