summaryrefslogtreecommitdiff
path: root/vendor/github.com/grpc-ecosystem/go-grpc-middleware/validator
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/grpc-ecosystem/go-grpc-middleware/validator')
-rw-r--r--vendor/github.com/grpc-ecosystem/go-grpc-middleware/validator/doc.go45
-rw-r--r--vendor/github.com/grpc-ecosystem/go-grpc-middleware/validator/validator.go90
2 files changed, 135 insertions, 0 deletions
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/validator/doc.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/validator/doc.go
new file mode 100644
index 00000000..7205520a
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/validator/doc.go
@@ -0,0 +1,45 @@
+// Copyright 2016 Michal Witkowski. All Rights Reserved.
+// See LICENSE for licensing terms.
+
+/*
+`grpc_validator` is a generic request contents validator server-side middleware for gRPC.
+
+Request Validator Middleware
+
+Validating input is important, and hard. It also causes a lot of boilerplate code. This middleware
+checks for the existence of a `Validate` method on each of the messages of a gRPC request. This
+includes the single request of the `Unary` calls, as well as each message of the inbound Stream calls.
+In case of a validation failure, an `InvalidArgument` gRPC status is returned, along with a
+description of the validation failure.
+
+While it is generic, it was intended to be used with https://github.com/mwitkow/go-proto-validators,
+a Go protocol buffers codegen plugin that creates the `Validate` methods (including nested messages)
+based on declarative options in the `.proto` files themselves. For example:
+
+
+ syntax = "proto3";
+ package validator.examples;
+ import "github.com/mwitkow/go-proto-validators/validator.proto";
+
+ message InnerMessage {
+ // some_integer can only be in range (1, 100).
+ int32 some_integer = 1 [(validator.field) = {int_gt: 0, int_lt: 100}];
+ // some_float can only be in range (0;1).
+ double some_float = 2 [(validator.field) = {float_gte: 0, float_lte: 1}];
+ }
+
+ message OuterMessage {
+ // important_string must be a lowercase alpha-numeric of 5 to 30 characters (RE2 syntax).
+ string important_string = 1 [(validator.field) = {regex: "^[a-z]{2,5}$"}];
+ // proto3 doesn't have `required`, the `msg_exist` enforces presence of InnerMessage.
+ InnerMessage inner = 2 [(validator.field) = {msg_exists : true}];
+ }
+
+The `OuterMessage.Validate` would include validation of regexes, existence of the InnerMessage and
+the range values within it. The `grpc_validator` middleware would then automatically use that to
+check all messages processed by the server.
+
+Please consult https://github.com/mwitkow/go-proto-validators for details on `protoc` invocation and
+other parameters of customization.
+*/
+package grpc_validator
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/validator/validator.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/validator/validator.go
new file mode 100644
index 00000000..7e1e413d
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/validator/validator.go
@@ -0,0 +1,90 @@
+// Copyright 2016 Michal Witkowski. All Rights Reserved.
+// See LICENSE for licensing terms.
+
+package grpc_validator
+
+import (
+ "context"
+
+ "google.golang.org/grpc"
+ "google.golang.org/grpc/codes"
+ "google.golang.org/grpc/status"
+)
+
+// The validate interface starting with protoc-gen-validate v0.6.0.
+// See https://github.com/envoyproxy/protoc-gen-validate/pull/455.
+type validator interface {
+ Validate(all bool) error
+}
+
+// The validate interface prior to protoc-gen-validate v0.6.0.
+type validatorLegacy interface {
+ Validate() error
+}
+
+func validate(req interface{}) error {
+ switch v := req.(type) {
+ case validatorLegacy:
+ if err := v.Validate(); err != nil {
+ return status.Error(codes.InvalidArgument, err.Error())
+ }
+ case validator:
+ if err := v.Validate(false); err != nil {
+ return status.Error(codes.InvalidArgument, err.Error())
+ }
+ }
+ return nil
+}
+
+// UnaryServerInterceptor returns a new unary server interceptor that validates incoming messages.
+//
+// Invalid messages will be rejected with `InvalidArgument` before reaching any userspace handlers.
+func UnaryServerInterceptor() grpc.UnaryServerInterceptor {
+ return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
+ if err := validate(req); err != nil {
+ return nil, err
+ }
+ return handler(ctx, req)
+ }
+}
+
+// UnaryClientInterceptor returns a new unary client interceptor that validates outgoing messages.
+//
+// Invalid messages will be rejected with `InvalidArgument` before sending the request to server.
+func UnaryClientInterceptor() grpc.UnaryClientInterceptor {
+ return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
+ if err := validate(req); err != nil {
+ return err
+ }
+ return invoker(ctx, method, req, reply, cc, opts...)
+ }
+}
+
+// StreamServerInterceptor returns a new streaming server interceptor that validates incoming messages.
+//
+// The stage at which invalid messages will be rejected with `InvalidArgument` varies based on the
+// type of the RPC. For `ServerStream` (1:m) requests, it will happen before reaching any userspace
+// handlers. For `ClientStream` (n:1) or `BidiStream` (n:m) RPCs, the messages will be rejected on
+// calls to `stream.Recv()`.
+func StreamServerInterceptor() grpc.StreamServerInterceptor {
+ return func(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
+ wrapper := &recvWrapper{stream}
+ return handler(srv, wrapper)
+ }
+}
+
+type recvWrapper struct {
+ grpc.ServerStream
+}
+
+func (s *recvWrapper) RecvMsg(m interface{}) error {
+ if err := s.ServerStream.RecvMsg(m); err != nil {
+ return err
+ }
+
+ if err := validate(m); err != nil {
+ return err
+ }
+
+ return nil
+}