package links
import (
"context"
"fmt"
"net/http"
"time"
"git.sr.ht/~emersion/gqlclient"
oauth2 "netlandish.com/x/gobwebs-oauth2"
"netlandish.com/x/gobwebs/auth"
"netlandish.com/x/gobwebs/server"
)
// HTTPTransport custom http transport
type HTTPTransport struct {
headers map[string]string
}
// AddHeader add headers for request
func (h *HTTPTransport) AddHeader(k, v string) {
if h.headers == nil {
h.headers = make(map[string]string)
}
h.headers[k] = v
}
// RoundTrip apply headers for request
func (h *HTTPTransport) RoundTrip(req *http.Request) (*http.Response, error) {
for k, v := range h.headers {
req.Header.Set(k, v)
}
return http.DefaultTransport.RoundTrip(req)
}
// Execute ...
func Execute(ctx context.Context, op *gqlclient.Operation, result interface{}) error {
var (
client *gqlclient.Client
httpClient *http.Client
origin string
)
srv := server.ForContext(ctx)
user := auth.ForContext(ctx)
if ostr, ok := srv.Config.File.Get("links", "api-origin"); ok {
origin = ostr
} else {
origin = "http://127.0.0.1:8080/query"
}
trans := &HTTPTransport{}
issued := time.Now().UTC()
expires := issued.Add(30 * time.Second)
grant := oauth2.BearerToken{
Version: oauth2.TokenVersion,
Issued: oauth2.ToTimestamp(issued),
Expires: oauth2.ToTimestamp(expires),
Grants: "",
ClientID: "",
}
if user != nil && user.IsAuthenticated() {
grant.Type = TypeWebAuth
grant.UserID = int(user.GetID())
} else {
grant.Type = TypeInternal
// Add Lang Header
lang := LangForContext(ctx)
trans.AddHeader("Accept-Language", lang)
}
token := grant.Encode(ctx)
trans.AddHeader("Authorization", fmt.Sprintf("Internal %s", token))
httpClient = &http.Client{
Transport: trans,
Timeout: 30 * time.Second,
}
client = gqlclient.New(origin, httpClient)
err := client.Execute(ctx, op, &result)
if graphErrors, ok := err.(interface{ Unwrap() []error }); ok {
errs := graphErrors.Unwrap()
err = errs[0]
}
return err
}