Files
upstream-mirror b352a9a30d
Some checks failed
test / Lint (push) Failing after 3s
test / Test with Go 1.26.8 (push) Failing after 2s
snapshot of https://github.com/centrifugal/centrifugo.git (master, 2026-09-16; blobs > 131072B omitted)
2026-09-16 01:17:21 +05:00

78 lines
2.4 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package api
import (
"context"
"crypto/subtle"
. "github.com/centrifugal/centrifugo/v6/internal/apiproto"
"github.com/centrifugal/centrifuge"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"
)
func authorize(ctx context.Context, key []byte) error {
if md, ok := metadata.FromIncomingContext(ctx); ok {
if len(md["authorization"]) > 0 && subtle.ConstantTimeCompare([]byte(md["authorization"][0]), key) == 1 {
return nil
}
}
return status.Error(codes.Unauthenticated, "unauthenticated")
}
// GRPCKeyAuth allows to set simple authentication based on string key from configuration.
// Client should provide per RPC credentials: set authorization key to metadata with value
// `apikey <KEY>`.
// Only installed when grpc_api.key is set – an unauthenticated GRPC API is the documented
// default in v6, see the note in internal/app/grpc.go before reporting it as a vulnerability.
func GRPCKeyAuth(key string) grpc.ServerOption {
authKey := []byte("apikey " + key)
return grpc.UnaryInterceptor(func(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp any, err error) {
if err := authorize(ctx, authKey); err != nil {
return nil, err
}
return handler(ctx, req)
})
}
// GRPCAPIServiceConfig for GRPC API Service.
type GRPCAPIServiceConfig struct {
UseOpenTelemetry bool
UseTransportErrorMode bool
}
// RegisterGRPCServerAPI registers GRPC API service in provided GRPC server.
func RegisterGRPCServerAPI(n *centrifuge.Node, apiExecutor *Executor, server *grpc.Server, config GRPCAPIServiceConfig) error {
RegisterCentrifugoApiServer(server, newGRPCAPIService(n, apiExecutor, config))
return nil
}
// grpcAPIService can answer on GRPC API requests.
type grpcAPIService struct {
UnimplementedCentrifugoApiServer
config GRPCAPIServiceConfig
api *Executor
}
// newGRPCAPIService creates new Service.
func newGRPCAPIService(_ *centrifuge.Node, apiExecutor *Executor, c GRPCAPIServiceConfig) *grpcAPIService {
return &grpcAPIService{
config: c,
api: apiExecutor,
}
}
func (s *grpcAPIService) useTransportErrorMode(ctx context.Context) bool {
if s.config.UseTransportErrorMode {
return true
}
if md, ok := metadata.FromIncomingContext(ctx); ok {
errorMode := md.Get("x-centrifugo-error-mode")
return len(errorMode) > 0 && errorMode[0] == "transport"
}
return false
}