Files
bridge/internal/permissions/client.go
Mike Mason 4d1e9717e5 fix linting
2023-07-17 19:27:12 +00:00

134 lines
2.7 KiB
Go

package permissions
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"strings"
"time"
"github.com/labstack/echo/v4"
"go.uber.org/zap"
)
const defaultPermissionsURL = "https://permissions-api.hollow-a.sv15.metalkube.net"
var defaultHTTPClient = &http.Client{
Timeout: 5 * time.Second, // nolint:gomnd // unexported
}
// Client is the permissions client.
type Client struct {
logger *zap.SugaredLogger
httpClient *http.Client
token string
baseURL *url.URL
allowURL *url.URL
}
// Do executes the provided request.
// If the out value is provided, the response will attempt to be json decoded.
func (c *Client) Do(req *http.Request, out any) (*http.Response, error) {
if c.token != "" {
req.Header.Set(echo.HeaderAuthorization, "Bearer "+c.token)
}
req.Header.Set("Content-Type", "application/json")
resp, err := c.httpClient.Do(req)
if err != nil {
return nil, err
}
if out != nil {
defer resp.Body.Close()
if err := json.NewDecoder(resp.Body).Decode(out); err != nil {
return resp, err
}
}
return resp, nil
}
// DoRequest creates a new request from the provided parameters and executes the request.
func (c *Client) DoRequest(ctx context.Context, method, path string, body io.Reader, out any) (*http.Response, error) {
path = strings.TrimPrefix(path, c.baseURL.Path)
pathURL, err := url.Parse(path)
if err != nil {
return nil, err
}
url := c.baseURL.JoinPath(pathURL.Path)
query := url.Query()
for k, v := range pathURL.Query() {
query[k] = v
}
url.RawQuery = query.Encode()
req, err := http.NewRequestWithContext(ctx, method, url.String(), body)
if err != nil {
return nil, fmt.Errorf("failed to build request: %w", err)
}
resp, err := c.Do(req, out)
if err != nil {
return nil, fmt.Errorf("failed to get response: %w", err)
}
if resp.StatusCode < http.StatusOK || resp.StatusCode >= http.StatusMultipleChoices {
return resp, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
}
return resp, nil
}
func encodeJSON(v any) (*bytes.Buffer, error) {
var buff bytes.Buffer
if err := json.NewEncoder(&buff).Encode(v); err != nil {
return nil, err
}
return &buff, nil
}
// NewClient creats a new permissions client.
func NewClient(token string, options ...Option) (*Client, error) {
client := &Client{
logger: zap.NewNop().Sugar(),
httpClient: defaultHTTPClient,
token: token,
}
for _, opt := range options {
if err := opt(client); err != nil {
return nil, err
}
}
if client.baseURL == nil {
uri, err := url.Parse(defaultPermissionsURL)
if err != nil {
return nil, err
}
client.baseURL = uri
}
client.allowURL = client.baseURL.JoinPath("/api/v1/allow")
return client, nil
}