relynolli-server/CDEK/v2/auth.go

71 lines
1.5 KiB
Go

package v2
import (
"context"
"fmt"
"net/http"
"net/url"
"strings"
"time"
)
type Credentials struct {
ClientID string
ClientSecret string
}
func (c *Credentials) UrlValues() url.Values {
data := url.Values{}
data.Set("grant_type", "client_credentials")
data.Set("client_id", c.ClientID)
data.Set("client_secret", c.ClientSecret)
return data
}
type AuthResponse struct {
AccessToken string `json:"access_token"`
TokenType string `json:"token_type"`
ExpiresIn int `json:"expires_in"`
Scope string `json:"scope"`
Jti string `json:"jti"`
}
func (c *clientImpl) getAccessToken(ctx context.Context) (string, error) {
d, err := time.ParseDuration(fmt.Sprintf("%ds", c.expireIn))
if err != nil {
return "", err
}
isExpired := time.Now().After(time.Now().Add(d))
if len(c.accessToken) == 0 || isExpired {
resp, err := c.Auth(ctx)
if err != nil {
return "", err
}
c.accessToken = resp.AccessToken
c.expireIn = resp.ExpiresIn
}
return c.accessToken, nil
}
func (c *clientImpl) Auth(ctx context.Context) (*AuthResponse, error) {
if len(c.opts.Credentials.ClientID) == 0 || len(c.opts.Credentials.ClientSecret) == 0 {
return nil, fmt.Errorf("empty credentials")
}
req, err := http.NewRequestWithContext(
ctx, http.MethodPost,
c.buildUri("/v2/oauth/token", nil),
strings.NewReader(c.opts.Credentials.UrlValues().Encode()),
)
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
return jsonReq[AuthResponse](req)
}