Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/sanity.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,5 @@ jobs:

- name: Run test
run: |
export GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }}
go test -v ./...
81 changes: 81 additions & 0 deletions rcap/authentication.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package rcap

import (
"os"
"strings"
)

// AuthProvider is a provider for various kinds of auth
type AuthProvider interface {
HeaderForDomain(string) *AuthHeader
}

// AuthHeader is an HTTP header designed to authenticate requests
type AuthHeader struct {
HeaderType string `json:"headerType"`
Value string `json:"value"`
}

// AuthProviderConfig is a config for the default auth provider
type AuthProviderConfig struct {
// Headers is a map between domains and auth header that should be added to requests to those domains
Headers map[string]AuthHeader `json:"headers"`
}

type defaultAuthProvider struct {
config *AuthProviderConfig

augmentedHeaders map[string]AuthHeader
}

// DefaultAuthProvider creates the default static auth provider
func DefaultAuthProvider(config *AuthProviderConfig) AuthProvider {
ap := &defaultAuthProvider{
config: config,
augmentedHeaders: map[string]AuthHeader{},
}

return ap
}

// HeadersForDomain returns the appropriate auth headers for the given domain
func (ap *defaultAuthProvider) HeaderForDomain(domain string) *AuthHeader {
header, ok := ap.augmentedHeaders[domain]
if !ok {
if ap.config == nil {
return nil
}

origignalHeader, exists := ap.config.Headers[domain]
if !exists {
return nil
}

augmented := augmentHeaderFromEnv(origignalHeader)

ap.augmentedHeaders[domain] = augmented
header = augmented
}

return &header
}

// augmentHeadersFromEnv takes a an AuthHeader and replaces and `env()` values with their representative values from the environment
func augmentHeaderFromEnv(header AuthHeader) AuthHeader {
// turn env(SOME_HEADER_KEY) into SOME_HEADER_KEY
if strings.HasPrefix(header.Value, "env(") && strings.HasSuffix(header.Value, ")") {
headerKey := strings.TrimPrefix(header.Value, "env(")
headerKey = strings.TrimSuffix(headerKey, ")")

val := os.Getenv(headerKey)

augmentedHeader := AuthHeader{
HeaderType: header.HeaderType,
Value: val,
}

return augmentedHeader
}

return header
}
17 changes: 14 additions & 3 deletions rcap/graphql.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ import (
"fmt"
"io/ioutil"
"net/http"
"net/url"

"github.com/pkg/errors"
)

// GraphQLClient is a GraphQL capability for Reactr Modules
type GraphQLClient interface {
Do(endpoint, query string) (*GraphQLResponse, error)
Do(auth AuthProvider, endpoint, query string) (*GraphQLResponse, error)
}

// defaultGraphQLClient is the default implementation of the GraphQL capability
Expand Down Expand Up @@ -48,7 +49,7 @@ type GraphQLError struct {
Path string `json:"path"`
}

func (g *defaultGraphQLClient) Do(endpoint, query string) (*GraphQLResponse, error) {
func (g *defaultGraphQLClient) Do(auth AuthProvider, endpoint, query string) (*GraphQLResponse, error) {
r := &GraphQLRequest{
Query: query,
Variables: map[string]string{},
Expand All @@ -59,13 +60,23 @@ func (g *defaultGraphQLClient) Do(endpoint, query string) (*GraphQLResponse, err
return nil, errors.Wrap(err, "failed to Marshal request")
}

endpointURL, err := url.Parse(endpoint)
if err != nil {
return nil, errors.Wrap(err, "failed to Parse endpoint")
}

req, err := http.NewRequest(http.MethodPost, endpoint, bytes.NewBuffer(reqBytes))
if err != nil {
return nil, errors.Wrap(err, "failed to NewRequest")
}

req.Header.Add("Content-Type", "application/json")

authHeader := auth.HeaderForDomain(endpointURL.Host)
if authHeader.Value != "" {
req.Header.Add("Authorization", fmt.Sprintf("%s %s", authHeader.HeaderType, authHeader.Value))
}

resp, err := g.client.Do(req)
if err != nil {
return nil, errors.Wrap(err, "failed to Do")
Expand All @@ -84,7 +95,7 @@ func (g *defaultGraphQLClient) Do(endpoint, query string) (*GraphQLResponse, err
}

if resp.StatusCode > 299 {
return gqlResp, errors.New("non-200 HTTP response code")
return gqlResp, fmt.Errorf("non-200 HTTP response code; %s", string(respJSON))
}

if gqlResp.Errors != nil && len(gqlResp.Errors) > 0 {
Expand Down
30 changes: 0 additions & 30 deletions rcap/tester/main.go

This file was deleted.

2 changes: 2 additions & 0 deletions rt/capabilities.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ var ErrCapabilityNotAvailable = errors.New("capability not available")

// Capabilities define the capabilities available to a Runnable
type Capabilities struct {
Auth rcap.AuthProvider
LoggerSource rcap.LoggerSource
HTTPClient rcap.HTTPClient
GraphQLClient rcap.GraphQLClient
Expand All @@ -25,6 +26,7 @@ type Capabilities struct {

func defaultCaps(logger *vlog.Logger) Capabilities {
caps := Capabilities{
Auth: rcap.DefaultAuthProvider(nil), // no authentication config is set up by default
LoggerSource: rcap.DefaultLoggerSource(logger),
HTTPClient: rcap.DefaultHTTPClient(),
GraphQLClient: rcap.DefaultGraphQLClient(),
Expand Down
2 changes: 1 addition & 1 deletion rwasm/api_graphql.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func graphql_query(endpointPointer int32, endpointSize int32, queryPointer int32
queryBytes := inst.readMemory(queryPointer, querySize)
query := string(queryBytes)

resp, err := inst.ctx.GraphQLClient.Do(endpoint, query)
resp, err := inst.ctx.GraphQLClient.Do(inst.ctx.Auth, endpoint, query)
if err != nil {
internalLogger.Error(errors.Wrap(err, "failed to GraphQLClient.Do"))
return -1
Expand Down
Binary file modified rwasm/testdata/as-graphql/as-graphql.wasm
Binary file not shown.
2 changes: 1 addition & 1 deletion rwasm/testdata/as-graphql/src/lib.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { graphQLQuery, logInfo } from "@suborbital/suborbital"

export function run(_: ArrayBuffer): ArrayBuffer {
let result = graphQLQuery("https://api.rawkode.dev", "{ allProfiles { forename, surname } }")
let result = graphQLQuery("https://api.github.com/graphql", "{ repository (owner: \"suborbital\", name: \"reactr\") { name, nameWithOwner }}")
if (result.byteLength == 0) {
return String.UTF8.encode("failed")
}
Expand Down
5 changes: 5 additions & 0 deletions rwasm/testdata/as-json/.runnable.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
name: as-json
namespace: default
lang: assemblyscript
version: ""
apiVersion: 0.10.0
Binary file added rwasm/testdata/as-json/as-json.wasm
Binary file not shown.
12 changes: 12 additions & 0 deletions rwasm/testdata/as-json/asconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"targets": {
"release": {
"binaryFile": "as-json.wasm",
"optimizeLevel": 3,
"shrinkLevel": 1,
"converge": false,
"noAssert": false
}
},
"options": {}
}
Loading