-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 95e2eca
Showing
18 changed files
with
820 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
.PHONY: generate-proto | ||
generate-proto: | ||
@echo "Generating proto files..." | ||
@protoc --proto_path=proto --go_out=scopesproto --go_opt=paths=source_relative proto/scopes.proto | ||
|
||
.PHONY: generate-test-proto | ||
generate-test-proto: | ||
@echo "Generating test proto files..." | ||
@cd test && buf mod update && buf generate | ||
|
||
.PHONY: test | ||
test: generate-test-proto | ||
@echo "Running tests..." | ||
@go test ./... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# proto-gen-go-grpc-scopes |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
module github.com/dapperlabs/proto-gen-go-grpc-scopes | ||
|
||
go 1.20 | ||
|
||
require ( | ||
github.com/golang/protobuf v1.5.3 | ||
github.com/stretchr/testify v1.8.4 | ||
google.golang.org/grpc v1.56.1 | ||
) | ||
|
||
require ( | ||
github.com/davecgh/go-spew v1.1.1 // indirect | ||
github.com/pmezard/go-difflib v1.0.0 // indirect | ||
gopkg.in/yaml.v3 v3.0.1 // indirect | ||
) | ||
|
||
require ( | ||
golang.org/x/net v0.9.0 // indirect | ||
golang.org/x/sys v0.7.0 // indirect | ||
golang.org/x/text v0.9.0 // indirect | ||
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect | ||
google.golang.org/protobuf v1.30.0 | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | ||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= | ||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= | ||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= | ||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= | ||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | ||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= | ||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= | ||
golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= | ||
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= | ||
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= | ||
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= | ||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= | ||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A= | ||
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= | ||
google.golang.org/grpc v1.56.1 h1:z0dNfjIl0VpaZ9iSVjA6daGatAYwPGstTjt5vkRMFkQ= | ||
google.golang.org/grpc v1.56.1/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= | ||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= | ||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= | ||
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= | ||
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= | ||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package main | ||
|
||
import ( | ||
"flag" | ||
"fmt" | ||
|
||
"github.com/dapperlabs/proto-gen-go-grpc-scopes/scopesproto" | ||
"github.com/golang/protobuf/proto" | ||
"google.golang.org/protobuf/compiler/protogen" | ||
"google.golang.org/protobuf/types/descriptorpb" | ||
"google.golang.org/protobuf/types/pluginpb" | ||
) | ||
|
||
func main() { | ||
var ( | ||
flags flag.FlagSet | ||
) | ||
|
||
protogen.Options{ | ||
ParamFunc: flags.Set, | ||
}.Run(func(gen *protogen.Plugin) error { | ||
for _, f := range gen.Files { | ||
if !f.Generate { | ||
continue | ||
} | ||
msgScopesInfo := map[string][]string{} | ||
for _, msg := range f.Messages { | ||
msgName := msg.GoIdent.GoName | ||
msgOptions := msg.Desc.Options() | ||
if msgOptions == nil { | ||
continue | ||
} | ||
msgOptionsPB := msgOptions.(*descriptorpb.MessageOptions) | ||
ext, err := proto.GetExtension(msgOptionsPB, scopesproto.E_RequiredReqScopes) | ||
if err != nil { | ||
// not a scope extension | ||
continue | ||
} | ||
scopesExt := ext.(*scopesproto.RequiredScopesOption) | ||
msgScopesInfo[msgName] = scopesExt.Scopes | ||
} | ||
|
||
if len(msgScopesInfo) > 0 { | ||
// generate scopes file | ||
filename := f.GeneratedFilenamePrefix + "_scopes.pb.go" | ||
g := gen.NewGeneratedFile(filename, f.GoImportPath) | ||
g.P("// Code generated by protoc-gen-go-scopes. DO NOT EDIT.") | ||
g.P("package ", f.GoPackageName) | ||
for msg, requiredScopes := range msgScopesInfo { | ||
g.P(fmt.Sprintf("func (*%s) RequiredScopes() []string {", msg)) | ||
g.P(fmt.Sprintf("return %#v", requiredScopes)) | ||
g.P("}") | ||
} | ||
} | ||
} | ||
gen.SupportedFeatures = uint64(pluginpb.CodeGeneratorResponse_FEATURE_PROTO3_OPTIONAL) | ||
return nil | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
version: v1 | ||
name: buf.build/rrrkren/proto-gen-go-grpc-scopes | ||
breaking: | ||
use: | ||
- FILE | ||
lint: | ||
use: | ||
- DEFAULT |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
syntax = "proto3"; | ||
|
||
package scopes; | ||
|
||
option go_package = "github.com/dapperlabs/proto-gen-go-grpc-scopes/scopesproto"; | ||
|
||
import "google/protobuf/descriptor.proto"; | ||
|
||
// Define your custom option type | ||
message RequiredScopesOption { | ||
repeated string scopes = 1; | ||
} | ||
|
||
extend google.protobuf.MessageOptions { | ||
RequiredScopesOption required_req_scopes = 50000; // 50000 is an example, replace it with your desired field number | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package scopes | ||
|
||
import ( | ||
"context" | ||
|
||
"google.golang.org/grpc" | ||
) | ||
|
||
type ScopeValidator func(ctx context.Context, scopes []string) error | ||
|
||
// ScopeValidationInterceptor validates that the request has the required scopes | ||
func ScopeValidationInterceptor(v ScopeValidator) grpc.UnaryServerInterceptor { | ||
return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { | ||
if scopeFetcher, ok := req.(HasScopeRequirements); ok { | ||
if err := v(ctx, scopeFetcher.RequiredScopes()); err != nil { | ||
return nil, err | ||
} | ||
} | ||
return handler(ctx, req) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
package scopes_test | ||
|
||
import ( | ||
"context" | ||
"net" | ||
"testing" | ||
|
||
"github.com/dapperlabs/proto-gen-go-grpc-scopes/scopes" | ||
"github.com/dapperlabs/proto-gen-go-grpc-scopes/test/testgen" | ||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
"google.golang.org/grpc" | ||
"google.golang.org/grpc/codes" | ||
"google.golang.org/grpc/metadata" | ||
"google.golang.org/grpc/status" | ||
) | ||
|
||
func TestScopeValidationInterceptor(t *testing.T) { | ||
server := grpc.NewServer( | ||
grpc.UnaryInterceptor(scopes.ScopeValidationInterceptor(func(ctx context.Context, scopes []string) error { | ||
md, ok := metadata.FromIncomingContext(ctx) | ||
if !ok { | ||
return status.Error(codes.Unauthenticated, "missing metadata") | ||
} | ||
|
||
authScope := md.Get("authorization_scope") | ||
if len(authScope) != 1 { | ||
return status.Error(codes.Unauthenticated, "missing authorization_scope") | ||
} | ||
providedScope := authScope[0] | ||
for _, allowedScope := range scopes { | ||
if providedScope == allowedScope { | ||
return nil | ||
} | ||
} | ||
return status.Errorf(codes.PermissionDenied, "missing scope: %s", scopes) | ||
})), | ||
) | ||
testgen.RegisterPingPongServer(server, &ScopeValidatorServer{}) | ||
|
||
lis, err := net.Listen("tcp", ":8080") | ||
require.NoError(t, err) | ||
|
||
go server.Serve(lis) | ||
|
||
conn, err := grpc.Dial(":8080", grpc.WithInsecure()) | ||
require.NoError(t, err) | ||
defer conn.Close() | ||
|
||
client := testgen.NewPingPongClient(conn) | ||
|
||
header := metadata.New(map[string]string{"authorization_scope": "scope1"}) | ||
ctx := metadata.NewOutgoingContext(context.Background(), header) | ||
|
||
res, err := client.Ping(ctx, &testgen.PingRequest{}) | ||
assert.NoError(t, err) | ||
assert.Equal(t, "pong", res.GetPong()) | ||
|
||
res, err = client.Ping(context.Background(), &testgen.PingRequest{}) | ||
assert.Equal(t, codes.Unauthenticated, status.Code(err)) | ||
|
||
header = metadata.New(map[string]string{"authorization_scope": "scope3"}) | ||
ctx = metadata.NewOutgoingContext(context.Background(), header) | ||
res, err = client.Ping(ctx, &testgen.PingRequest{}) | ||
assert.Equal(t, codes.PermissionDenied, status.Code(err)) | ||
} | ||
|
||
type ScopeValidatorServer struct { | ||
} | ||
|
||
func (s ScopeValidatorServer) Ping(ctx context.Context, request *testgen.PingRequest) (*testgen.PingResponse, error) { | ||
return &testgen.PingResponse{Pong: "pong"}, nil | ||
} | ||
|
||
var _ testgen.PingPongServer = (*ScopeValidatorServer)(nil) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
package scopes | ||
|
||
type HasScopeRequirements interface { | ||
RequiredScopes() []string | ||
} |
Oops, something went wrong.