package server import ( "fmt" "git.rodere.systems/stream-service/api" "golang.org/x/net/context" "google.golang.org/grpc" "google.golang.org/grpc/metadata" "log" "strings" ) // private type for Context keys type contextKey int const ( clientIDKey contextKey = iota ) func credMatcher(headerName string) (mdName string, ok bool) { if headerName == "Login" || headerName == "Password" { return headerName, true } return "", false } // authenticateAgent check the client credentials func authenticateClient(ctx context.Context, s *api.Server) (string, error) { if md, ok := metadata.FromIncomingContext(ctx); ok { clientLogin := strings.Join(md["login"], "") clientPassword := strings.Join(md["password"], "") if clientLogin != "john" { return "", fmt.Errorf("unknown user %s", clientLogin) } if clientPassword != "doe" { return "", fmt.Errorf("bad password %s", clientPassword) } log.Printf("authenticated client: %s", clientLogin) return "42", nil } return "", fmt.Errorf("missing credentials") } // unaryInterceptor call authenticateClient with current context func unaryInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { s, ok := info.Server.(*api.Server) if !ok { return nil, fmt.Errorf("unable to cast server") } clientID, err := authenticateClient(ctx, s) if err != nil { return nil, err } ctx = context.WithValue(ctx, clientIDKey, clientID) return handler(ctx, req) }