Skip to content

Commit

Permalink
refactor: improve code structure in graphqlmetrics service, allow api…
Browse files Browse the repository at this point in the history
…-key override in cli (wundergraph#348)
  • Loading branch information
StarpTech authored Dec 9, 2023
1 parent 9ee2b43 commit be57291
Show file tree
Hide file tree
Showing 12 changed files with 244 additions and 130 deletions.
2 changes: 2 additions & 0 deletions .run/graphqlmetrics.run.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
<configuration default="false" name="graphqlmetrics" type="GoApplicationRunConfiguration" factoryName="Go Application">
<module name="cosmo" />
<working_directory value="$PROJECT_DIR$/graphqlmetrics" />
<go_parameters value="-race" />
<kind value="FILE" />
<package value="github.com/wundergraph/cosmo/graphqlmetrics" />
<directory value="$PROJECT_DIR$" />
<filePath value="$PROJECT_DIR$/graphqlmetrics/cmd/main.go" />
<method v="2" />
Expand Down
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
all: dev-setup

setup-build-tools:
go install github.com/bufbuild/buf/cmd/buf@latest
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install connectrpc.com/connect/cmd/protoc-gen-connect-go@latest
go install github.com/bufbuild/buf/cmd/buf@v1.28.1
go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.31.0
go install connectrpc.com/connect/cmd/protoc-gen-connect-go@v1.12.0

setup-dev-tools: setup-build-tools
go install github.com/amacneil/dbmate/v2@v2.6.0
Expand Down
3 changes: 2 additions & 1 deletion cli/src/core/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ const getLoginDetails = (): { accessToken: string; organizationSlug: string } |

export const config = {
baseURL: process.env.COSMO_API_URL || 'https://cosmo-cp.wundergraph.com',
apiKey: getLoginDetails()?.accessToken || process.env.COSMO_API_KEY,
// environment var first to allow overriding
apiKey: process.env.COSMO_API_KEY || getLoginDetails()?.accessToken,
kcApiURL: process.env.KC_API_URL || 'https://accounts.wundergraph.com/auth',
webURL: process.env.COSMO_WEB_URL || 'https://cosmo.wundergraph.com',
kcClientId: process.env.KC_CLIENT_ID || 'cosmo-cli',
Expand Down
19 changes: 10 additions & 9 deletions graphqlmetrics/cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import (
"github.com/ClickHouse/clickhouse-go/v2"
"github.com/amacneil/dbmate/v2/pkg/dbmate"
_ "github.com/amacneil/dbmate/v2/pkg/driver/clickhouse"
"github.com/wundergraph/cosmo/graphqlmetrics"
"github.com/wundergraph/cosmo/graphqlmetrics/config"
"github.com/wundergraph/cosmo/graphqlmetrics/core"
"github.com/wundergraph/cosmo/graphqlmetrics/internal/logging"
"go.uber.org/automaxprocs/maxprocs"
"go.uber.org/zap"
Expand All @@ -32,7 +32,7 @@ func main() {
logger := logging.New(!cfg.JSONLog, isDebug, logLevel).
With(
zap.String("component", "@wundergraph/graphqlmetrics"),
zap.String("service_version", graphqlmetrics.Version),
zap.String("service_version", core.Version),
)

// Automatically set GOMAXPROCS to avoid CPU throttling on containerized environments
Expand Down Expand Up @@ -69,11 +69,11 @@ func main() {
Name string
Version string
}{
{Name: "graphqlmetrics", Version: graphqlmetrics.Version},
{Name: "graphqlmetrics", Version: core.Version},
},
}
options.MaxIdleConns = 10
options.MaxOpenConns = 20
options.MaxIdleConns = 16
options.MaxOpenConns = 32

logger.Info("Connecting to clickhouse",
zap.Int("maxOpenConns", options.MaxOpenConns),
Expand Down Expand Up @@ -108,10 +108,11 @@ func main() {
logger.Info("Migration is up to date")
}

svr := graphqlmetrics.NewServer(
graphqlmetrics.NewMetricsService(logger, conn, []byte(cfg.IngestJWTSecret)),
graphqlmetrics.WithListenAddr(cfg.ListenAddr),
graphqlmetrics.WithLogger(logger),
svr := core.NewServer(
core.NewMetricsService(logger, conn),
core.WithJwtSecret([]byte(cfg.IngestJWTSecret)),
core.WithListenAddr(cfg.ListenAddr),
core.WithLogger(logger),
)

go func() {
Expand Down
71 changes: 71 additions & 0 deletions graphqlmetrics/core/authentication.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package core

import (
"context"
"fmt"
"github.com/golang-jwt/jwt/v5"
"go.uber.org/zap"
"net/http"
"strings"
)

type GraphAPITokenClaims struct {
OrganizationID string `json:"organization_id"`
FederatedGraphID string `json:"federated_graph_id"`
jwt.RegisteredClaims
}

type claimsContextKey string

const claimsKey claimsContextKey = "claims"

func getClaims(ctx context.Context) (*GraphAPITokenClaims, error) {
claims, ok := ctx.Value(claimsKey).(*GraphAPITokenClaims)
if !ok {
return nil, fmt.Errorf("could not get claims from context")
}
return claims, nil
}

func setClaims(ctx context.Context, claims *GraphAPITokenClaims) context.Context {
return context.WithValue(ctx, claimsKey, claims)
}

func authenticate(jwtSecret []byte, logger *zap.Logger, next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

parts := strings.Split(r.Header.Get("Authorization"), " ")
if len(parts) != 2 {
w.WriteHeader(http.StatusUnauthorized)
return
}

token, err := jwt.ParseWithClaims(parts[1], &GraphAPITokenClaims{}, func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
}
return jwtSecret, nil
})
if err != nil {
logger.Debug("Failed to parse token", zap.Error(err))
w.WriteHeader(http.StatusUnauthorized)
return
}

if !token.Valid {
logger.Debug("Token is invalid", zap.Bool("valid", token.Valid))
w.WriteHeader(http.StatusUnauthorized)
return
}

claims, ok := token.Claims.(*GraphAPITokenClaims)
if !ok {
w.WriteHeader(http.StatusUnauthorized)
return
}

r = r.WithContext(setClaims(r.Context(), claims))

next.ServeHTTP(w, r)
})
}
Loading

0 comments on commit be57291

Please sign in to comment.