package okta import ( "context" "fmt" "net/http" "time" "github.com/go-resty/resty/v2" "edge-infra.dev/pkg/edge/api/types" ) const ( formContentType = "application/x-www-form-urlencoded" jsonContentType = "application/json" contentTypeHeader = "Content-Type" acceptHeader = "Accept" ) type Client struct { *resty.Client config types.OktaConfig } type Request struct { *resty.Request } var ( defaultTimeOut = time.Second * 10 ) func New(cfg types.OktaConfig) *Client { client := resty.New() client.SetBaseURL(cfg.OktaIssuer) client.SetTimeout(defaultTimeOut) client.SetHeader(contentTypeHeader, jsonContentType) client.SetHeader(acceptHeader, jsonContentType) return &Client{ Client: client, config: cfg, } } func (c *Client) request(ctx context.Context) *Request { req := c.R().SetContext(ctx) return &Request{Request: req} } func (c *Client) WithFormData(ctx context.Context, data map[string]string) *Request { req := c.request(ctx) req.SetFormData(data) req.SetHeader(contentTypeHeader, formContentType) req.SetHeader(acceptHeader, jsonContentType) return req } func (c *Client) WithData(ctx context.Context, data interface{}) *Request { req := c.request(ctx) req.SetBody(data) req.SetHeader(contentTypeHeader, formContentType) req.SetHeader(acceptHeader, jsonContentType) return req } func (c *Client) WithNoData(ctx context.Context) *Request { req := c.request(ctx) req.SetHeader(acceptHeader, jsonContentType) return req } func (r *Request) WithAccessToken(token string) *Request { r.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token)) return r } func (r *Request) Post(path string, resp interface{}) error { r.SetResult(resp) res, err := r.Execute(http.MethodPost, path) return ValidateResponse(res, err) } func (r *Request) Get(path string, resp interface{}) error { r.SetResult(resp) res, err := r.Execute(http.MethodGet, path) return ValidateResponse(res, err) } func ValidateResponse(res *resty.Response, err error) error { ok := res.StatusCode() == 200 || res.StatusCode() == 204 if err == nil && ok { return nil } if err == nil { err = fmt.Errorf("status code: %v", res.StatusCode()) } if res.StatusCode() == http.StatusBadRequest { err = fmt.Errorf("the request failed validation, status code: %v", res.StatusCode()) } return err }