package middleware import ( "context" "fmt" "net/http" "github.com/99designs/gqlgen/graphql" "github.com/apex/log" ) type ContextKey string const ( ApiKey = ContextKey("apikey") ) func NewApiKey(apiKey string, logger log.Interface) *ApiKeyMiddleware { return &ApiKeyMiddleware{ apiKey: apiKey, } } type ApiKeyMiddleware struct { apiKey string } func (m *ApiKeyMiddleware) Handler(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { header := r.Header.Get("x-api-key") if len(header) == 0 { next.ServeHTTP(w, r) } else { ctx := context.WithValue(r.Context(), ApiKey, header) next.ServeHTTP(w, r.WithContext(ctx)) } }) } func (m *ApiKeyMiddleware) Directive(ctx context.Context, obj interface{}, next graphql.Resolver) (res interface{}, err error) { key, err := m.fromContext(ctx) if err != nil { return nil, err } if key != m.apiKey { return nil, fmt.Errorf("invalid API-key") } return next(ctx) } func (m *ApiKeyMiddleware) fromContext(ctx context.Context) (string, error) { if value := ctx.Value(ApiKey); value != nil { if u, ok := value.(string); ok { return u, nil } return "", fmt.Errorf("current API-key is in wrong format") } return "", fmt.Errorf("no API-key found") }