Merge pull request #1654 from micro/auth-scopes

Auth Improvements
This commit is contained in:
ben-toogood 2020-05-27 10:52:07 +01:00 committed by GitHub
commit f00b696282
24 changed files with 1120 additions and 707 deletions

View File

@ -2,8 +2,6 @@ package resolver
import (
"net/http"
"github.com/micro/go-micro/v2/auth"
)
// NewOptions returns new initialised options
@ -14,7 +12,7 @@ func NewOptions(opts ...Option) Options {
}
if options.Namespace == nil {
options.Namespace = StaticNamespace(auth.DefaultNamespace)
options.Namespace = StaticNamespace("go.micro")
}
return options

View File

@ -7,20 +7,23 @@ import (
"time"
)
const (
// BearerScheme used for Authorization header
BearerScheme = "Bearer "
// ScopePublic is the scope applied to a rule to allow access to the public
ScopePublic = ""
// ScopeAccount is the scope applied to a rule to limit to users with any valid account
ScopeAccount = "*"
)
var (
// ErrNotFound is returned when a resouce cannot be found
ErrNotFound = errors.New("not found")
// ErrEncodingToken is returned when the service encounters an error during encoding
ErrEncodingToken = errors.New("error encoding the token")
// ErrInvalidToken is returned when the token provided is not valid
// ErrInvalidToken is when the token provided is not valid
ErrInvalidToken = errors.New("invalid token provided")
// ErrInvalidRole is returned when the role provided was invalid
ErrInvalidRole = errors.New("invalid role")
// ErrForbidden is returned when a user does not have the necessary roles to access a resource
// ErrForbidden is when a user does not have the necessary scope to access a resource
ErrForbidden = errors.New("resource forbidden")
)
// Auth providers authentication and authorization
// Auth provides authentication and authorization
type Auth interface {
// Init the auth
Init(opts ...Option)
@ -28,65 +31,38 @@ type Auth interface {
Options() Options
// Generate a new account
Generate(id string, opts ...GenerateOption) (*Account, error)
// Grant access to a resource
Grant(role string, res *Resource) error
// Revoke access to a resource
Revoke(role string, res *Resource) error
// Verify an account has access to a resource
Verify(acc *Account, res *Resource) error
// Verify an account has access to a resource using the rules
Verify(acc *Account, res *Resource, opts ...VerifyOption) error
// Inspect a token
Inspect(token string) (*Account, error)
// Token generated using refresh token
// Token generated using refresh token or credentials
Token(opts ...TokenOption) (*Token, error)
// Grant access to a resource
Grant(rule *Rule) error
// Revoke access to a resource
Revoke(rule *Rule) error
// Rules returns all the rules used to verify requests
Rules(...RulesOption) ([]*Rule, error)
// String returns the name of the implementation
String() string
}
// Resource is an entity such as a user or
type Resource struct {
// Name of the resource
Name string `json:"name"`
// Type of resource, e.g.
Type string `json:"type"`
// Endpoint resource e.g NotesService.Create
Endpoint string `json:"endpoint"`
// Namespace the resource belongs to
Namespace string `json:"namespace"`
}
// Account provided by an auth provider
type Account struct {
// ID of the account e.g. email
ID string `json:"id"`
// Type of the account, e.g. service
Type string `json:"type"`
// Provider who issued the account
Provider string `json:"provider"`
// Roles associated with the Account
Roles []string `json:"roles"`
// Issuer of the account
Issuer string `json:"issuer"`
// Any other associated metadata
Metadata map[string]string `json:"metadata"`
// Namespace the account belongs to
Namespace string `json:"namespace"`
// Scopes the account has access to
Scopes []string `json:"scopes"`
// Secret for the account, e.g. the password
Secret string `json:"secret"`
}
// HasRole returns a boolean indicating if the account has the given role
func (a *Account) HasRole(role string) bool {
if a.Roles == nil {
return false
}
for _, r := range a.Roles {
if r == role {
return true
}
}
return false
}
// Token can be short or long lived
type Token struct {
// The token to be used for accessing resources
@ -99,15 +75,47 @@ type Token struct {
Expiry time.Time `json:"expiry"`
}
// Expired returns a boolean indicating if the token needs to be refreshed
func (t *Token) Expired() bool {
return t.Expiry.Unix() < time.Now().Unix()
}
// Resource is an entity such as a user or
type Resource struct {
// Name of the resource, e.g. go.micro.service.notes
Name string `json:"name"`
// Type of resource, e.g. service
Type string `json:"type"`
// Endpoint resource e.g NotesService.Create
Endpoint string `json:"endpoint"`
}
// Access defines the type of access a rule grants
type Access int
const (
// DefaultNamespace used for auth
DefaultNamespace = "go.micro"
// TokenCookieName is the name of the cookie which stores the auth token
TokenCookieName = "micro-token"
// BearerScheme used for Authorization header
BearerScheme = "Bearer "
// AccessGranted to a resource
AccessGranted Access = iota
// AccessDenied to a resource
AccessDenied
)
// Rule is used to verify access to a resource
type Rule struct {
// ID of the rule, e.g. "public"
ID string
// Scope the rule requires, a blank scope indicates open to the public and * indicates the rule
// applies to any valid account
Scope string
// Resource the rule applies to
Resource *Resource
// Access determines if the rule grants or denies access to the resource
Access Access
// Priority the rule should take when verifying a request, the higher the value the sooner the
// rule will be applied
Priority int32
}
type accountKey struct{}
// AccountFromContext gets the account from the context, which

View File

@ -1,17 +0,0 @@
package auth
import "testing"
func TestHasRole(t *testing.T) {
if new(Account).HasRole("foo") {
t.Errorf("Expected the blank account to not have a role")
}
acc := Account{Roles: []string{"foo"}}
if !acc.HasRole("foo") {
t.Errorf("Expected the account to have the foo role")
}
if acc.HasRole("bar") {
t.Errorf("Expected the account to not have the bar role")
}
}

View File

@ -49,35 +49,37 @@ func (n *noop) Generate(id string, opts ...GenerateOption) (*Account, error) {
options := NewGenerateOptions(opts...)
return &Account{
ID: id,
Roles: options.Roles,
Secret: options.Secret,
Metadata: options.Metadata,
Namespace: DefaultNamespace,
ID: id,
Secret: options.Secret,
Metadata: options.Metadata,
Scopes: options.Scopes,
Issuer: n.Options().Namespace,
}, nil
}
// Grant access to a resource
func (n *noop) Grant(role string, res *Resource) error {
func (n *noop) Grant(rule *Rule) error {
return nil
}
// Revoke access to a resource
func (n *noop) Revoke(role string, res *Resource) error {
func (n *noop) Revoke(rule *Rule) error {
return nil
}
// Rules used to verify requests
func (n *noop) Rules(opts ...RulesOption) ([]*Rule, error) {
return []*Rule{}, nil
}
// Verify an account has access to a resource
func (n *noop) Verify(acc *Account, res *Resource) error {
func (n *noop) Verify(acc *Account, res *Resource, opts ...VerifyOption) error {
return nil
}
// Inspect a token
func (n *noop) Inspect(token string) (*Account, error) {
return &Account{
ID: uuid.New().String(),
Namespace: DefaultNamespace,
}, nil
return &Account{ID: uuid.New().String(), Issuer: n.Options().Namespace}, nil
}
// Token generation using an account id and secret

View File

@ -5,6 +5,7 @@ import (
"time"
"github.com/micro/go-micro/v2/auth"
"github.com/micro/go-micro/v2/auth/rules"
"github.com/micro/go-micro/v2/auth/token"
jwtToken "github.com/micro/go-micro/v2/auth/token/jwt"
)
@ -16,15 +17,10 @@ func NewAuth(opts ...auth.Option) auth.Auth {
return j
}
type rule struct {
role string
resource *auth.Resource
}
type jwt struct {
options auth.Options
jwt token.Provider
rules []*rule
rules []*auth.Rule
sync.Mutex
}
@ -41,10 +37,6 @@ func (j *jwt) Init(opts ...auth.Option) {
o(&j.options)
}
if len(j.options.Namespace) == 0 {
j.options.Namespace = auth.DefaultNamespace
}
j.jwt = jwtToken.NewTokenProvider(
token.WithPrivateKey(j.options.PrivateKey),
token.WithPublicKey(j.options.PublicKey),
@ -60,12 +52,11 @@ func (j *jwt) Options() auth.Options {
func (j *jwt) Generate(id string, opts ...auth.GenerateOption) (*auth.Account, error) {
options := auth.NewGenerateOptions(opts...)
account := &auth.Account{
ID: id,
Type: options.Type,
Roles: options.Roles,
Provider: options.Provider,
Metadata: options.Metadata,
Namespace: options.Namespace,
ID: id,
Type: options.Type,
Scopes: options.Scopes,
Metadata: options.Metadata,
Issuer: j.Options().Namespace,
}
// generate a JWT secret which can be provided to the Token() method
@ -80,84 +71,44 @@ func (j *jwt) Generate(id string, opts ...auth.GenerateOption) (*auth.Account, e
return account, nil
}
func (j *jwt) Grant(role string, res *auth.Resource) error {
func (j *jwt) Grant(rule *auth.Rule) error {
j.Lock()
defer j.Unlock()
j.rules = append(j.rules, &rule{role, res})
j.rules = append(j.rules, rule)
return nil
}
func (j *jwt) Revoke(role string, res *auth.Resource) error {
func (j *jwt) Revoke(rule *auth.Rule) error {
j.Lock()
defer j.Unlock()
rules := make([]*rule, 0, len(j.rules))
var ruleFound bool
rules := []*auth.Rule{}
for _, r := range rules {
if r.role == role && r.resource == res {
ruleFound = true
} else {
if r.ID != rule.ID {
rules = append(rules, r)
}
}
if !ruleFound {
return auth.ErrNotFound
}
j.rules = rules
return nil
}
func (j *jwt) Verify(acc *auth.Account, res *auth.Resource) error {
func (j *jwt) Verify(acc *auth.Account, res *auth.Resource, opts ...auth.VerifyOption) error {
j.Lock()
if len(res.Namespace) == 0 {
res.Namespace = j.options.Namespace
}
rules := j.rules
j.Unlock()
defer j.Unlock()
for _, rule := range rules {
// validate the rule applies to the requested resource
if rule.resource.Namespace != "*" && rule.resource.Namespace != res.Namespace {
continue
}
if rule.resource.Type != "*" && rule.resource.Type != res.Type {
continue
}
if rule.resource.Name != "*" && rule.resource.Name != res.Name {
continue
}
if rule.resource.Endpoint != "*" && rule.resource.Endpoint != res.Endpoint {
continue
}
// a blank role indicates anyone can access the resource, even without an account
if rule.role == "" {
return nil
}
// all furter checks require an account
if acc == nil {
continue
}
// this rule allows any account access, allow the request
if rule.role == "*" {
return nil
}
// if the account has the necessary role, allow the request
for _, r := range acc.Roles {
if r == rule.role {
return nil
}
}
var options auth.VerifyOptions
for _, o := range opts {
o(&options)
}
// no rules matched, forbid the request
return auth.ErrForbidden
return rules.Verify(j.rules, acc, res)
}
func (j *jwt) Rules(opts ...auth.RulesOption) ([]*auth.Rule, error) {
j.Lock()
defer j.Unlock()
return j.rules, nil
}
func (j *jwt) Inspect(token string) (*auth.Account, error) {

View File

@ -1,6 +1,7 @@
package auth
import (
"context"
"time"
"github.com/micro/go-micro/v2/auth/provider"
@ -13,9 +14,6 @@ func NewOptions(opts ...Option) Options {
for _, o := range opts {
o(&options)
}
if len(options.Namespace) == 0 {
options.Namespace = DefaultNamespace
}
if options.Client == nil {
options.Client = client.DefaultClient
}
@ -124,10 +122,8 @@ func WithClient(c client.Client) Option {
type GenerateOptions struct {
// Metadata associated with the account
Metadata map[string]string
// Roles/scopes associated with the account
Roles []string
// Namespace the account belongs too
Namespace string
// Scopes the account has access too
Scopes []string
// Provider of the account, e.g. oauth
Provider string
// Type of the account, e.g. user
@ -159,20 +155,6 @@ func WithMetadata(md map[string]string) GenerateOption {
}
}
// WithRoles for the generated account
func WithRoles(rs ...string) GenerateOption {
return func(o *GenerateOptions) {
o.Roles = rs
}
}
// WithNamespace for the generated account
func WithNamespace(n string) GenerateOption {
return func(o *GenerateOptions) {
o.Namespace = n
}
}
// WithProvider for the generated account
func WithProvider(p string) GenerateOption {
return func(o *GenerateOptions) {
@ -180,6 +162,13 @@ func WithProvider(p string) GenerateOption {
}
}
// WithScopes for the generated account
func WithScopes(s ...string) GenerateOption {
return func(o *GenerateOptions) {
o.Scopes = s
}
}
// NewGenerateOptions from a slice of options
func NewGenerateOptions(opts ...GenerateOption) GenerateOptions {
var options GenerateOptions
@ -236,3 +225,27 @@ func NewTokenOptions(opts ...TokenOption) TokenOptions {
return options
}
type VerifyOptions struct {
Context context.Context
}
type VerifyOption func(o *VerifyOptions)
func VerifyContext(ctx context.Context) VerifyOption {
return func(o *VerifyOptions) {
o.Context = ctx
}
}
type RulesOptions struct {
Context context.Context
}
type RulesOption func(o *RulesOptions)
func RulesContext(ctx context.Context) RulesOption {
return func(o *RulesOptions) {
o.Context = ctx
}
}

93
auth/rules/rules.go Normal file
View File

@ -0,0 +1,93 @@
package rules
import (
"fmt"
"sort"
"strings"
"github.com/micro/go-micro/v2/auth"
)
// Verify an account has access to a resource using the rules provided. If the account does not have
// access an error will be returned. If there are no rules provided which match the resource, an error
// will be returned
func Verify(rules []*auth.Rule, acc *auth.Account, res *auth.Resource) error {
// the rule is only to be applied if the type matches the resource or is catch-all (*)
validTypes := []string{"*", res.Type}
// the rule is only to be applied if the name matches the resource or is catch-all (*)
validNames := []string{"*", res.Name}
// rules can have wildcard excludes on endpoints since this can also be a path for web services,
// e.g. /foo/* would include /foo/bar. We also want to check for wildcards and the exact endpoint
validEndpoints := []string{"*", res.Endpoint}
if comps := strings.Split(res.Endpoint, "/"); len(comps) > 1 {
for i := 1; i < len(comps)+1; i++ {
wildcard := fmt.Sprintf("%v/*", strings.Join(comps[0:i], "/"))
validEndpoints = append(validEndpoints, wildcard)
}
}
// filter the rules to the ones which match the criteria above
filteredRules := make([]*auth.Rule, 0)
for _, rule := range rules {
if !include(validTypes, rule.Resource.Type) {
continue
}
if !include(validNames, rule.Resource.Name) {
continue
}
if !include(validEndpoints, rule.Resource.Endpoint) {
continue
}
filteredRules = append(filteredRules, rule)
}
// sort the filtered rules by priority, highest to lowest
sort.SliceStable(filteredRules, func(i, j int) bool {
return filteredRules[i].Priority > filteredRules[j].Priority
})
// loop through the rules and check for a rule which applies to this account
for _, rule := range filteredRules {
// a blank scope indicates the rule applies to everyone, even nil accounts
if rule.Scope == auth.ScopePublic && rule.Access == auth.AccessDenied {
return auth.ErrForbidden
} else if rule.Scope == auth.ScopePublic && rule.Access == auth.AccessGranted {
return nil
}
// all further checks require an account
if acc == nil {
continue
}
// this rule applies to any account
if rule.Scope == auth.ScopeAccount && rule.Access == auth.AccessDenied {
return auth.ErrForbidden
} else if rule.Scope == auth.ScopeAccount && rule.Access == auth.AccessGranted {
return nil
}
// if the account has the necessary scope
if include(acc.Scopes, rule.Scope) && rule.Access == auth.AccessDenied {
return auth.ErrForbidden
} else if include(acc.Scopes, rule.Scope) && rule.Access == auth.AccessGranted {
return nil
}
}
// if no rules matched then return forbidden
return auth.ErrForbidden
}
// include is a helper function which checks to see if the slice contains the value. includes is
// not case sensitive.
func include(slice []string, val string) bool {
for _, s := range slice {
if strings.ToLower(s) == strings.ToLower(val) {
return true
}
}
return false
}

290
auth/rules/rules_test.go Normal file
View File

@ -0,0 +1,290 @@
package rules
import (
"testing"
"github.com/micro/go-micro/v2/auth"
)
func TestVerify(t *testing.T) {
srvResource := &auth.Resource{
Type: "service",
Name: "go.micro.service.foo",
Endpoint: "Foo.Bar",
}
webResource := &auth.Resource{
Type: "service",
Name: "go.micro.web.foo",
Endpoint: "/foo/bar",
}
catchallResource := &auth.Resource{
Type: "*",
Name: "*",
Endpoint: "*",
}
tt := []struct {
Name string
Rules []*auth.Rule
Account *auth.Account
Resource *auth.Resource
Error error
}{
{
Name: "NoRules",
Rules: []*auth.Rule{},
Account: nil,
Resource: srvResource,
Error: auth.ErrForbidden,
},
{
Name: "CatchallPublicAccount",
Account: &auth.Account{},
Resource: srvResource,
Rules: []*auth.Rule{
&auth.Rule{
Scope: "",
Resource: catchallResource,
},
},
},
{
Name: "CatchallPublicNoAccount",
Resource: srvResource,
Rules: []*auth.Rule{
&auth.Rule{
Scope: "",
Resource: catchallResource,
},
},
},
{
Name: "CatchallPrivateAccount",
Account: &auth.Account{},
Resource: srvResource,
Rules: []*auth.Rule{
&auth.Rule{
Scope: "*",
Resource: catchallResource,
},
},
},
{
Name: "CatchallPrivateNoAccount",
Resource: srvResource,
Rules: []*auth.Rule{
&auth.Rule{
Scope: "*",
Resource: catchallResource,
},
},
Error: auth.ErrForbidden,
},
{
Name: "CatchallServiceRuleMatch",
Resource: srvResource,
Account: &auth.Account{},
Rules: []*auth.Rule{
&auth.Rule{
Scope: "*",
Resource: &auth.Resource{
Type: srvResource.Type,
Name: srvResource.Name,
Endpoint: "*",
},
},
},
},
{
Name: "CatchallServiceRuleNoMatch",
Resource: srvResource,
Account: &auth.Account{},
Rules: []*auth.Rule{
&auth.Rule{
Scope: "*",
Resource: &auth.Resource{
Type: srvResource.Type,
Name: "wrongname",
Endpoint: "*",
},
},
},
Error: auth.ErrForbidden,
},
{
Name: "ExactRuleValidScope",
Resource: srvResource,
Account: &auth.Account{
Scopes: []string{"neededscope"},
},
Rules: []*auth.Rule{
&auth.Rule{
Scope: "neededscope",
Resource: srvResource,
},
},
},
{
Name: "ExactRuleInvalidScope",
Resource: srvResource,
Account: &auth.Account{
Scopes: []string{"neededscope"},
},
Rules: []*auth.Rule{
&auth.Rule{
Scope: "invalidscope",
Resource: srvResource,
},
},
Error: auth.ErrForbidden,
},
{
Name: "CatchallDenyWithAccount",
Resource: srvResource,
Account: &auth.Account{},
Rules: []*auth.Rule{
&auth.Rule{
Scope: "*",
Resource: catchallResource,
Access: auth.AccessDenied,
},
},
Error: auth.ErrForbidden,
},
{
Name: "CatchallDenyWithNoAccount",
Resource: srvResource,
Account: &auth.Account{},
Rules: []*auth.Rule{
&auth.Rule{
Scope: "*",
Resource: catchallResource,
Access: auth.AccessDenied,
},
},
Error: auth.ErrForbidden,
},
{
Name: "RulePriorityGrantFirst",
Resource: srvResource,
Account: &auth.Account{},
Rules: []*auth.Rule{
&auth.Rule{
Scope: "*",
Resource: catchallResource,
Access: auth.AccessGranted,
Priority: 1,
},
&auth.Rule{
Scope: "*",
Resource: catchallResource,
Access: auth.AccessDenied,
Priority: 0,
},
},
},
{
Name: "RulePriorityDenyFirst",
Resource: srvResource,
Account: &auth.Account{},
Rules: []*auth.Rule{
&auth.Rule{
Scope: "*",
Resource: catchallResource,
Access: auth.AccessGranted,
Priority: 0,
},
&auth.Rule{
Scope: "*",
Resource: catchallResource,
Access: auth.AccessDenied,
Priority: 1,
},
},
Error: auth.ErrForbidden,
},
{
Name: "WebExactEndpointValid",
Resource: webResource,
Account: &auth.Account{},
Rules: []*auth.Rule{
&auth.Rule{
Scope: "*",
Resource: webResource,
},
},
},
{
Name: "WebExactEndpointInalid",
Resource: webResource,
Account: &auth.Account{},
Rules: []*auth.Rule{
&auth.Rule{
Scope: "*",
Resource: &auth.Resource{
Type: webResource.Type,
Name: webResource.Name,
Endpoint: "invalidendpoint",
},
},
},
Error: auth.ErrForbidden,
},
{
Name: "WebWildcardEndpoint",
Resource: webResource,
Account: &auth.Account{},
Rules: []*auth.Rule{
&auth.Rule{
Scope: "*",
Resource: &auth.Resource{
Type: webResource.Type,
Name: webResource.Name,
Endpoint: "*",
},
},
},
},
{
Name: "WebWildcardPathEndpointValid",
Resource: webResource,
Account: &auth.Account{},
Rules: []*auth.Rule{
&auth.Rule{
Scope: "*",
Resource: &auth.Resource{
Type: webResource.Type,
Name: webResource.Name,
Endpoint: "/foo/*",
},
},
},
},
{
Name: "WebWildcardPathEndpointInvalid",
Resource: webResource,
Account: &auth.Account{},
Rules: []*auth.Rule{
&auth.Rule{
Scope: "*",
Resource: &auth.Resource{
Type: webResource.Type,
Name: webResource.Name,
Endpoint: "/bar/*",
},
},
},
Error: auth.ErrForbidden,
},
}
for _, tc := range tt {
t.Run(tc.Name, func(t *testing.T) {
if err := Verify(tc.Rules, tc.Account, tc.Resource); err != tc.Error {
t.Errorf("Expected %v but got %v", tc.Error, err)
}
})
}
}

View File

@ -188,10 +188,9 @@ func (m *Token) GetExpiry() int64 {
type Account struct {
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"`
Roles []string `protobuf:"bytes,3,rep,name=roles,proto3" json:"roles,omitempty"`
Metadata map[string]string `protobuf:"bytes,4,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
Namespace string `protobuf:"bytes,5,opt,name=namespace,proto3" json:"namespace,omitempty"`
Provider string `protobuf:"bytes,6,opt,name=provider,proto3" json:"provider,omitempty"`
Scopes []string `protobuf:"bytes,5,rep,name=scopes,proto3" json:"scopes,omitempty"`
Issuer string `protobuf:"bytes,6,opt,name=issuer,proto3" json:"issuer,omitempty"`
Secret string `protobuf:"bytes,7,opt,name=secret,proto3" json:"secret,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
@ -237,13 +236,6 @@ func (m *Account) GetType() string {
return ""
}
func (m *Account) GetRoles() []string {
if m != nil {
return m.Roles
}
return nil
}
func (m *Account) GetMetadata() map[string]string {
if m != nil {
return m.Metadata
@ -251,16 +243,16 @@ func (m *Account) GetMetadata() map[string]string {
return nil
}
func (m *Account) GetNamespace() string {
func (m *Account) GetScopes() []string {
if m != nil {
return m.Namespace
return m.Scopes
}
return ""
return nil
}
func (m *Account) GetProvider() string {
func (m *Account) GetIssuer() string {
if m != nil {
return m.Provider
return m.Issuer
}
return ""
}
@ -276,7 +268,6 @@ type Resource struct {
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"`
Endpoint string `protobuf:"bytes,3,opt,name=endpoint,proto3" json:"endpoint,omitempty"`
Namespace string `protobuf:"bytes,4,opt,name=namespace,proto3" json:"namespace,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -328,18 +319,10 @@ func (m *Resource) GetEndpoint() string {
return ""
}
func (m *Resource) GetNamespace() string {
if m != nil {
return m.Namespace
}
return ""
}
type GenerateRequest struct {
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Roles []string `protobuf:"bytes,2,rep,name=roles,proto3" json:"roles,omitempty"`
Metadata map[string]string `protobuf:"bytes,3,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
Namespace string `protobuf:"bytes,4,opt,name=namespace,proto3" json:"namespace,omitempty"`
Scopes []string `protobuf:"bytes,4,rep,name=scopes,proto3" json:"scopes,omitempty"`
Secret string `protobuf:"bytes,5,opt,name=secret,proto3" json:"secret,omitempty"`
Type string `protobuf:"bytes,6,opt,name=type,proto3" json:"type,omitempty"`
Provider string `protobuf:"bytes,7,opt,name=provider,proto3" json:"provider,omitempty"`
@ -380,13 +363,6 @@ func (m *GenerateRequest) GetId() string {
return ""
}
func (m *GenerateRequest) GetRoles() []string {
if m != nil {
return m.Roles
}
return nil
}
func (m *GenerateRequest) GetMetadata() map[string]string {
if m != nil {
return m.Metadata
@ -394,11 +370,11 @@ func (m *GenerateRequest) GetMetadata() map[string]string {
return nil
}
func (m *GenerateRequest) GetNamespace() string {
func (m *GenerateRequest) GetScopes() []string {
if m != nil {
return m.Namespace
return m.Scopes
}
return ""
return nil
}
func (m *GenerateRequest) GetSecret() string {
@ -462,7 +438,7 @@ func (m *GenerateResponse) GetAccount() *Account {
}
type GrantRequest struct {
Role string `protobuf:"bytes,1,opt,name=role,proto3" json:"role,omitempty"`
Scope string `protobuf:"bytes,1,opt,name=scope,proto3" json:"scope,omitempty"`
Resource *Resource `protobuf:"bytes,2,opt,name=resource,proto3" json:"resource,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
@ -494,9 +470,9 @@ func (m *GrantRequest) XXX_DiscardUnknown() {
var xxx_messageInfo_GrantRequest proto.InternalMessageInfo
func (m *GrantRequest) GetRole() string {
func (m *GrantRequest) GetScope() string {
if m != nil {
return m.Role
return m.Scope
}
return ""
}
@ -540,7 +516,7 @@ func (m *GrantResponse) XXX_DiscardUnknown() {
var xxx_messageInfo_GrantResponse proto.InternalMessageInfo
type RevokeRequest struct {
Role string `protobuf:"bytes,1,opt,name=role,proto3" json:"role,omitempty"`
Scope string `protobuf:"bytes,1,opt,name=scope,proto3" json:"scope,omitempty"`
Resource *Resource `protobuf:"bytes,2,opt,name=resource,proto3" json:"resource,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
@ -572,9 +548,9 @@ func (m *RevokeRequest) XXX_DiscardUnknown() {
var xxx_messageInfo_RevokeRequest proto.InternalMessageInfo
func (m *RevokeRequest) GetRole() string {
func (m *RevokeRequest) GetScope() string {
if m != nil {
return m.Role
return m.Scope
}
return ""
}
@ -799,7 +775,7 @@ func (m *TokenResponse) GetToken() *Token {
type Rule struct {
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Role string `protobuf:"bytes,2,opt,name=role,proto3" json:"role,omitempty"`
Scope string `protobuf:"bytes,2,opt,name=scope,proto3" json:"scope,omitempty"`
Resource *Resource `protobuf:"bytes,3,opt,name=resource,proto3" json:"resource,omitempty"`
Access Access `protobuf:"varint,4,opt,name=access,proto3,enum=go.micro.auth.Access" json:"access,omitempty"`
Priority int32 `protobuf:"varint,5,opt,name=priority,proto3" json:"priority,omitempty"`
@ -840,9 +816,9 @@ func (m *Rule) GetId() string {
return ""
}
func (m *Rule) GetRole() string {
func (m *Rule) GetScope() string {
if m != nil {
return m.Role
return m.Scope
}
return ""
}
@ -869,13 +845,10 @@ func (m *Rule) GetPriority() int32 {
}
type CreateRequest struct {
Role string `protobuf:"bytes,1,opt,name=role,proto3" json:"role,omitempty"`
Resource *Resource `protobuf:"bytes,2,opt,name=resource,proto3" json:"resource,omitempty"`
Access Access `protobuf:"varint,3,opt,name=access,proto3,enum=go.micro.auth.Access" json:"access,omitempty"`
Priority int32 `protobuf:"varint,4,opt,name=priority,proto3" json:"priority,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
Rule *Rule `protobuf:"bytes,1,opt,name=rule,proto3" json:"rule,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *CreateRequest) Reset() { *m = CreateRequest{} }
@ -903,34 +876,13 @@ func (m *CreateRequest) XXX_DiscardUnknown() {
var xxx_messageInfo_CreateRequest proto.InternalMessageInfo
func (m *CreateRequest) GetRole() string {
func (m *CreateRequest) GetRule() *Rule {
if m != nil {
return m.Role
}
return ""
}
func (m *CreateRequest) GetResource() *Resource {
if m != nil {
return m.Resource
return m.Rule
}
return nil
}
func (m *CreateRequest) GetAccess() Access {
if m != nil {
return m.Access
}
return Access_UNKNOWN
}
func (m *CreateRequest) GetPriority() int32 {
if m != nil {
return m.Priority
}
return 0
}
type CreateResponse struct {
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
@ -963,13 +915,10 @@ func (m *CreateResponse) XXX_DiscardUnknown() {
var xxx_messageInfo_CreateResponse proto.InternalMessageInfo
type DeleteRequest struct {
Role string `protobuf:"bytes,1,opt,name=role,proto3" json:"role,omitempty"`
Resource *Resource `protobuf:"bytes,2,opt,name=resource,proto3" json:"resource,omitempty"`
Access Access `protobuf:"varint,3,opt,name=access,proto3,enum=go.micro.auth.Access" json:"access,omitempty"`
Priority int32 `protobuf:"varint,4,opt,name=priority,proto3" json:"priority,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *DeleteRequest) Reset() { *m = DeleteRequest{} }
@ -997,34 +946,13 @@ func (m *DeleteRequest) XXX_DiscardUnknown() {
var xxx_messageInfo_DeleteRequest proto.InternalMessageInfo
func (m *DeleteRequest) GetRole() string {
func (m *DeleteRequest) GetId() string {
if m != nil {
return m.Role
return m.Id
}
return ""
}
func (m *DeleteRequest) GetResource() *Resource {
if m != nil {
return m.Resource
}
return nil
}
func (m *DeleteRequest) GetAccess() Access {
if m != nil {
return m.Access
}
return Access_UNKNOWN
}
func (m *DeleteRequest) GetPriority() int32 {
if m != nil {
return m.Priority
}
return 0
}
type DeleteResponse struct {
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
@ -1157,64 +1085,62 @@ func init() {
func init() { proto.RegisterFile("auth/service/proto/auth.proto", fileDescriptor_21300bfacc51fc2a) }
var fileDescriptor_21300bfacc51fc2a = []byte{
// 900 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x56, 0xdd, 0x8e, 0xdb, 0x44,
0x14, 0x5e, 0xff, 0xc4, 0xc9, 0x9e, 0xfc, 0x6c, 0x34, 0xdd, 0x16, 0x2b, 0xed, 0x96, 0xad, 0x8b,
0xd0, 0x52, 0x41, 0x16, 0xa5, 0x37, 0x40, 0x6f, 0x58, 0x35, 0x51, 0x68, 0xa1, 0x41, 0x58, 0x45,
0xe5, 0x06, 0x55, 0xc6, 0x39, 0xb0, 0xd6, 0x66, 0x6d, 0x33, 0x33, 0x5e, 0x91, 0x1b, 0x24, 0xde,
0x81, 0x37, 0x80, 0x2b, 0x9e, 0x89, 0x7b, 0x5e, 0x03, 0xcd, 0x9f, 0x37, 0x76, 0x9c, 0xaa, 0x40,
0x2f, 0xb8, 0x9b, 0x33, 0xe7, 0xf8, 0xcc, 0xf7, 0x7d, 0xe7, 0xcc, 0xf1, 0xc0, 0x51, 0x54, 0xf0,
0xf3, 0x53, 0x86, 0xf4, 0x2a, 0x89, 0xf1, 0x34, 0xa7, 0x19, 0xcf, 0x4e, 0xc5, 0xd6, 0x58, 0x2e,
0x49, 0xff, 0x87, 0x6c, 0x7c, 0x99, 0xc4, 0x34, 0x1b, 0x8b, 0xcd, 0xe0, 0x26, 0xdc, 0xf8, 0x22,
0x61, 0xfc, 0x2c, 0x8e, 0xb3, 0x22, 0xe5, 0x2c, 0xc4, 0x1f, 0x0b, 0x64, 0x3c, 0x78, 0x0a, 0x87,
0xd5, 0x6d, 0x96, 0x67, 0x29, 0x43, 0x32, 0x81, 0x4e, 0xa4, 0xf7, 0x7c, 0xeb, 0xd8, 0x39, 0xe9,
0x4e, 0x6e, 0x8d, 0x2b, 0x09, 0xc7, 0xfa, 0x93, 0xb0, 0x8c, 0x0b, 0x7e, 0xb1, 0xa0, 0xf5, 0x3c,
0xbb, 0xc0, 0x94, 0xdc, 0x83, 0x5e, 0x14, 0xc7, 0xc8, 0xd8, 0x4b, 0x2e, 0x6c, 0xdf, 0x3a, 0xb6,
0x4e, 0xf6, 0xc3, 0xae, 0xda, 0x53, 0x21, 0xf7, 0xa1, 0x4f, 0xf1, 0x7b, 0x8a, 0xec, 0x5c, 0xc7,
0xd8, 0x32, 0xa6, 0xa7, 0x37, 0x55, 0x90, 0x0f, 0xed, 0x98, 0x62, 0xc4, 0x71, 0xe9, 0x3b, 0xc7,
0xd6, 0x89, 0x13, 0x1a, 0x93, 0xdc, 0x02, 0x0f, 0x7f, 0xca, 0x13, 0xba, 0xf6, 0x5d, 0xe9, 0xd0,
0x56, 0xf0, 0xab, 0x0d, 0x6d, 0x8d, 0x8c, 0x0c, 0xc0, 0x4e, 0x96, 0xfa, 0x6c, 0x3b, 0x59, 0x12,
0x02, 0x2e, 0x5f, 0xe7, 0xa8, 0x4f, 0x92, 0x6b, 0x72, 0x08, 0x2d, 0x9a, 0xad, 0x90, 0xf9, 0xce,
0xb1, 0x73, 0xb2, 0x1f, 0x2a, 0x83, 0x7c, 0x0a, 0x9d, 0x4b, 0xe4, 0xd1, 0x32, 0xe2, 0x91, 0xef,
0x4a, 0xf6, 0xef, 0x34, 0xb3, 0x1f, 0x3f, 0xd3, 0x61, 0xb3, 0x94, 0xd3, 0x75, 0x58, 0x7e, 0x45,
0xee, 0xc0, 0x7e, 0x1a, 0x5d, 0x22, 0xcb, 0xa3, 0x18, 0xfd, 0x96, 0x3c, 0xf0, 0x7a, 0x83, 0x8c,
0xa0, 0x93, 0xd3, 0xec, 0x2a, 0x59, 0x22, 0xf5, 0x3d, 0xe9, 0x2c, 0x6d, 0xc1, 0x8c, 0x61, 0x4c,
0x91, 0xfb, 0x6d, 0xe9, 0xd1, 0xd6, 0xe8, 0x11, 0xf4, 0x2b, 0x87, 0x91, 0x21, 0x38, 0x17, 0xb8,
0xd6, 0xfc, 0xc4, 0x52, 0x90, 0xb9, 0x8a, 0x56, 0x85, 0x61, 0xa8, 0x8c, 0x4f, 0xec, 0x8f, 0xac,
0x60, 0x05, 0x9d, 0x10, 0x59, 0x56, 0xd0, 0x18, 0x85, 0x0c, 0x02, 0x89, 0xfe, 0x50, 0xae, 0x1b,
0xa5, 0x19, 0x41, 0x07, 0xd3, 0x65, 0x9e, 0x25, 0x29, 0x97, 0xea, 0xef, 0x87, 0xa5, 0x5d, 0xa5,
0xe7, 0xd6, 0xe8, 0x05, 0xbf, 0xdb, 0x70, 0x30, 0xc7, 0x14, 0x69, 0xc4, 0x51, 0x37, 0xda, 0x56,
0x31, 0x4a, 0xe1, 0xed, 0x4d, 0xe1, 0x3f, 0xdb, 0x10, 0xde, 0x91, 0xc2, 0xbf, 0x5f, 0x13, 0xbe,
0x96, 0xf7, 0xf5, 0x0a, 0x50, 0x47, 0xb8, 0x21, 0x72, 0x6b, 0x53, 0xe4, 0x52, 0x07, 0xaf, 0xaa,
0x43, 0x59, 0xac, 0x76, 0xb5, 0x58, 0xff, 0xad, 0x28, 0x53, 0x18, 0x5e, 0xb3, 0xd1, 0xf7, 0xee,
0x43, 0x68, 0xeb, 0xfb, 0x24, 0x73, 0xec, 0xbe, 0x76, 0x26, 0x2c, 0x78, 0x01, 0xbd, 0x39, 0x8d,
0x52, 0x6e, 0x84, 0x26, 0xe0, 0x0a, 0x2d, 0x4d, 0x79, 0xc5, 0x9a, 0x3c, 0x84, 0x0e, 0xd5, 0xe5,
0x97, 0x30, 0xba, 0x93, 0xb7, 0x6a, 0x69, 0x4d, 0x77, 0x84, 0x65, 0x60, 0x70, 0x00, 0x7d, 0x9d,
0x58, 0x61, 0x0b, 0xbe, 0x81, 0x7e, 0x88, 0x57, 0xd9, 0x05, 0xbe, 0xf1, 0xa3, 0x86, 0x30, 0x30,
0x99, 0xf5, 0x59, 0xef, 0xc2, 0xe0, 0x49, 0xca, 0x72, 0x8c, 0x4b, 0x5e, 0x87, 0xd0, 0xda, 0x1c,
0x26, 0xca, 0x08, 0x1e, 0xc3, 0x41, 0x19, 0xf7, 0xaf, 0x25, 0xfc, 0x19, 0x7a, 0x72, 0xde, 0xec,
0xea, 0xd5, 0xeb, 0x6e, 0xb1, 0x2b, 0xdd, 0xb2, 0x35, 0xc3, 0x9c, 0x86, 0x19, 0x76, 0x0f, 0x7a,
0xd2, 0xf9, 0xb2, 0x32, 0xaf, 0xba, 0x72, 0x6f, 0xa6, 0x86, 0xd6, 0x23, 0xe8, 0xeb, 0xf3, 0x35,
0x85, 0x07, 0x9b, 0x5c, 0xbb, 0x93, 0xc3, 0x1a, 0x01, 0x15, 0xac, 0x15, 0xf8, 0xc3, 0x02, 0x37,
0x2c, 0x56, 0xd8, 0x34, 0xee, 0x64, 0x75, 0xec, 0x1d, 0xd5, 0x71, 0x5e, 0xb3, 0x3a, 0xe4, 0x03,
0xf0, 0xd4, 0xe4, 0x96, 0xd8, 0x07, 0x93, 0x9b, 0xdb, 0x7a, 0x22, 0x63, 0xa1, 0x0e, 0x52, 0xf7,
0x25, 0xc9, 0x68, 0xc2, 0xd7, 0xf2, 0x76, 0xb5, 0xc2, 0xd2, 0x0e, 0x7e, 0xb3, 0xa0, 0xff, 0x58,
0x8e, 0xf0, 0x37, 0xdd, 0x43, 0x1b, 0x28, 0x9d, 0x7f, 0x8a, 0xd2, 0xad, 0xa1, 0x1c, 0xc2, 0xc0,
0x80, 0xd4, 0xed, 0x28, 0x70, 0x4f, 0x71, 0x85, 0xff, 0x7b, 0xdc, 0x06, 0xa4, 0xc6, 0xdd, 0x87,
0xae, 0xf8, 0xbd, 0x9b, 0xbf, 0xfd, 0xc7, 0xd0, 0x53, 0xa6, 0xee, 0xb3, 0xf7, 0xa0, 0x45, 0x0b,
0x31, 0x84, 0xd5, 0x2f, 0xfe, 0x46, 0x1d, 0x6d, 0xb1, 0xc2, 0x50, 0x45, 0x3c, 0x18, 0x83, 0xa7,
0x90, 0x90, 0x2e, 0xb4, 0xbf, 0x5e, 0x7c, 0xbe, 0xf8, 0xf2, 0xc5, 0x62, 0xb8, 0x27, 0x8c, 0x79,
0x78, 0xb6, 0x78, 0x3e, 0x9b, 0x0e, 0x2d, 0x02, 0xe0, 0x4d, 0x67, 0x8b, 0x27, 0xb3, 0xe9, 0xd0,
0x9e, 0xfc, 0x65, 0x81, 0x7b, 0x56, 0xf0, 0x73, 0xf2, 0x0c, 0x3a, 0x66, 0xca, 0x91, 0xbb, 0xaf,
0x1e, 0xe6, 0xa3, 0xb7, 0x77, 0xfa, 0x35, 0x9f, 0x3d, 0xf2, 0x14, 0xda, 0xfa, 0xc2, 0x93, 0xa3,
0x5a, 0x74, 0x75, 0x60, 0x8c, 0xee, 0xee, 0x72, 0x97, 0xb9, 0xa6, 0xe6, 0xbd, 0x72, 0xbb, 0xf1,
0x82, 0xe9, 0x3c, 0x77, 0x9a, 0x9d, 0x26, 0xcb, 0xe4, 0x5b, 0xe8, 0x98, 0xe7, 0x13, 0xf9, 0x0a,
0x5c, 0x21, 0x30, 0x09, 0x6a, 0xdf, 0x34, 0x3c, 0xbd, 0x46, 0xf7, 0x5f, 0x19, 0x53, 0xa6, 0xff,
0xd3, 0x82, 0x96, 0x28, 0x04, 0x23, 0x73, 0xf0, 0x54, 0x5b, 0x92, 0x3a, 0xa4, 0xca, 0x95, 0x1a,
0x1d, 0xed, 0xf0, 0x96, 0xbc, 0xe7, 0xe0, 0xa9, 0x3e, 0xd9, 0x4a, 0x54, 0xe9, 0xf1, 0xad, 0x44,
0xb5, 0xe6, 0xda, 0x23, 0x67, 0x9a, 0xee, 0xa8, 0x81, 0x8a, 0x49, 0x72, 0xbb, 0xd1, 0x67, 0x52,
0x7c, 0xe7, 0xc9, 0xd7, 0xea, 0xc3, 0xbf, 0x03, 0x00, 0x00, 0xff, 0xff, 0xdf, 0x67, 0x3c, 0x6e,
0xce, 0x0a, 0x00, 0x00,
// 872 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0x51, 0x8f, 0xdb, 0x44,
0x10, 0x3e, 0x27, 0xb1, 0x93, 0x9b, 0xc4, 0x77, 0xd1, 0xf6, 0x5a, 0xac, 0x94, 0x6b, 0xaf, 0x2e,
0x82, 0xa3, 0x82, 0x1c, 0x4a, 0x5f, 0x0a, 0x7d, 0xe1, 0xd4, 0x44, 0xa1, 0x85, 0x06, 0x61, 0x15,
0x21, 0x90, 0x50, 0x65, 0x9c, 0x81, 0xb3, 0x2e, 0x67, 0x9b, 0xdd, 0xf5, 0x89, 0xbc, 0x20, 0xf1,
0xc6, 0x8f, 0xe1, 0x27, 0xf1, 0xce, 0x1f, 0xe0, 0x07, 0x20, 0xef, 0xce, 0xba, 0xb1, 0xe3, 0x54,
0x15, 0x88, 0x37, 0xcf, 0xec, 0xb7, 0xb3, 0xf3, 0x7d, 0x3b, 0x33, 0x6b, 0x38, 0x0e, 0x73, 0x79,
0x71, 0x26, 0x90, 0x5f, 0xc7, 0x11, 0x9e, 0x65, 0x3c, 0x95, 0xe9, 0x59, 0xe1, 0x1a, 0xab, 0x4f,
0xe6, 0xfe, 0x94, 0x8e, 0xaf, 0xe2, 0x88, 0xa7, 0xe3, 0xc2, 0xe9, 0xdf, 0x84, 0x1b, 0x5f, 0xc4,
0x42, 0x9e, 0x47, 0x51, 0x9a, 0x27, 0x52, 0x04, 0xf8, 0x73, 0x8e, 0x42, 0xfa, 0xcf, 0xe0, 0xa8,
0xea, 0x16, 0x59, 0x9a, 0x08, 0x64, 0x13, 0xe8, 0x85, 0xe4, 0xf3, 0xac, 0x93, 0xf6, 0x69, 0x7f,
0x72, 0x6b, 0x5c, 0x09, 0x38, 0xa6, 0x2d, 0x41, 0x89, 0xf3, 0x7f, 0xb3, 0xc0, 0x7e, 0x91, 0x5e,
0x62, 0xc2, 0xee, 0xc1, 0x20, 0x8c, 0x22, 0x14, 0xe2, 0xa5, 0x2c, 0x6c, 0xcf, 0x3a, 0xb1, 0x4e,
0xf7, 0x83, 0xbe, 0xf6, 0x69, 0xc8, 0x7d, 0x70, 0x39, 0xfe, 0xc8, 0x51, 0x5c, 0x10, 0xa6, 0xa5,
0x30, 0x03, 0x72, 0x6a, 0x90, 0x07, 0xdd, 0x88, 0x63, 0x28, 0x71, 0xe9, 0xb5, 0x4f, 0xac, 0xd3,
0x76, 0x60, 0x4c, 0x76, 0x0b, 0x1c, 0xfc, 0x25, 0x8b, 0xf9, 0xda, 0xeb, 0xa8, 0x05, 0xb2, 0xfc,
0xbf, 0x2d, 0xe8, 0x52, 0x66, 0xec, 0x00, 0x5a, 0xf1, 0x92, 0xce, 0x6e, 0xc5, 0x4b, 0xc6, 0xa0,
0x23, 0xd7, 0x19, 0xd2, 0x49, 0xea, 0x9b, 0x7d, 0x0a, 0xbd, 0x2b, 0x94, 0xe1, 0x32, 0x94, 0xa1,
0xd7, 0x51, 0x3c, 0xdf, 0x69, 0xe6, 0x39, 0x7e, 0x4e, 0xb0, 0x59, 0x22, 0xf9, 0x3a, 0x28, 0x77,
0x15, 0x99, 0x88, 0x28, 0xcd, 0x50, 0x78, 0xf6, 0x49, 0xfb, 0x74, 0x3f, 0x20, 0xab, 0xf0, 0xc7,
0x42, 0xe4, 0xc8, 0x3d, 0x47, 0x9d, 0x47, 0x96, 0xc2, 0x63, 0xc4, 0x51, 0x7a, 0x5d, 0xed, 0xd7,
0xd6, 0xe8, 0x31, 0xb8, 0x95, 0x23, 0xd8, 0x10, 0xda, 0x97, 0xb8, 0xa6, 0xfc, 0x8b, 0x4f, 0x76,
0x04, 0xf6, 0x75, 0xb8, 0xca, 0x0d, 0x03, 0x6d, 0x7c, 0xd2, 0x7a, 0x64, 0xf9, 0x0b, 0xe8, 0x05,
0x28, 0xd2, 0x9c, 0x47, 0x58, 0xd0, 0x4c, 0xc2, 0x2b, 0xa4, 0x8d, 0xea, 0xbb, 0x91, 0xfa, 0x08,
0x7a, 0x98, 0x2c, 0xb3, 0x34, 0x4e, 0xa4, 0x52, 0x77, 0x3f, 0x28, 0x6d, 0xff, 0xf7, 0x16, 0x1c,
0xce, 0x31, 0x41, 0x1e, 0x4a, 0xa4, 0x52, 0xd9, 0x92, 0xf3, 0xb3, 0x0d, 0xe9, 0xda, 0x4a, 0xba,
0x0f, 0x6a, 0xd2, 0xd5, 0x22, 0xbc, 0x81, 0x84, 0x9d, 0xba, 0x84, 0x24, 0x95, 0xbd, 0x29, 0x55,
0xc9, 0xc6, 0xa9, 0xb2, 0xc9, 0x78, 0x7a, 0x1d, 0x2f, 0x91, 0x93, 0xb0, 0xa5, 0xfd, 0xdf, 0xa4,
0x9d, 0xc2, 0xf0, 0x15, 0x0f, 0xea, 0x8e, 0x8f, 0xa0, 0x4b, 0x55, 0xaf, 0x62, 0xec, 0x6e, 0x0e,
0x03, 0xf3, 0xbf, 0x85, 0xc1, 0x9c, 0x87, 0x89, 0x34, 0x62, 0x1e, 0x81, 0xad, 0x48, 0x52, 0x0e,
0xda, 0x60, 0x0f, 0xa1, 0xc7, 0xe9, 0x1a, 0x55, 0x22, 0xfd, 0xc9, 0x5b, 0xb5, 0xc0, 0xe6, 0x96,
0x83, 0x12, 0xe8, 0x1f, 0x82, 0x4b, 0xa1, 0x75, 0x76, 0xfe, 0x77, 0xe0, 0x06, 0x78, 0x9d, 0x5e,
0xe2, 0xff, 0x70, 0xd8, 0x10, 0x0e, 0x4c, 0x6c, 0x3a, 0xed, 0x5d, 0x38, 0x78, 0x9a, 0x88, 0x0c,
0xa3, 0x4d, 0x6e, 0x9b, 0x6d, 0xaf, 0x0d, 0xff, 0x09, 0x1c, 0x96, 0xb8, 0x7f, 0x2d, 0xe3, 0xaf,
0x30, 0x50, 0x93, 0x61, 0x57, 0x4d, 0xbe, 0xaa, 0x98, 0x56, 0xa5, 0x62, 0xb6, 0xa6, 0x4d, 0xbb,
0x61, 0xda, 0xdc, 0x83, 0x81, 0x5a, 0x7c, 0x59, 0x99, 0x2c, 0x7d, 0xe5, 0x9b, 0xe9, 0xf1, 0xf2,
0x18, 0x5c, 0x3a, 0x9f, 0x28, 0x3c, 0xd8, 0xe4, 0xda, 0x9f, 0x1c, 0xd5, 0x08, 0x68, 0x30, 0x29,
0xf0, 0x87, 0x05, 0x9d, 0x20, 0x5f, 0xe1, 0x56, 0xd6, 0xe5, 0xfd, 0xb4, 0x76, 0xdd, 0x4f, 0xfb,
0x0d, 0xef, 0x87, 0x7d, 0x08, 0x8e, 0x9e, 0xb2, 0x2a, 0xfb, 0x83, 0xc9, 0xcd, 0x6d, 0x45, 0x51,
0x88, 0x80, 0x40, 0xba, 0x6b, 0xe2, 0x94, 0xc7, 0x72, 0xad, 0x7a, 0xcc, 0x0e, 0x4a, 0xdb, 0x7f,
0x04, 0xee, 0x13, 0x35, 0x6d, 0x8d, 0xd8, 0xef, 0x41, 0x87, 0xe7, 0x2b, 0x24, 0xaa, 0x37, 0xea,
0xc9, 0xe4, 0x2b, 0x0c, 0x14, 0xa0, 0x28, 0x12, 0xb3, 0x93, 0x8a, 0xe4, 0x2e, 0xb8, 0x53, 0x5c,
0xe1, 0xce, 0x61, 0x52, 0x6c, 0x31, 0x00, 0xda, 0xe2, 0x42, 0xbf, 0x78, 0x99, 0xcc, 0x43, 0xf5,
0x31, 0x0c, 0xb4, 0x49, 0xc2, 0xbf, 0x0f, 0x76, 0x71, 0x96, 0x79, 0x9d, 0x1a, 0xb3, 0xd1, 0x88,
0x07, 0x63, 0x70, 0x34, 0x6d, 0xd6, 0x87, 0xee, 0xd7, 0x8b, 0xcf, 0x17, 0x5f, 0x7e, 0xb3, 0x18,
0xee, 0x15, 0xc6, 0x3c, 0x38, 0x5f, 0xbc, 0x98, 0x4d, 0x87, 0x16, 0x03, 0x70, 0xa6, 0xb3, 0xc5,
0xd3, 0xd9, 0x74, 0xd8, 0x9a, 0xfc, 0x65, 0x41, 0xe7, 0x3c, 0x97, 0x17, 0xec, 0x39, 0xf4, 0x4c,
0xeb, 0xb3, 0x3b, 0xaf, 0x9f, 0x6d, 0xa3, 0xbb, 0x3b, 0xd7, 0x89, 0xcf, 0x1e, 0x7b, 0x06, 0x5d,
0xea, 0x00, 0x76, 0x5c, 0x43, 0x57, 0x3b, 0x68, 0x74, 0x67, 0xd7, 0x72, 0x19, 0x6b, 0x6a, 0x9e,
0xda, 0xdb, 0x8d, 0x15, 0x47, 0x71, 0xde, 0x6e, 0x5e, 0x34, 0x51, 0x26, 0xdf, 0x43, 0xcf, 0xbc,
0xfc, 0xec, 0x2b, 0xe8, 0x14, 0x02, 0x33, 0xbf, 0xb6, 0xa7, 0xe1, 0xaf, 0x61, 0x74, 0xff, 0xb5,
0x98, 0x32, 0xfc, 0x9f, 0x16, 0xd8, 0xc5, 0x45, 0x08, 0x36, 0x07, 0x47, 0x57, 0x04, 0xab, 0xa7,
0x54, 0x29, 0xb1, 0xd1, 0xf1, 0x8e, 0xd5, 0x92, 0xf7, 0x1c, 0x1c, 0x5d, 0x27, 0x5b, 0x81, 0x2a,
0xf5, 0xb5, 0x15, 0xa8, 0x56, 0x5c, 0x7b, 0xec, 0x9c, 0xe8, 0x8e, 0x1a, 0xa8, 0x98, 0x20, 0xb7,
0x1b, 0xd7, 0x4c, 0x88, 0x1f, 0x1c, 0xf5, 0xa3, 0xf5, 0xf0, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff,
0x52, 0x12, 0xc2, 0xdb, 0x89, 0x09, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.

View File

@ -35,10 +35,9 @@ message Token {
message Account {
string id = 1;
string type = 2;
repeated string roles = 3;
map<string, string> metadata = 4;
string namespace = 5;
string provider = 6;
repeated string scopes = 5;
string issuer = 6;
string secret = 7;
}
@ -46,14 +45,12 @@ message Resource{
string name = 1;
string type = 2;
string endpoint = 3;
string namespace = 4;
}
message GenerateRequest {
string id = 1;
repeated string roles = 2;
map<string, string> metadata = 3;
string namespace = 4;
repeated string scopes = 4;
string secret = 5;
string type = 6;
string provider = 7;
@ -64,14 +61,14 @@ message GenerateResponse {
}
message GrantRequest {
string role = 1;
string scope = 1;
Resource resource = 2;
}
message GrantResponse {}
message RevokeRequest {
string role = 1;
string scope = 1;
Resource resource = 2;
}
@ -104,26 +101,20 @@ enum Access {
message Rule {
string id = 1;
string role = 2;
string scope = 2;
Resource resource = 3;
Access access = 4;
int32 priority = 5;
}
message CreateRequest {
string role = 1;
Resource resource = 2;
Access access = 3;
int32 priority = 4;
Rule rule = 1;
}
message CreateResponse {}
message DeleteRequest {
string role = 1;
Resource resource = 2;
Access access = 3;
int32 priority = 4;
string id = 1;
}
message DeleteResponse {}

View File

@ -2,25 +2,22 @@ package service
import (
"context"
"fmt"
"sort"
"strings"
"time"
"github.com/micro/go-micro/v2/auth"
"github.com/micro/go-micro/v2/auth/rules"
pb "github.com/micro/go-micro/v2/auth/service/proto"
"github.com/micro/go-micro/v2/auth/token"
"github.com/micro/go-micro/v2/auth/token/jwt"
"github.com/micro/go-micro/v2/client"
log "github.com/micro/go-micro/v2/logger"
"github.com/micro/go-micro/v2/util/jitter"
)
// svc is the service implementation of the Auth interface
type svc struct {
options auth.Options
auth pb.AuthService
rule pb.RulesService
rules pb.RulesService
jwt token.Provider
}
@ -38,7 +35,7 @@ func (s *svc) Init(opts ...auth.Option) {
}
s.auth = pb.NewAuthService("go.micro.auth", s.options.Client)
s.rule = pb.NewRulesService("go.micro.auth", s.options.Client)
s.rules = pb.NewRulesService("go.micro.auth", s.options.Client)
// if we have a JWT public key passed as an option,
// we can decode tokens with the type "JWT" locally
@ -57,13 +54,12 @@ func (s *svc) Generate(id string, opts ...auth.GenerateOption) (*auth.Account, e
options := auth.NewGenerateOptions(opts...)
rsp, err := s.auth.Generate(context.TODO(), &pb.GenerateRequest{
Id: id,
Type: options.Type,
Secret: options.Secret,
Roles: options.Roles,
Metadata: options.Metadata,
Provider: options.Provider,
Namespace: options.Namespace,
Id: id,
Type: options.Type,
Secret: options.Secret,
Scopes: options.Scopes,
Metadata: options.Metadata,
Provider: options.Provider,
})
if err != nil {
return nil, err
@ -73,87 +69,75 @@ func (s *svc) Generate(id string, opts ...auth.GenerateOption) (*auth.Account, e
}
// Grant access to a resource
func (s *svc) Grant(role string, res *auth.Resource) error {
_, err := s.rule.Create(context.TODO(), &pb.CreateRequest{
Role: role,
Access: pb.Access_GRANTED,
Resource: &pb.Resource{
Namespace: res.Namespace,
Type: res.Type,
Name: res.Name,
Endpoint: res.Endpoint,
func (s *svc) Grant(rule *auth.Rule) error {
access := pb.Access_UNKNOWN
if rule.Access == auth.AccessGranted {
access = pb.Access_GRANTED
} else if rule.Access == auth.AccessDenied {
access = pb.Access_DENIED
}
_, err := s.rules.Create(context.TODO(), &pb.CreateRequest{
Rule: &pb.Rule{
Id: rule.ID,
Scope: rule.Scope,
Priority: rule.Priority,
Access: access,
Resource: &pb.Resource{
Type: rule.Resource.Type,
Name: rule.Resource.Name,
Endpoint: rule.Resource.Endpoint,
},
},
})
return err
}
// Revoke access to a resource
func (s *svc) Revoke(role string, res *auth.Resource) error {
_, err := s.rule.Delete(context.TODO(), &pb.DeleteRequest{
Role: role,
Access: pb.Access_GRANTED,
Resource: &pb.Resource{
Namespace: res.Namespace,
Type: res.Type,
Name: res.Name,
Endpoint: res.Endpoint,
},
func (s *svc) Revoke(rule *auth.Rule) error {
_, err := s.rules.Delete(context.TODO(), &pb.DeleteRequest{
Id: rule.ID,
})
return err
}
func (s *svc) Rules(opts ...auth.RulesOption) ([]*auth.Rule, error) {
var options auth.RulesOptions
for _, o := range opts {
o(&options)
}
if options.Context == nil {
options.Context = context.TODO()
}
rsp, err := s.rules.List(options.Context, &pb.ListRequest{}, client.WithCache(time.Second*30))
if err != nil {
return nil, err
}
rules := make([]*auth.Rule, len(rsp.Rules))
for i, r := range rsp.Rules {
rules[i] = serializeRule(r)
}
return rules, nil
}
// Verify an account has access to a resource
func (s *svc) Verify(acc *auth.Account, res *auth.Resource) error {
// set the namespace on the resource
if len(res.Namespace) == 0 {
res.Namespace = s.Options().Namespace
func (s *svc) Verify(acc *auth.Account, res *auth.Resource, opts ...auth.VerifyOption) error {
var options auth.VerifyOptions
for _, o := range opts {
o(&options)
}
queries := [][]string{
{res.Namespace, res.Type, res.Name, res.Endpoint}, // check for specific role, e.g. service.foo.ListFoo:admin (role is checked in accessForRule)
{res.Namespace, res.Type, res.Name, "*"}, // check for wildcard endpoint, e.g. service.foo*
{res.Namespace, res.Type, "*"}, // check for wildcard name, e.g. service.*
{res.Namespace, "*"}, // check for wildcard type, e.g. *
{"*"}, // check for wildcard namespace
rs, err := s.Rules(auth.RulesContext(options.Context))
if err != nil {
return err
}
// endpoint is a url which can have wildcard excludes, e.g.
// "/foo/*" will allow "/foo/bar"
if comps := strings.Split(res.Endpoint, "/"); len(comps) > 1 {
for i := 1; i < len(comps); i++ {
wildcard := fmt.Sprintf("%v/*", strings.Join(comps[0:i], "/"))
queries = append(queries, []string{res.Type, res.Name, wildcard})
}
}
// set a default account id / namespace to log
logID := acc.ID
if len(logID) == 0 {
logID = "[no account]"
}
logNamespace := acc.Namespace
if len(logNamespace) == 0 {
logNamespace = "[no namespace]"
}
for _, q := range queries {
for _, rule := range s.listRules(q...) {
switch accessForRule(rule, acc, res) {
case pb.Access_UNKNOWN:
continue // rule did not specify access, check the next rule
case pb.Access_GRANTED:
log.Tracef("%v:%v granted access to %v:%v:%v:%v by rule %v", logNamespace, logID, res.Namespace, res.Type, res.Name, res.Endpoint, rule.Id)
return nil // rule grants the account access to the resource
case pb.Access_DENIED:
log.Tracef("%v:%v denied access to %v:%v:%v:%v by rule %v", logNamespace, logID, res.Namespace, res.Type, res.Name, res.Endpoint, rule.Id)
return auth.ErrForbidden // rule denies access to the resource
}
}
}
// no rules were found for the resource, default to denying access
log.Tracef("%v:%v denied access to %v:%v:%v:%v by lack of rule (%v rules found for namespace)", logNamespace, logID, res.Namespace, res.Type, res.Name, res.Endpoint, len(s.listRules(res.Namespace)))
return auth.ErrForbidden
return rules.Verify(rs, acc, res)
}
// Inspect a token
@ -189,82 +173,6 @@ func (s *svc) Token(opts ...auth.TokenOption) (*auth.Token, error) {
return serializeToken(rsp.Token), nil
}
var ruleJoinKey = ":"
// accessForRule returns a rule status, indicating if a rule permits access to a
// resource for a given account
func accessForRule(rule *pb.Rule, acc *auth.Account, res *auth.Resource) pb.Access {
// a blank role permits access to the public
if rule.Role == "" {
return rule.Access
}
// a * role permits access to any user
if rule.Role == "*" && acc != nil {
return rule.Access
}
for _, role := range acc.Roles {
if rule.Role == role {
return rule.Access
}
// allow user.anything if role is user.*
if strings.HasSuffix(rule.Role, ".*") && strings.HasPrefix(rule.Role, role+".") {
return rule.Access
}
}
return pb.Access_UNKNOWN
}
// listRules gets all the rules from the store which match the filters.
// filters are namespace, type, name and then endpoint.
func (s *svc) listRules(filters ...string) []*pb.Rule {
// load rules using the client cache
allRules, err := s.loadRules()
if err != nil {
return []*pb.Rule{}
}
var rules []*pb.Rule
for _, r := range allRules {
if len(filters) > 0 && r.Resource.Namespace != filters[0] {
continue
}
if len(filters) > 1 && r.Resource.Type != filters[1] {
continue
}
if len(filters) > 2 && r.Resource.Name != filters[2] {
continue
}
if len(filters) > 3 && r.Resource.Endpoint != filters[3] {
continue
}
rules = append(rules, r)
}
// sort rules by priority
sort.Slice(rules, func(i, j int) bool {
return rules[i].Priority < rules[j].Priority
})
return rules
}
// loadRules retrieves the rules from the auth service
func (s *svc) loadRules() ([]*pb.Rule, error) {
rsp, err := s.rule.List(context.TODO(), &pb.ListRequest{}, client.WithCache(time.Minute))
if err != nil {
log.Debugf("Error listing rules: %v", err)
return nil, err
}
return rsp.Rules, nil
}
func serializeToken(t *pb.Token) *auth.Token {
return &auth.Token{
AccessToken: t.AccessToken,
@ -276,12 +184,32 @@ func serializeToken(t *pb.Token) *auth.Token {
func serializeAccount(a *pb.Account) *auth.Account {
return &auth.Account{
ID: a.Id,
Roles: a.Roles,
Secret: a.Secret,
Metadata: a.Metadata,
Provider: a.Provider,
Namespace: a.Namespace,
ID: a.Id,
Secret: a.Secret,
Issuer: a.Issuer,
Metadata: a.Metadata,
Scopes: a.Scopes,
}
}
func serializeRule(r *pb.Rule) *auth.Rule {
var access auth.Access
if r.Access == pb.Access_GRANTED {
access = auth.AccessGranted
} else {
access = auth.AccessDenied
}
return &auth.Rule{
ID: r.Id,
Scope: r.Scope,
Access: access,
Priority: r.Priority,
Resource: &auth.Resource{
Type: r.Resource.Type,
Name: r.Resource.Name,
Endpoint: r.Resource.Endpoint,
},
}
}
@ -292,22 +220,9 @@ func NewAuth(opts ...auth.Option) auth.Auth {
options.Client = client.DefaultClient
}
service := &svc{
return &svc{
auth: pb.NewAuthService("go.micro.auth", options.Client),
rule: pb.NewRulesService("go.micro.auth", options.Client),
rules: pb.NewRulesService("go.micro.auth", options.Client),
options: options,
}
// load rules periodically from the auth service
go func() {
ruleTimer := time.NewTicker(time.Second * 30)
for {
<-ruleTimer.C
time.Sleep(jitter.Do(time.Second * 5))
service.loadRules()
}
}()
return service
}

View File

@ -32,10 +32,10 @@ func TestInspect(t *testing.T) {
t.Run("Valid token", func(t *testing.T) {
md := map[string]string{"foo": "bar"}
roles := []string{"admin"}
scopes := []string{"admin"}
subject := "test"
tok, err := b.Generate(&auth.Account{ID: subject, Roles: roles, Metadata: md})
tok, err := b.Generate(&auth.Account{ID: subject, Scopes: scopes, Metadata: md})
if err != nil {
t.Fatalf("Generate returned %v error, expected nil", err)
}
@ -47,8 +47,8 @@ func TestInspect(t *testing.T) {
if tok2.ID != subject {
t.Errorf("Inspect returned %v as the token subject, expected %v", tok2.ID, subject)
}
if len(tok2.Roles) != len(roles) {
t.Errorf("Inspect returned %v roles, expected %v", len(tok2.Roles), len(roles))
if len(tok2.Scopes) != len(scopes) {
t.Errorf("Inspect returned %v scopes, expected %v", len(tok2.Scopes), len(scopes))
}
if len(tok2.Metadata) != len(md) {
t.Errorf("Inspect returned %v as the token metadata, expected %v", tok2.Metadata, md)

View File

@ -11,11 +11,9 @@ import (
// authClaims to be encoded in the JWT
type authClaims struct {
Type string `json:"type"`
Roles []string `json:"roles"`
Provider string `json:"provider"`
Metadata map[string]string `json:"metadata"`
Namespace string `json:"namespace"`
Type string `json:"type"`
Scopes []string `json:"scopes"`
Metadata map[string]string `json:"metadata"`
jwt.StandardClaims
}
@ -52,8 +50,9 @@ func (j *JWT) Generate(acc *auth.Account, opts ...token.GenerateOption) (*token.
// generate the JWT
expiry := time.Now().Add(options.Expiry)
t := jwt.NewWithClaims(jwt.SigningMethodRS256, authClaims{
acc.Type, acc.Roles, acc.Provider, acc.Metadata, acc.Namespace, jwt.StandardClaims{
acc.Type, acc.Scopes, acc.Metadata, jwt.StandardClaims{
Subject: acc.ID,
Issuer: acc.Issuer,
ExpiresAt: expiry.Unix(),
},
})
@ -97,12 +96,11 @@ func (j *JWT) Inspect(t string) (*auth.Account, error) {
// return the token
return &auth.Account{
ID: claims.Subject,
Type: claims.Type,
Roles: claims.Roles,
Provider: claims.Provider,
Metadata: claims.Metadata,
Namespace: claims.Namespace,
ID: claims.Subject,
Issuer: claims.Issuer,
Type: claims.Type,
Scopes: claims.Scopes,
Metadata: claims.Metadata,
}, nil
}

View File

@ -42,10 +42,10 @@ func TestInspect(t *testing.T) {
t.Run("Valid token", func(t *testing.T) {
md := map[string]string{"foo": "bar"}
roles := []string{"admin"}
scopes := []string{"admin"}
subject := "test"
acc := &auth.Account{ID: subject, Roles: roles, Metadata: md}
acc := &auth.Account{ID: subject, Scopes: scopes, Metadata: md}
tok, err := j.Generate(acc)
if err != nil {
t.Fatalf("Generate returned %v error, expected nil", err)
@ -58,8 +58,8 @@ func TestInspect(t *testing.T) {
if acc.ID != subject {
t.Errorf("Inspect returned %v as the token subject, expected %v", acc.ID, subject)
}
if len(tok2.Roles) != len(roles) {
t.Errorf("Inspect returned %v roles, expected %v", len(tok2.Roles), len(roles))
if len(tok2.Scopes) != len(scopes) {
t.Errorf("Inspect returned %v scopes, expected %v", len(tok2.Scopes), len(scopes))
}
if len(tok2.Metadata) != len(md) {
t.Errorf("Inspect returned %v as the token metadata, expected %v", tok2.Metadata, md)

View File

@ -48,10 +48,10 @@ func (c *Cache) List() map[string]string {
// key returns a hash for the context and request
func key(ctx context.Context, req *Request) string {
md, _ := metadata.FromContext(ctx)
ns, _ := metadata.Get(ctx, "Micro-Namespace")
bytes, _ := json.Marshal(map[string]interface{}{
"metadata": md,
"namespace": ns,
"request": map[string]interface{}{
"service": (*req).Service(),
"endpoint": (*req).Endpoint(),

View File

@ -65,7 +65,7 @@ func TestCacheKey(t *testing.T) {
})
t.Run("DifferentMetadata", func(t *testing.T) {
mdCtx := metadata.Set(context.TODO(), "foo", "bar")
mdCtx := metadata.Set(context.TODO(), "Micro-Namespace", "bar")
key1 := key(mdCtx, &req1)
key2 := key(ctx, &req1)

View File

@ -278,6 +278,7 @@ var (
Name: "auth_namespace",
EnvVars: []string{"MICRO_AUTH_NAMESPACE"},
Usage: "Namespace for the services auth account",
Value: "go.micro",
},
&cli.StringFlag{
Name: "auth_public_key",

View File

@ -166,9 +166,7 @@ type CreateOptions struct {
// create type of service
Type string `protobuf:"bytes,5,opt,name=type,proto3" json:"type,omitempty"`
// image to use
Image string `protobuf:"bytes,6,opt,name=image,proto3" json:"image,omitempty"`
// namespace to use
Namespace string `protobuf:"bytes,7,opt,name=namespace,proto3" json:"namespace,omitempty"`
Image string `protobuf:"bytes,6,opt,name=image,proto3" json:"image,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -241,13 +239,6 @@ func (m *CreateOptions) GetImage() string {
return ""
}
func (m *CreateOptions) GetNamespace() string {
if m != nil {
return m.Namespace
}
return ""
}
type CreateRequest struct {
Service *Service `protobuf:"bytes,1,opt,name=service,proto3" json:"service,omitempty"`
Options *CreateOptions `protobuf:"bytes,2,opt,name=options,proto3" json:"options,omitempty"`
@ -332,9 +323,7 @@ type ReadOptions struct {
// version of the service
Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"`
// type of service
Type string `protobuf:"bytes,3,opt,name=type,proto3" json:"type,omitempty"`
// namespace of service
Namespace string `protobuf:"bytes,4,opt,name=namespace,proto3" json:"namespace,omitempty"`
Type string `protobuf:"bytes,3,opt,name=type,proto3" json:"type,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -386,13 +375,6 @@ func (m *ReadOptions) GetType() string {
return ""
}
func (m *ReadOptions) GetNamespace() string {
if m != nil {
return m.Namespace
}
return ""
}
type ReadRequest struct {
Options *ReadOptions `protobuf:"bytes,1,opt,name=options,proto3" json:"options,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
@ -472,8 +454,6 @@ func (m *ReadResponse) GetServices() []*Service {
}
type DeleteOptions struct {
// namespace of the service
Namespace string `protobuf:"bytes,1,opt,name=namespace,proto3" json:"namespace,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -504,13 +484,6 @@ func (m *DeleteOptions) XXX_DiscardUnknown() {
var xxx_messageInfo_DeleteOptions proto.InternalMessageInfo
func (m *DeleteOptions) GetNamespace() string {
if m != nil {
return m.Namespace
}
return ""
}
type DeleteRequest struct {
Service *Service `protobuf:"bytes,1,opt,name=service,proto3" json:"service,omitempty"`
Options *DeleteOptions `protobuf:"bytes,2,opt,name=options,proto3" json:"options,omitempty"`
@ -590,8 +563,6 @@ func (m *DeleteResponse) XXX_DiscardUnknown() {
var xxx_messageInfo_DeleteResponse proto.InternalMessageInfo
type UpdateOptions struct {
// namespace of the service
Namespace string `protobuf:"bytes,1,opt,name=namespace,proto3" json:"namespace,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -622,13 +593,6 @@ func (m *UpdateOptions) XXX_DiscardUnknown() {
var xxx_messageInfo_UpdateOptions proto.InternalMessageInfo
func (m *UpdateOptions) GetNamespace() string {
if m != nil {
return m.Namespace
}
return ""
}
type UpdateRequest struct {
Service *Service `protobuf:"bytes,1,opt,name=service,proto3" json:"service,omitempty"`
Options *UpdateOptions `protobuf:"bytes,2,opt,name=options,proto3" json:"options,omitempty"`
@ -708,8 +672,6 @@ func (m *UpdateResponse) XXX_DiscardUnknown() {
var xxx_messageInfo_UpdateResponse proto.InternalMessageInfo
type ListOptions struct {
// namespace to list from
Namespace string `protobuf:"bytes,1,opt,name=namespace,proto3" json:"namespace,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -740,13 +702,6 @@ func (m *ListOptions) XXX_DiscardUnknown() {
var xxx_messageInfo_ListOptions proto.InternalMessageInfo
func (m *ListOptions) GetNamespace() string {
if m != nil {
return m.Namespace
}
return ""
}
type ListRequest struct {
Options *ListOptions `protobuf:"bytes,1,opt,name=options,proto3" json:"options,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
@ -826,8 +781,6 @@ func (m *ListResponse) GetServices() []*Service {
}
type LogsOptions struct {
// namespace of the service
Namespace string `protobuf:"bytes,1,opt,name=namespace,proto3" json:"namespace,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -858,13 +811,6 @@ func (m *LogsOptions) XXX_DiscardUnknown() {
var xxx_messageInfo_LogsOptions proto.InternalMessageInfo
func (m *LogsOptions) GetNamespace() string {
if m != nil {
return m.Namespace
}
return ""
}
type LogsRequest struct {
// service to request logs for
Service string `protobuf:"bytes,1,opt,name=service,proto3" json:"service,omitempty"`
@ -1031,52 +977,50 @@ func init() {
}
var fileDescriptor_2434d8152598889b = []byte{
// 711 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0x4d, 0x6f, 0xd3, 0x4c,
0x10, 0xae, 0x63, 0x27, 0x69, 0x27, 0x6f, 0x5e, 0x55, 0xab, 0x0a, 0x99, 0xf2, 0x15, 0x99, 0x03,
0x45, 0xa8, 0x2e, 0x4a, 0x85, 0xf8, 0x3a, 0x96, 0x94, 0x4b, 0x2b, 0x24, 0x23, 0x7e, 0xc0, 0xe2,
0x8c, 0x22, 0x8b, 0xda, 0x6b, 0xbc, 0xeb, 0x48, 0x3d, 0x71, 0xe4, 0x8f, 0x70, 0xe7, 0x67, 0x70,
0xe6, 0x1f, 0xa1, 0xfd, 0x8a, 0x3f, 0x1a, 0x47, 0xad, 0xaa, 0xde, 0x76, 0xc6, 0xb3, 0xb3, 0xcf,
0xf3, 0xcc, 0xec, 0xac, 0xe1, 0x69, 0x51, 0x66, 0x22, 0x49, 0xf1, 0x88, 0x63, 0xb1, 0x4c, 0x62,
0x3c, 0xca, 0x0b, 0x26, 0xd8, 0x91, 0xf1, 0x86, 0xca, 0x22, 0xbb, 0x0b, 0x16, 0xa6, 0x49, 0x5c,
0xb0, 0xd0, 0xf8, 0x83, 0xbf, 0x0e, 0x0c, 0x3f, 0xeb, 0x1d, 0x84, 0x80, 0x97, 0xd1, 0x14, 0x7d,
0x67, 0xe2, 0x1c, 0xec, 0x44, 0x6a, 0x4d, 0x7c, 0x18, 0x2e, 0xb1, 0xe0, 0x09, 0xcb, 0xfc, 0x9e,
0x72, 0x5b, 0x93, 0xdc, 0x83, 0x01, 0x67, 0x65, 0x11, 0xa3, 0xef, 0xaa, 0x0f, 0xc6, 0x22, 0x27,
0xb0, 0x9d, 0xa2, 0xa0, 0x73, 0x2a, 0xa8, 0xef, 0x4d, 0xdc, 0x83, 0xd1, 0xf4, 0x59, 0xd8, 0x3e,
0x36, 0x34, 0x47, 0x86, 0xe7, 0x26, 0x72, 0x96, 0x89, 0xe2, 0x32, 0x5a, 0x6d, 0xdc, 0x7f, 0x0f,
0xe3, 0xc6, 0x27, 0xb2, 0x0b, 0xee, 0x37, 0xbc, 0x34, 0xd0, 0xe4, 0x92, 0xec, 0x41, 0x7f, 0x49,
0x2f, 0x4a, 0x34, 0xb8, 0xb4, 0xf1, 0xae, 0xf7, 0xc6, 0x09, 0x52, 0xe8, 0xcf, 0x96, 0x98, 0x09,
0x49, 0x48, 0x5c, 0xe6, 0x2b, 0x42, 0x72, 0x4d, 0x1e, 0xc2, 0x8e, 0x44, 0xc0, 0x05, 0x4d, 0x73,
0xb5, 0xd5, 0x8d, 0x2a, 0x87, 0xa4, 0x6b, 0xf4, 0x33, 0xac, 0xac, 0x59, 0x17, 0xc2, 0x6b, 0x08,
0x11, 0xfc, 0x76, 0x60, 0x7c, 0x52, 0x20, 0x15, 0xf8, 0x29, 0x17, 0x09, 0xcb, 0xb8, 0x8c, 0x8d,
0x59, 0x9a, 0xd2, 0x6c, 0xee, 0x3b, 0x13, 0x57, 0xc6, 0x1a, 0x53, 0x22, 0xa2, 0xc5, 0x82, 0xfb,
0x3d, 0xe5, 0x56, 0x6b, 0x49, 0x0d, 0xb3, 0xa5, 0xef, 0x2a, 0x97, 0x5c, 0x4a, 0x69, 0x59, 0x29,
0xf2, 0x52, 0x98, 0xa3, 0x8c, 0xb5, 0xe2, 0xd3, 0xaf, 0xf1, 0xd9, 0x83, 0x7e, 0x92, 0xd2, 0x05,
0xfa, 0x03, 0x2d, 0x83, 0x32, 0x24, 0x4b, 0x59, 0x3e, 0x9e, 0xd3, 0x18, 0xfd, 0xa1, 0xfa, 0x52,
0x39, 0x82, 0x1f, 0x16, 0x70, 0x84, 0xdf, 0x4b, 0xe4, 0x82, 0x1c, 0x57, 0xb4, 0xa5, 0x56, 0xa3,
0xe9, 0xfd, 0xce, 0x92, 0x55, 0x8a, 0xbc, 0x85, 0x21, 0xd3, 0x84, 0x95, 0x8e, 0xa3, 0xe9, 0x93,
0xab, 0x9b, 0x1a, 0xba, 0x44, 0x36, 0x3e, 0xd8, 0x85, 0xff, 0x2d, 0x00, 0x9e, 0xb3, 0x8c, 0x63,
0xc0, 0x61, 0x14, 0x21, 0x9d, 0xd7, 0x14, 0xac, 0x03, 0x5a, 0x5f, 0x87, 0x56, 0x43, 0x5a, 0x75,
0xdc, 0x66, 0xb5, 0x2b, 0x1d, 0xbc, 0xb6, 0x0e, 0xa7, 0xfa, 0x50, 0xab, 0xc2, 0xeb, 0x8a, 0x90,
0x56, 0xe1, 0xd1, 0x55, 0x42, 0x35, 0x90, 0x15, 0x9d, 0x19, 0xfc, 0xa7, 0xf3, 0x68, 0x32, 0xe4,
0x15, 0x6c, 0x1b, 0xb8, 0x5c, 0x35, 0xc0, 0x46, 0x3d, 0x57, 0xa1, 0xc1, 0x21, 0x8c, 0x3f, 0xe0,
0x05, 0x56, 0x7d, 0xd4, 0x40, 0xef, 0xac, 0xa9, 0xa2, 0x0e, 0xbf, 0xf3, 0x2a, 0x36, 0x50, 0x35,
0xaa, 0x68, 0x01, 0x98, 0x2a, 0x1e, 0xc2, 0xf8, 0x4b, 0x3e, 0xa7, 0x37, 0x60, 0xa0, 0xc3, 0xef,
0x9c, 0x41, 0x03, 0x55, 0x83, 0x81, 0x05, 0x60, 0x18, 0xbc, 0x80, 0xd1, 0x59, 0xc2, 0xc5, 0xf5,
0xf0, 0x9f, 0xea, 0xe0, 0x9b, 0xf4, 0x4f, 0x2d, 0x79, 0xa3, 0x7f, 0x74, 0x9e, 0xdb, 0xf5, 0x8f,
0xc4, 0xce, 0x16, 0xfc, 0x7a, 0xd8, 0x7f, 0x39, 0x3a, 0xda, 0x82, 0xef, 0xbe, 0x71, 0x72, 0xd0,
0x8b, 0x02, 0x69, 0xaa, 0xe4, 0xdd, 0x8e, 0x8c, 0x25, 0x27, 0x4f, 0xcc, 0xca, 0x4c, 0xa8, 0x0b,
0xe7, 0x46, 0xda, 0x90, 0x5e, 0x9e, 0x64, 0xe6, 0xb6, 0xb9, 0x91, 0x36, 0xea, 0xd2, 0xf4, 0x3b,
0xa5, 0xa9, 0xb0, 0x57, 0xd2, 0xfc, 0x71, 0x60, 0xe7, 0x8c, 0x2d, 0x22, 0x8c, 0x59, 0x31, 0x6f,
0x0e, 0x6f, 0xa7, 0x3d, 0xbc, 0x67, 0xb5, 0x97, 0xa7, 0xa7, 0x64, 0x7b, 0xbe, 0xf6, 0x14, 0x9d,
0xac, 0xeb, 0xed, 0x91, 0x4a, 0xa4, 0xc8, 0xb9, 0x9c, 0xa9, 0xe6, 0x0d, 0x30, 0xe6, 0xad, 0x5e,
0xa5, 0xe9, 0x4f, 0x17, 0x86, 0x91, 0x06, 0x41, 0xce, 0x61, 0xa0, 0xe7, 0x1f, 0xe9, 0x9c, 0x99,
0xa6, 0x2e, 0xfb, 0x93, 0xee, 0x00, 0xd3, 0xb2, 0x5b, 0xe4, 0x23, 0x78, 0x72, 0xfe, 0x90, 0x8e,
0x79, 0x65, 0x53, 0x3d, 0xee, 0xfa, 0xbc, 0x4a, 0x74, 0x0e, 0x03, 0x7d, 0xa3, 0x49, 0xe7, 0x14,
0xd8, 0x80, 0xab, 0x35, 0x0c, 0x54, 0x3a, 0x7d, 0xbd, 0x48, 0xe7, 0x95, 0xdc, 0x90, 0xae, 0x75,
0x33, 0xb7, 0xc8, 0x29, 0x78, 0xb2, 0x47, 0x48, 0x47, 0xef, 0xd8, 0x54, 0x0f, 0x36, 0x14, 0x3d,
0xd8, 0x7a, 0xe9, 0x7c, 0x1d, 0xa8, 0x9f, 0xa1, 0xe3, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x8e,
0x6c, 0x03, 0x59, 0x33, 0x09, 0x00, 0x00,
// 683 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0xcb, 0x6e, 0xd3, 0x40,
0x14, 0xad, 0xe3, 0x3c, 0xda, 0x1b, 0x42, 0xab, 0x51, 0x85, 0x4c, 0x79, 0x45, 0x66, 0x41, 0xd9,
0x38, 0x28, 0x15, 0xe2, 0xb5, 0x2c, 0x09, 0x9b, 0x46, 0x48, 0x46, 0xfd, 0x80, 0xc1, 0xb9, 0x8a,
0x2c, 0x6a, 0x8f, 0xf1, 0x8c, 0x23, 0x65, 0xc5, 0x92, 0x35, 0xff, 0xc0, 0xbf, 0xb0, 0xe6, 0x8f,
0xd0, 0xbc, 0xfc, 0x48, 0xeb, 0x48, 0xa8, 0xea, 0x6e, 0xce, 0xf5, 0xcc, 0x9d, 0x73, 0xce, 0x9d,
0x7b, 0x65, 0x78, 0x9e, 0x17, 0xa9, 0x88, 0x13, 0x9c, 0x70, 0xcc, 0xd7, 0x71, 0x84, 0x93, 0x2c,
0x67, 0x82, 0x4d, 0x4c, 0x34, 0x50, 0x88, 0x1c, 0xad, 0x58, 0x90, 0xc4, 0x51, 0xce, 0x02, 0x13,
0xf7, 0xff, 0x3a, 0x30, 0xf8, 0xa2, 0x4f, 0x10, 0x02, 0xdd, 0x94, 0x26, 0xe8, 0x39, 0x63, 0xe7,
0xf4, 0x20, 0x54, 0x6b, 0xe2, 0xc1, 0x60, 0x8d, 0x39, 0x8f, 0x59, 0xea, 0x75, 0x54, 0xd8, 0x42,
0xf2, 0x00, 0xfa, 0x9c, 0x15, 0x79, 0x84, 0x9e, 0xab, 0x3e, 0x18, 0x44, 0xce, 0x61, 0x3f, 0x41,
0x41, 0x97, 0x54, 0x50, 0xaf, 0x3b, 0x76, 0x4f, 0x87, 0xd3, 0x17, 0xc1, 0xf6, 0xb5, 0x81, 0xb9,
0x32, 0x58, 0x98, 0x9d, 0xb3, 0x54, 0xe4, 0x9b, 0xb0, 0x3c, 0x78, 0xf2, 0x01, 0x46, 0x8d, 0x4f,
0xe4, 0x08, 0xdc, 0x6f, 0xb8, 0x31, 0xd4, 0xe4, 0x92, 0x1c, 0x43, 0x6f, 0x4d, 0xaf, 0x0a, 0x34,
0xbc, 0x34, 0x78, 0xdf, 0x79, 0xeb, 0xf8, 0x09, 0xf4, 0x66, 0x6b, 0x4c, 0x85, 0x14, 0x24, 0x36,
0x59, 0x29, 0x48, 0xae, 0xc9, 0x63, 0x38, 0x90, 0x0c, 0xb8, 0xa0, 0x49, 0xa6, 0x8e, 0xba, 0x61,
0x15, 0x90, 0x72, 0x8d, 0x7f, 0x46, 0x95, 0x85, 0x75, 0x23, 0xba, 0x0d, 0x23, 0xfc, 0x5f, 0x0e,
0x8c, 0xce, 0x73, 0xa4, 0x02, 0x3f, 0x67, 0x22, 0x66, 0x29, 0x97, 0x7b, 0x23, 0x96, 0x24, 0x34,
0x5d, 0x7a, 0xce, 0xd8, 0x95, 0x7b, 0x0d, 0x94, 0x8c, 0x68, 0xbe, 0xe2, 0x5e, 0x47, 0x85, 0xd5,
0x5a, 0x4a, 0xc3, 0x74, 0xed, 0xb9, 0x2a, 0x24, 0x97, 0xd2, 0x5a, 0x56, 0x88, 0xac, 0x10, 0xe6,
0x2a, 0x83, 0x4a, 0x3d, 0xbd, 0x9a, 0x9e, 0x63, 0xe8, 0xc5, 0x09, 0x5d, 0xa1, 0xd7, 0xd7, 0x36,
0x28, 0xe0, 0xff, 0xb0, 0x94, 0x42, 0xfc, 0x5e, 0x20, 0x17, 0xe4, 0xac, 0x12, 0x26, 0xdd, 0x18,
0x4e, 0x1f, 0xb6, 0x16, 0xa5, 0xd2, 0xfc, 0x0e, 0x06, 0x4c, 0x4b, 0x52, 0x4e, 0x0d, 0xa7, 0xcf,
0xae, 0x1f, 0x6a, 0x28, 0x0f, 0xed, 0x7e, 0xff, 0x08, 0xee, 0x5b, 0x02, 0x3c, 0x63, 0x29, 0x47,
0xff, 0x12, 0x86, 0x21, 0xd2, 0x65, 0xcd, 0xa3, 0x3a, 0xa1, 0x9b, 0x9d, 0xde, 0x7a, 0x72, 0x56,
0xbf, 0x5b, 0xe9, 0xf7, 0xe7, 0x3a, 0xad, 0xd5, 0xf9, 0xa6, 0xa2, 0xac, 0x75, 0x3e, 0xb9, 0x4e,
0xb9, 0x46, 0xa3, 0x22, 0x3c, 0x83, 0x7b, 0x3a, 0x8f, 0xa6, 0x4b, 0x5e, 0xc3, 0xbe, 0x21, 0xc4,
0x55, 0x11, 0x77, 0x3a, 0x56, 0x6e, 0xf5, 0x0f, 0x61, 0xf4, 0x11, 0xaf, 0xb0, 0x74, 0x44, 0x56,
0x42, 0x07, 0xee, 0xbc, 0x12, 0x8d, 0x7b, 0x1b, 0x95, 0xb0, 0x04, 0x4c, 0x25, 0x0e, 0x61, 0x74,
0x99, 0x2d, 0x69, 0x83, 0xa3, 0x0e, 0xdc, 0x39, 0xc7, 0xc6, 0xbd, 0x0d, 0x8e, 0x96, 0x80, 0xe1,
0x38, 0x82, 0xe1, 0x45, 0xcc, 0x85, 0x65, 0x38, 0xd7, 0xf0, 0x7f, 0xaa, 0x5c, 0x3b, 0xde, 0xa8,
0xb2, 0xce, 0x73, 0xbb, 0x2a, 0x4b, 0x76, 0x6c, 0xc5, 0x2d, 0xbb, 0xdf, 0x8e, 0xc6, 0x96, 0x5e,
0xfb, 0xdb, 0x96, 0x43, 0x53, 0xe4, 0x48, 0x13, 0x65, 0xd1, 0x7e, 0x68, 0x90, 0xec, 0xe2, 0x88,
0x15, 0xa9, 0x50, 0x4f, 0xdb, 0x0d, 0x35, 0x90, 0x51, 0x1e, 0xa7, 0x11, 0xaa, 0x31, 0xe0, 0x86,
0x1a, 0xd4, 0xc5, 0xf7, 0x5a, 0xc5, 0x57, 0xec, 0x2a, 0xf1, 0x7f, 0x1c, 0x38, 0xb8, 0x60, 0xab,
0x10, 0x23, 0x96, 0x2f, 0x9b, 0x83, 0xd0, 0xd9, 0x1e, 0x84, 0xb3, 0xda, 0x14, 0xef, 0x28, 0x63,
0x5e, 0xde, 0x78, 0x8b, 0x4e, 0xd6, 0x36, 0xc7, 0xa5, 0x13, 0x09, 0x72, 0x2e, 0xe7, 0x93, 0x99,
0xa7, 0x06, 0xde, 0x6a, 0xc2, 0x4f, 0x7f, 0xba, 0x30, 0x08, 0x35, 0x09, 0xb2, 0x80, 0xbe, 0x9e,
0x34, 0xa4, 0x75, 0x3a, 0x99, 0xba, 0x9c, 0x8c, 0xdb, 0x37, 0x98, 0x67, 0xb7, 0x47, 0x3e, 0x41,
0x57, 0xce, 0x01, 0xd2, 0x32, 0x37, 0x6c, 0xaa, 0xa7, 0x6d, 0x9f, 0xcb, 0x44, 0x0b, 0xe8, 0xeb,
0xbe, 0x23, 0xad, 0xbd, 0xba, 0x83, 0xd7, 0x56, 0xcb, 0xaa, 0x74, 0xba, 0x45, 0x48, 0x6b, 0x5b,
0xed, 0x48, 0xb7, 0xd5, 0x5d, 0x7b, 0x64, 0x0e, 0x5d, 0xf9, 0x46, 0x48, 0xcb, 0xdb, 0xb1, 0xa9,
0x1e, 0xed, 0x28, 0xba, 0xbf, 0xf7, 0xca, 0xf9, 0xda, 0x57, 0x3f, 0x16, 0x67, 0xff, 0x02, 0x00,
0x00, 0xff, 0xff, 0xe1, 0x5b, 0x52, 0x93, 0x7f, 0x08, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.

View File

@ -41,8 +41,6 @@ message CreateOptions {
string type = 5;
// image to use
string image = 6;
// namespace to use
string namespace = 7;
}
message CreateRequest {
@ -59,8 +57,6 @@ message ReadOptions {
string version = 2;
// type of service
string type = 3;
// namespace of service
string namespace = 4;
}
message ReadRequest {
@ -72,8 +68,6 @@ message ReadResponse {
}
message DeleteOptions {
// namespace of the service
string namespace = 1;
}
message DeleteRequest {
@ -84,8 +78,6 @@ message DeleteRequest {
message DeleteResponse {}
message UpdateOptions {
// namespace of the service
string namespace = 1;
}
message UpdateRequest {
@ -96,8 +88,6 @@ message UpdateRequest {
message UpdateResponse {}
message ListOptions {
// namespace to list from
string namespace = 1;
}
message ListRequest {
@ -109,8 +99,6 @@ message ListResponse {
}
message LogsOptions {
// namespace of the service
string namespace = 1;
}
message LogsRequest{

View File

@ -54,12 +54,11 @@ func (s *svc) Create(svc *runtime.Service, opts ...runtime.CreateOption) error {
Metadata: svc.Metadata,
},
Options: &pb.CreateOptions{
Command: options.Command,
Args: options.Args,
Env: options.Env,
Type: options.Type,
Image: options.Image,
Namespace: options.Namespace,
Command: options.Command,
Args: options.Args,
Env: options.Env,
Type: options.Type,
Image: options.Image,
},
}
@ -84,9 +83,6 @@ func (s *svc) Logs(service *runtime.Service, opts ...runtime.LogsOption) (runtim
Service: service.Name,
Stream: options.Stream,
Count: options.Count,
Options: &pb.LogsOptions{
Namespace: options.Namespace,
},
})
if err != nil {
return nil, err
@ -176,10 +172,9 @@ func (s *svc) Read(opts ...runtime.ReadOption) ([]*runtime.Service, error) {
// runtime service create request
req := &pb.ReadRequest{
Options: &pb.ReadOptions{
Service: options.Service,
Version: options.Version,
Type: options.Type,
Namespace: options.Namespace,
Service: options.Service,
Version: options.Version,
Type: options.Type,
},
}
@ -220,9 +215,6 @@ func (s *svc) Update(svc *runtime.Service, opts ...runtime.UpdateOption) error {
Source: svc.Source,
Metadata: svc.Metadata,
},
Options: &pb.UpdateOptions{
Namespace: options.Namespace,
},
}
if _, err := s.runtime.Update(options.Context, req); err != nil {
@ -250,9 +242,6 @@ func (s *svc) Delete(svc *runtime.Service, opts ...runtime.DeleteOption) error {
Source: svc.Source,
Metadata: svc.Metadata,
},
Options: &pb.DeleteOptions{
Namespace: options.Namespace,
},
}
if _, err := s.runtime.Delete(options.Context, req); err != nil {

View File

@ -18,17 +18,17 @@ func Generate(id string, name string, a auth.Auth) error {
// if no credentials were provided, generate an account
if len(accID) == 0 || len(accSecret) == 0 {
name := fmt.Sprintf("%v-%v", name, id)
opts := []auth.GenerateOption{
auth.WithType("service"),
auth.WithRoles("service"),
auth.WithNamespace(a.Options().Namespace),
auth.WithScopes("service"),
}
acc, err := a.Generate(name, opts...)
if err != nil {
return err
}
logger.Infof("Auth [%v] Authenticated as %v in the %v namespace", a, name, acc.Namespace)
logger.Infof("Auth [%v] Authenticated as %v issued by %v", a, name, acc.Issuer)
accID = acc.ID
accSecret = acc.Secret

View File

@ -4,7 +4,6 @@ import (
"context"
"reflect"
"strings"
"time"
"github.com/micro/go-micro/v2/auth"
"github.com/micro/go-micro/v2/client"
@ -157,9 +156,14 @@ func (a *authWrapper) Call(ctx context.Context, req client.Request, rsp interfac
return a.Client.Call(ctx, req, rsp, opts...)
}
// set the namespace header if it has not been set (e.g. on a service to service request)
if _, ok := metadata.Get(ctx, "Micro-Namespace"); !ok {
ctx = metadata.Set(ctx, "Micro-Namespace", aa.Options().Namespace)
}
// check to see if we have a valid access token
aaOpts := aa.Options()
if aaOpts.Token != nil && aaOpts.Token.Expiry.Unix() > time.Now().Unix() {
if aaOpts.Token != nil && !aaOpts.Token.Expired() {
ctx = metadata.Set(ctx, "Authorization", auth.BearerScheme+aaOpts.Token.AccessToken)
return a.Client.Call(ctx, req, rsp, opts...)
}
@ -187,20 +191,28 @@ func AuthHandler(fn func() auth.Auth) server.HandlerWrapper {
// Extract the token if present. Note: if noop is being used
// then the token can be blank without erroring
var token string
var account *auth.Account
if header, ok := metadata.Get(ctx, "Authorization"); ok {
// Ensure the correct scheme is being used
if !strings.HasPrefix(header, auth.BearerScheme) {
return errors.Unauthorized(req.Service(), "invalid authorization header. expected Bearer schema")
}
token = header[len(auth.BearerScheme):]
// Strip the prefix and inspect the resulting token
account, _ = a.Inspect(strings.TrimPrefix(header, auth.BearerScheme))
}
// Inspect the token and get the account
account, err := a.Inspect(token)
if err != nil {
account = &auth.Account{Namespace: a.Options().Namespace}
// Extract the namespace header
ns, ok := metadata.Get(ctx, "Micro-Namespace")
if !ok {
ns = a.Options().Namespace
ctx = metadata.Set(ctx, "Micro-Namespace", ns)
}
// Check the issuer matches the services namespace. TODO: Stop allowing go.micro to access
// any namespace and instead check for the server issuer.
if account != nil && account.Issuer != ns && account.Issuer != "go.micro" {
return errors.Forbidden(req.Service(), "Account was not issued by %v", ns)
}
// construct the resource
@ -211,15 +223,15 @@ func AuthHandler(fn func() auth.Auth) server.HandlerWrapper {
}
// Verify the caller has access to the resource
err = a.Verify(account, res)
if err != nil && len(account.ID) > 0 {
err := a.Verify(account, res, auth.VerifyContext(ctx))
if err != nil && account != nil {
return errors.Forbidden(req.Service(), "Forbidden call made to %v:%v by %v", req.Service(), req.Endpoint(), account.ID)
} else if err != nil {
return errors.Unauthorized(req.Service(), "Unauthorised call made to %v:%v", req.Service(), req.Endpoint())
}
// There is an account, set it in the context
if len(account.ID) > 0 {
if account != nil {
ctx = auth.ContextWithAccount(ctx, account)
}

View File

@ -2,12 +2,16 @@ package wrapper
import (
"context"
"net/http"
"reflect"
"testing"
"time"
"github.com/micro/go-micro/v2/auth"
"github.com/micro/go-micro/v2/client"
"github.com/micro/go-micro/v2/errors"
"github.com/micro/go-micro/v2/metadata"
"github.com/micro/go-micro/v2/server"
)
func TestWrapper(t *testing.T) {
@ -54,6 +58,313 @@ func TestWrapper(t *testing.T) {
}
}
type testAuth struct {
verifyCount int
inspectCount int
namespace string
inspectAccount *auth.Account
verifyError error
auth.Auth
}
func (a *testAuth) Verify(acc *auth.Account, res *auth.Resource, opts ...auth.VerifyOption) error {
a.verifyCount = a.verifyCount + 1
return a.verifyError
}
func (a *testAuth) Inspect(token string) (*auth.Account, error) {
a.inspectCount = a.inspectCount + 1
return a.inspectAccount, nil
}
func (a *testAuth) Options() auth.Options {
return auth.Options{Namespace: a.namespace}
}
type testRequest struct {
service string
endpoint string
server.Request
}
func (r testRequest) Service() string {
return r.service
}
func (r testRequest) Endpoint() string {
return r.endpoint
}
func TestAuthHandler(t *testing.T) {
h := func(ctx context.Context, req server.Request, rsp interface{}) error {
return nil
}
debugReq := testRequest{service: "go.micro.service.foo", endpoint: "Debug.Foo"}
serviceReq := testRequest{service: "go.micro.service.foo", endpoint: "Foo.Bar"}
// Debug endpoints should be excluded from auth so auth.Verify should never get called
t.Run("DebugEndpoint", func(t *testing.T) {
a := testAuth{}
handler := AuthHandler(func() auth.Auth {
return &a
})
err := handler(h)(context.TODO(), debugReq, nil)
if err != nil {
t.Errorf("Expected nil error but got %v", err)
}
if a.verifyCount != 0 {
t.Errorf("Did not expect verify to be called")
}
})
// If the Authorization header is blank, no error should be returned and verify not called
t.Run("BlankAuthorizationHeader", func(t *testing.T) {
a := testAuth{}
handler := AuthHandler(func() auth.Auth {
return &a
})
err := handler(h)(context.TODO(), serviceReq, nil)
if err != nil {
t.Errorf("Expected nil error but got %v", err)
}
if a.inspectCount != 0 {
t.Errorf("Did not expect inspect to be called")
}
})
// If the Authorization header is invalid, an error should be returned and verify not called
t.Run("InvalidAuthorizationHeader", func(t *testing.T) {
a := testAuth{}
handler := AuthHandler(func() auth.Auth {
return &a
})
ctx := metadata.Set(context.TODO(), "Authorization", "Invalid")
err := handler(h)(ctx, serviceReq, nil)
if verr, ok := err.(*errors.Error); !ok || verr.Code != http.StatusUnauthorized {
t.Errorf("Expected unauthorized error but got %v", err)
}
if a.inspectCount != 0 {
t.Errorf("Did not expect inspect to be called")
}
})
// If the Authorization header is valid, no error should be returned and verify should called
t.Run("ValidAuthorizationHeader", func(t *testing.T) {
a := testAuth{}
handler := AuthHandler(func() auth.Auth {
return &a
})
ctx := metadata.Set(context.TODO(), "Authorization", auth.BearerScheme+"Token")
err := handler(h)(ctx, serviceReq, nil)
if err != nil {
t.Errorf("Expected nil error but got %v", err)
}
if a.inspectCount != 1 {
t.Errorf("Expected inspect to be called")
}
})
// If the namespace header was not set on the request, the wrapper should set it to the auths
// own namespace
t.Run("BlankNamespaceHeader", func(t *testing.T) {
a := testAuth{namespace: "mynamespace"}
handler := AuthHandler(func() auth.Auth {
return &a
})
inCtx := context.TODO()
h := func(ctx context.Context, req server.Request, rsp interface{}) error {
inCtx = ctx
return nil
}
err := handler(h)(inCtx, serviceReq, nil)
if err != nil {
t.Errorf("Expected nil error but got %v", err)
}
if ns, _ := metadata.Get(inCtx, "Micro-Namespace"); ns != a.namespace {
t.Errorf("Expected namespace to be set to %v but was %v", a.namespace, ns)
}
})
t.Run("ValidNamespaceHeader", func(t *testing.T) {
a := testAuth{namespace: "mynamespace"}
handler := AuthHandler(func() auth.Auth {
return &a
})
inNs := "reqnamespace"
inCtx := metadata.Set(context.TODO(), "Micro-Namespace", inNs)
h := func(ctx context.Context, req server.Request, rsp interface{}) error {
inCtx = ctx
return nil
}
err := handler(h)(inCtx, serviceReq, nil)
if err != nil {
t.Errorf("Expected nil error but got %v", err)
}
if ns, _ := metadata.Get(inCtx, "Micro-Namespace"); ns != inNs {
t.Errorf("Expected namespace to remain as %v but was set to %v", inNs, ns)
}
})
// If the callers account was set but the issuer didn't match that of the request, the request
// should be forbidden
t.Run("InvalidAccountIssuer", func(t *testing.T) {
a := testAuth{
namespace: "validnamespace",
inspectAccount: &auth.Account{Issuer: "invalidnamespace"},
}
handler := AuthHandler(func() auth.Auth {
return &a
})
ctx := metadata.Set(context.TODO(), "Authorization", auth.BearerScheme+"Token")
err := handler(h)(ctx, serviceReq, nil)
if verr, ok := err.(*errors.Error); !ok || verr.Code != http.StatusForbidden {
t.Errorf("Expected forbidden error but got %v", err)
}
})
t.Run("ValidAccountIssuer", func(t *testing.T) {
a := testAuth{
namespace: "validnamespace",
inspectAccount: &auth.Account{Issuer: "validnamespace"},
}
handler := AuthHandler(func() auth.Auth {
return &a
})
ctx := metadata.Set(context.TODO(), "Authorization", auth.BearerScheme+"Token")
err := handler(h)(ctx, serviceReq, nil)
if err != nil {
t.Errorf("Expected nil error but got %v", err)
}
})
// If the caller had a nil account and verify returns an error, the request should be unauthorised
t.Run("NilAccountUnauthorized", func(t *testing.T) {
a := testAuth{verifyError: auth.ErrForbidden}
handler := AuthHandler(func() auth.Auth {
return &a
})
err := handler(h)(context.TODO(), serviceReq, nil)
if verr, ok := err.(*errors.Error); !ok || verr.Code != http.StatusUnauthorized {
t.Errorf("Expected unauthorizard error but got %v", err)
}
})
t.Run("AccountForbidden", func(t *testing.T) {
a := testAuth{verifyError: auth.ErrForbidden, inspectAccount: &auth.Account{}}
handler := AuthHandler(func() auth.Auth {
return &a
})
ctx := metadata.Set(context.TODO(), "Authorization", auth.BearerScheme+"Token")
err := handler(h)(ctx, serviceReq, nil)
if verr, ok := err.(*errors.Error); !ok || verr.Code != http.StatusForbidden {
t.Errorf("Expected forbidden error but got %v", err)
}
})
t.Run("AccountValid", func(t *testing.T) {
a := testAuth{inspectAccount: &auth.Account{}}
handler := AuthHandler(func() auth.Auth {
return &a
})
ctx := metadata.Set(context.TODO(), "Authorization", auth.BearerScheme+"Token")
err := handler(h)(ctx, serviceReq, nil)
if err != nil {
t.Errorf("Expected nil error but got %v", err)
}
})
// If an account is returned from inspecting the token, it should be set in the context
t.Run("ContextWithAccount", func(t *testing.T) {
accID := "myaccountid"
a := testAuth{inspectAccount: &auth.Account{ID: accID}}
handler := AuthHandler(func() auth.Auth {
return &a
})
inCtx := metadata.Set(context.TODO(), "Authorization", auth.BearerScheme+"Token")
h := func(ctx context.Context, req server.Request, rsp interface{}) error {
inCtx = ctx
return nil
}
err := handler(h)(inCtx, serviceReq, nil)
if err != nil {
t.Errorf("Expected nil error but got %v", err)
}
if acc, ok := auth.AccountFromContext(inCtx); !ok {
t.Errorf("Expected an account to be set in the context")
} else if acc.ID != accID {
t.Errorf("Expected the account in the context to have the ID %v but it actually had %v", accID, acc.ID)
}
})
// If verify returns an error the handler should not be called
t.Run("HandlerNotCalled", func(t *testing.T) {
a := testAuth{verifyError: auth.ErrForbidden}
handler := AuthHandler(func() auth.Auth {
return &a
})
var handlerCalled bool
h := func(ctx context.Context, req server.Request, rsp interface{}) error {
handlerCalled = true
return nil
}
ctx := metadata.Set(context.TODO(), "Authorization", auth.BearerScheme+"Token")
err := handler(h)(ctx, serviceReq, nil)
if verr, ok := err.(*errors.Error); !ok || verr.Code != http.StatusUnauthorized {
t.Errorf("Expected unauthorizard error but got %v", err)
}
if handlerCalled {
t.Errorf("Expected the handler to not be called")
}
})
// If verify does not return an error the handler should be called
t.Run("HandlerNotCalled", func(t *testing.T) {
a := testAuth{}
handler := AuthHandler(func() auth.Auth {
return &a
})
var handlerCalled bool
h := func(ctx context.Context, req server.Request, rsp interface{}) error {
handlerCalled = true
return nil
}
ctx := metadata.Set(context.TODO(), "Authorization", auth.BearerScheme+"Token")
err := handler(h)(ctx, serviceReq, nil)
if err != nil {
t.Errorf("Expected nil error but got %v", err)
}
if !handlerCalled {
t.Errorf("Expected the handler be called")
}
})
}
type testClient struct {
callCount int
callRsp interface{}

View File

@ -444,7 +444,7 @@ func (s *service) Init(opts ...Option) error {
func (s *service) Run() error {
// generate an auth account
srvID := s.opts.Service.Server().Options().Id
srvName := s.opts.Service.Name()
srvName := s.Options().Name
if err := authutil.Generate(srvID, srvName, s.opts.Service.Options().Auth); err != nil {
return err
}