Auth load rules (#1397)

* WithRoles variadic args

* Load Rules

* Timer => Ticker

Co-authored-by: Ben Toogood <ben@micro.mu>
This commit is contained in:
ben-toogood 2020-03-24 13:48:37 +00:00 committed by GitHub
parent 86272a3064
commit fd664f4392
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 312 additions and 729 deletions

View File

@ -20,6 +20,61 @@ var _ = math.Inf
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
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"`
Resource *Resource `protobuf:"bytes,3,opt,name=resource,proto3" json:"resource,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Rule) Reset() { *m = Rule{} }
func (m *Rule) String() string { return proto.CompactTextString(m) }
func (*Rule) ProtoMessage() {}
func (*Rule) Descriptor() ([]byte, []int) {
return fileDescriptor_21300bfacc51fc2a, []int{0}
}
func (m *Rule) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Rule.Unmarshal(m, b)
}
func (m *Rule) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Rule.Marshal(b, m, deterministic)
}
func (m *Rule) XXX_Merge(src proto.Message) {
xxx_messageInfo_Rule.Merge(m, src)
}
func (m *Rule) XXX_Size() int {
return xxx_messageInfo_Rule.Size(m)
}
func (m *Rule) XXX_DiscardUnknown() {
xxx_messageInfo_Rule.DiscardUnknown(m)
}
var xxx_messageInfo_Rule proto.InternalMessageInfo
func (m *Rule) GetId() string {
if m != nil {
return m.Id
}
return ""
}
func (m *Rule) GetRole() string {
if m != nil {
return m.Role
}
return ""
}
func (m *Rule) GetResource() *Resource {
if m != nil {
return m.Resource
}
return nil
}
type Token struct {
Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"`
Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"`
@ -37,7 +92,7 @@ func (m *Token) Reset() { *m = Token{} }
func (m *Token) String() string { return proto.CompactTextString(m) }
func (*Token) ProtoMessage() {}
func (*Token) Descriptor() ([]byte, []int) {
return fileDescriptor_21300bfacc51fc2a, []int{0}
return fileDescriptor_21300bfacc51fc2a, []int{1}
}
func (m *Token) XXX_Unmarshal(b []byte) error {
@ -121,7 +176,7 @@ func (m *Account) Reset() { *m = Account{} }
func (m *Account) String() string { return proto.CompactTextString(m) }
func (*Account) ProtoMessage() {}
func (*Account) Descriptor() ([]byte, []int) {
return fileDescriptor_21300bfacc51fc2a, []int{1}
return fileDescriptor_21300bfacc51fc2a, []int{2}
}
func (m *Account) XXX_Unmarshal(b []byte) error {
@ -183,7 +238,7 @@ func (m *Resource) Reset() { *m = Resource{} }
func (m *Resource) String() string { return proto.CompactTextString(m) }
func (*Resource) ProtoMessage() {}
func (*Resource) Descriptor() ([]byte, []int) {
return fileDescriptor_21300bfacc51fc2a, []int{2}
return fileDescriptor_21300bfacc51fc2a, []int{3}
}
func (m *Resource) XXX_Unmarshal(b []byte) error {
@ -239,7 +294,7 @@ func (m *GenerateRequest) Reset() { *m = GenerateRequest{} }
func (m *GenerateRequest) String() string { return proto.CompactTextString(m) }
func (*GenerateRequest) ProtoMessage() {}
func (*GenerateRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_21300bfacc51fc2a, []int{3}
return fileDescriptor_21300bfacc51fc2a, []int{4}
}
func (m *GenerateRequest) XXX_Unmarshal(b []byte) error {
@ -299,7 +354,7 @@ func (m *GenerateResponse) Reset() { *m = GenerateResponse{} }
func (m *GenerateResponse) String() string { return proto.CompactTextString(m) }
func (*GenerateResponse) ProtoMessage() {}
func (*GenerateResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_21300bfacc51fc2a, []int{4}
return fileDescriptor_21300bfacc51fc2a, []int{5}
}
func (m *GenerateResponse) XXX_Unmarshal(b []byte) error {
@ -339,7 +394,7 @@ func (m *GrantRequest) Reset() { *m = GrantRequest{} }
func (m *GrantRequest) String() string { return proto.CompactTextString(m) }
func (*GrantRequest) ProtoMessage() {}
func (*GrantRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_21300bfacc51fc2a, []int{5}
return fileDescriptor_21300bfacc51fc2a, []int{6}
}
func (m *GrantRequest) XXX_Unmarshal(b []byte) error {
@ -384,7 +439,7 @@ func (m *GrantResponse) Reset() { *m = GrantResponse{} }
func (m *GrantResponse) String() string { return proto.CompactTextString(m) }
func (*GrantResponse) ProtoMessage() {}
func (*GrantResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_21300bfacc51fc2a, []int{6}
return fileDescriptor_21300bfacc51fc2a, []int{7}
}
func (m *GrantResponse) XXX_Unmarshal(b []byte) error {
@ -405,84 +460,6 @@ func (m *GrantResponse) XXX_DiscardUnknown() {
var xxx_messageInfo_GrantResponse proto.InternalMessageInfo
type VerifyRequest struct {
Account *Account `protobuf:"bytes,1,opt,name=account,proto3" json:"account,omitempty"`
Resource *Resource `protobuf:"bytes,2,opt,name=resource,proto3" json:"resource,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *VerifyRequest) Reset() { *m = VerifyRequest{} }
func (m *VerifyRequest) String() string { return proto.CompactTextString(m) }
func (*VerifyRequest) ProtoMessage() {}
func (*VerifyRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_21300bfacc51fc2a, []int{7}
}
func (m *VerifyRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_VerifyRequest.Unmarshal(m, b)
}
func (m *VerifyRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_VerifyRequest.Marshal(b, m, deterministic)
}
func (m *VerifyRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_VerifyRequest.Merge(m, src)
}
func (m *VerifyRequest) XXX_Size() int {
return xxx_messageInfo_VerifyRequest.Size(m)
}
func (m *VerifyRequest) XXX_DiscardUnknown() {
xxx_messageInfo_VerifyRequest.DiscardUnknown(m)
}
var xxx_messageInfo_VerifyRequest proto.InternalMessageInfo
func (m *VerifyRequest) GetAccount() *Account {
if m != nil {
return m.Account
}
return nil
}
func (m *VerifyRequest) GetResource() *Resource {
if m != nil {
return m.Resource
}
return nil
}
type VerifyResponse struct {
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *VerifyResponse) Reset() { *m = VerifyResponse{} }
func (m *VerifyResponse) String() string { return proto.CompactTextString(m) }
func (*VerifyResponse) ProtoMessage() {}
func (*VerifyResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_21300bfacc51fc2a, []int{8}
}
func (m *VerifyResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_VerifyResponse.Unmarshal(m, b)
}
func (m *VerifyResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_VerifyResponse.Marshal(b, m, deterministic)
}
func (m *VerifyResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_VerifyResponse.Merge(m, src)
}
func (m *VerifyResponse) XXX_Size() int {
return xxx_messageInfo_VerifyResponse.Size(m)
}
func (m *VerifyResponse) XXX_DiscardUnknown() {
xxx_messageInfo_VerifyResponse.DiscardUnknown(m)
}
var xxx_messageInfo_VerifyResponse proto.InternalMessageInfo
type RevokeRequest 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"`
@ -495,7 +472,7 @@ func (m *RevokeRequest) Reset() { *m = RevokeRequest{} }
func (m *RevokeRequest) String() string { return proto.CompactTextString(m) }
func (*RevokeRequest) ProtoMessage() {}
func (*RevokeRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_21300bfacc51fc2a, []int{9}
return fileDescriptor_21300bfacc51fc2a, []int{8}
}
func (m *RevokeRequest) XXX_Unmarshal(b []byte) error {
@ -540,7 +517,7 @@ func (m *RevokeResponse) Reset() { *m = RevokeResponse{} }
func (m *RevokeResponse) String() string { return proto.CompactTextString(m) }
func (*RevokeResponse) ProtoMessage() {}
func (*RevokeResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_21300bfacc51fc2a, []int{10}
return fileDescriptor_21300bfacc51fc2a, []int{9}
}
func (m *RevokeResponse) XXX_Unmarshal(b []byte) error {
@ -572,7 +549,7 @@ func (m *InspectRequest) Reset() { *m = InspectRequest{} }
func (m *InspectRequest) String() string { return proto.CompactTextString(m) }
func (*InspectRequest) ProtoMessage() {}
func (*InspectRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_21300bfacc51fc2a, []int{11}
return fileDescriptor_21300bfacc51fc2a, []int{10}
}
func (m *InspectRequest) XXX_Unmarshal(b []byte) error {
@ -611,7 +588,7 @@ func (m *InspectResponse) Reset() { *m = InspectResponse{} }
func (m *InspectResponse) String() string { return proto.CompactTextString(m) }
func (*InspectResponse) ProtoMessage() {}
func (*InspectResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_21300bfacc51fc2a, []int{12}
return fileDescriptor_21300bfacc51fc2a, []int{11}
}
func (m *InspectResponse) XXX_Unmarshal(b []byte) error {
@ -651,7 +628,7 @@ func (m *RefreshRequest) Reset() { *m = RefreshRequest{} }
func (m *RefreshRequest) String() string { return proto.CompactTextString(m) }
func (*RefreshRequest) ProtoMessage() {}
func (*RefreshRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_21300bfacc51fc2a, []int{13}
return fileDescriptor_21300bfacc51fc2a, []int{12}
}
func (m *RefreshRequest) XXX_Unmarshal(b []byte) error {
@ -697,7 +674,7 @@ func (m *RefreshResponse) Reset() { *m = RefreshResponse{} }
func (m *RefreshResponse) String() string { return proto.CompactTextString(m) }
func (*RefreshResponse) ProtoMessage() {}
func (*RefreshResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_21300bfacc51fc2a, []int{14}
return fileDescriptor_21300bfacc51fc2a, []int{13}
}
func (m *RefreshResponse) XXX_Unmarshal(b []byte) error {
@ -725,7 +702,78 @@ func (m *RefreshResponse) GetToken() *Token {
return nil
}
type ListRulesRequest struct {
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *ListRulesRequest) Reset() { *m = ListRulesRequest{} }
func (m *ListRulesRequest) String() string { return proto.CompactTextString(m) }
func (*ListRulesRequest) ProtoMessage() {}
func (*ListRulesRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_21300bfacc51fc2a, []int{14}
}
func (m *ListRulesRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ListRulesRequest.Unmarshal(m, b)
}
func (m *ListRulesRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ListRulesRequest.Marshal(b, m, deterministic)
}
func (m *ListRulesRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_ListRulesRequest.Merge(m, src)
}
func (m *ListRulesRequest) XXX_Size() int {
return xxx_messageInfo_ListRulesRequest.Size(m)
}
func (m *ListRulesRequest) XXX_DiscardUnknown() {
xxx_messageInfo_ListRulesRequest.DiscardUnknown(m)
}
var xxx_messageInfo_ListRulesRequest proto.InternalMessageInfo
type ListRulesResponse struct {
Rules []*Rule `protobuf:"bytes,1,rep,name=rules,proto3" json:"rules,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *ListRulesResponse) Reset() { *m = ListRulesResponse{} }
func (m *ListRulesResponse) String() string { return proto.CompactTextString(m) }
func (*ListRulesResponse) ProtoMessage() {}
func (*ListRulesResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_21300bfacc51fc2a, []int{15}
}
func (m *ListRulesResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ListRulesResponse.Unmarshal(m, b)
}
func (m *ListRulesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ListRulesResponse.Marshal(b, m, deterministic)
}
func (m *ListRulesResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_ListRulesResponse.Merge(m, src)
}
func (m *ListRulesResponse) XXX_Size() int {
return xxx_messageInfo_ListRulesResponse.Size(m)
}
func (m *ListRulesResponse) XXX_DiscardUnknown() {
xxx_messageInfo_ListRulesResponse.DiscardUnknown(m)
}
var xxx_messageInfo_ListRulesResponse proto.InternalMessageInfo
func (m *ListRulesResponse) GetRules() []*Rule {
if m != nil {
return m.Rules
}
return nil
}
func init() {
proto.RegisterType((*Rule)(nil), "go.micro.auth.Rule")
proto.RegisterType((*Token)(nil), "go.micro.auth.Token")
proto.RegisterMapType((map[string]string)(nil), "go.micro.auth.Token.MetadataEntry")
proto.RegisterType((*Account)(nil), "go.micro.auth.Account")
@ -736,60 +784,62 @@ func init() {
proto.RegisterType((*GenerateResponse)(nil), "go.micro.auth.GenerateResponse")
proto.RegisterType((*GrantRequest)(nil), "go.micro.auth.GrantRequest")
proto.RegisterType((*GrantResponse)(nil), "go.micro.auth.GrantResponse")
proto.RegisterType((*VerifyRequest)(nil), "go.micro.auth.VerifyRequest")
proto.RegisterType((*VerifyResponse)(nil), "go.micro.auth.VerifyResponse")
proto.RegisterType((*RevokeRequest)(nil), "go.micro.auth.RevokeRequest")
proto.RegisterType((*RevokeResponse)(nil), "go.micro.auth.RevokeResponse")
proto.RegisterType((*InspectRequest)(nil), "go.micro.auth.InspectRequest")
proto.RegisterType((*InspectResponse)(nil), "go.micro.auth.InspectResponse")
proto.RegisterType((*RefreshRequest)(nil), "go.micro.auth.RefreshRequest")
proto.RegisterType((*RefreshResponse)(nil), "go.micro.auth.RefreshResponse")
proto.RegisterType((*ListRulesRequest)(nil), "go.micro.auth.ListRulesRequest")
proto.RegisterType((*ListRulesResponse)(nil), "go.micro.auth.ListRulesResponse")
}
func init() { proto.RegisterFile("auth/service/proto/auth.proto", fileDescriptor_21300bfacc51fc2a) }
var fileDescriptor_21300bfacc51fc2a = []byte{
// 663 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x55, 0xdd, 0x6e, 0xd3, 0x4c,
0x10, 0xad, 0xed, 0xfc, 0x75, 0x52, 0x27, 0xd1, 0xaa, 0xea, 0x67, 0xf9, 0xa3, 0x25, 0x18, 0x84,
0x2a, 0x54, 0xb9, 0x28, 0xbd, 0x41, 0x20, 0x10, 0x15, 0xad, 0xca, 0x8f, 0xca, 0x85, 0x85, 0x80,
0x3b, 0xe4, 0x3a, 0x53, 0x6a, 0xd2, 0xd8, 0x66, 0xbd, 0x8e, 0xc8, 0x5b, 0xf0, 0x52, 0xbc, 0x05,
0x77, 0xbc, 0x08, 0xda, 0xf5, 0xae, 0x6b, 0x3b, 0x09, 0x12, 0x05, 0xee, 0x76, 0x76, 0x66, 0xcf,
0x99, 0x39, 0x73, 0xe2, 0xc0, 0xb6, 0x9f, 0xb1, 0x8b, 0xfd, 0x14, 0xe9, 0x2c, 0x0c, 0x70, 0x3f,
0xa1, 0x31, 0x8b, 0xf7, 0xf9, 0x95, 0x2b, 0x8e, 0xc4, 0xfc, 0x18, 0xbb, 0xd3, 0x30, 0xa0, 0xb1,
0xcb, 0x2f, 0x9d, 0xaf, 0x3a, 0x34, 0xdf, 0xc4, 0x13, 0x8c, 0xc8, 0x26, 0x34, 0x19, 0x3f, 0x58,
0xda, 0x50, 0xdb, 0x5d, 0xf7, 0xf2, 0x80, 0x10, 0x68, 0xb0, 0x79, 0x82, 0x96, 0x2e, 0x2e, 0xc5,
0x99, 0x58, 0xd0, 0x0e, 0x28, 0xfa, 0x0c, 0xc7, 0x96, 0x31, 0xd4, 0x76, 0x0d, 0x4f, 0x85, 0x64,
0x0b, 0x5a, 0xf8, 0x25, 0x09, 0xe9, 0xdc, 0x6a, 0x88, 0x84, 0x8c, 0xf8, 0x8b, 0x34, 0x3b, 0xfb,
0x84, 0x01, 0xb3, 0x9a, 0x02, 0x48, 0x85, 0x9c, 0x95, 0xc6, 0x97, 0x98, 0x5a, 0xad, 0xa1, 0xc1,
0x59, 0x45, 0x40, 0x9e, 0x40, 0x67, 0x8a, 0xcc, 0x1f, 0xfb, 0xcc, 0xb7, 0xda, 0x43, 0x63, 0xb7,
0x3b, 0x72, 0xdc, 0x4a, 0xdf, 0xae, 0xe8, 0xd9, 0x3d, 0x95, 0x45, 0xc7, 0x11, 0xa3, 0x73, 0xaf,
0x78, 0x63, 0x3f, 0x02, 0xb3, 0x92, 0x22, 0x03, 0x30, 0x26, 0x38, 0x97, 0xa3, 0xf1, 0x23, 0x27,
0x9e, 0xf9, 0x97, 0x99, 0x9a, 0x2c, 0x0f, 0x1e, 0xea, 0x0f, 0x34, 0xe7, 0xbb, 0x06, 0xed, 0xc3,
0x20, 0x88, 0xb3, 0x88, 0x91, 0x1e, 0xe8, 0xe1, 0x58, 0x3e, 0xd3, 0xc3, 0x31, 0xd9, 0x83, 0x56,
0x8a, 0x01, 0x45, 0x26, 0x9e, 0x75, 0x47, 0x9b, 0xcb, 0xda, 0xf2, 0x64, 0xcd, 0xd5, 0x70, 0x46,
0x79, 0xb8, 0xa7, 0xa5, 0xe1, 0x1a, 0x62, 0xb8, 0x3b, 0x35, 0x14, 0xc9, 0xfe, 0x6f, 0xc6, 0x7b,
0x0d, 0x1d, 0x0f, 0xd3, 0x38, 0xa3, 0x01, 0xf2, 0xed, 0x46, 0xfe, 0x14, 0xe5, 0x43, 0x71, 0x5e,
0xba, 0x71, 0x1b, 0x3a, 0x18, 0x8d, 0x93, 0x38, 0x8c, 0x98, 0x58, 0xf9, 0xba, 0x57, 0xc4, 0xce,
0x0f, 0x0d, 0xfa, 0x27, 0x18, 0x21, 0xf5, 0x19, 0x7a, 0xf8, 0x39, 0xc3, 0x74, 0x51, 0xb6, 0x42,
0x08, 0xbd, 0x2c, 0xc4, 0xf3, 0x92, 0x10, 0x86, 0x10, 0x62, 0xaf, 0x26, 0x44, 0x0d, 0x77, 0x95,
0x20, 0xe4, 0x36, 0x98, 0xb9, 0xe4, 0x1f, 0x2a, 0xf6, 0xdb, 0xc8, 0x2f, 0x8f, 0xc5, 0xdd, 0x9f,
0xa9, 0x76, 0x04, 0x83, 0xab, 0x66, 0xd2, 0x24, 0x8e, 0x52, 0x24, 0xf7, 0xa1, 0xed, 0xe7, 0x9b,
0x12, 0x18, 0xdd, 0xd1, 0xd6, 0xf2, 0x3d, 0x7a, 0xaa, 0xcc, 0x79, 0x07, 0x1b, 0x27, 0xd4, 0x8f,
0x98, 0xd2, 0x89, 0x40, 0x83, 0x4b, 0xa1, 0xf4, 0xe7, 0x67, 0x72, 0x00, 0x1d, 0x2a, 0xf7, 0x23,
0x4d, 0xf6, 0x5f, 0x0d, 0x56, 0xad, 0xcf, 0x2b, 0x0a, 0x9d, 0x3e, 0x98, 0x12, 0x38, 0xef, 0xcd,
0x99, 0x81, 0xf9, 0x16, 0x69, 0x78, 0x3e, 0x57, 0x54, 0xbf, 0xdd, 0xec, 0xf5, 0x1a, 0x19, 0x40,
0x4f, 0xf1, 0xca, 0x4e, 0xde, 0x83, 0xe9, 0xe1, 0x2c, 0x9e, 0xe0, 0x5f, 0x1f, 0x7a, 0x00, 0x3d,
0x85, 0x2c, 0xb9, 0xee, 0x42, 0xef, 0x45, 0x94, 0x26, 0x18, 0x14, 0x0a, 0x2f, 0xfd, 0xaa, 0x39,
0xcf, 0xa0, 0x5f, 0xd4, 0x5d, 0x7b, 0x99, 0xaf, 0x38, 0xfd, 0x39, 0xc5, 0xf4, 0x42, 0x91, 0x6d,
0x15, 0x5f, 0x87, 0x9c, 0x4d, 0x7d, 0x07, 0x6e, 0xc1, 0x86, 0xe0, 0x55, 0xee, 0xd4, 0x85, 0x3b,
0xbb, 0xe2, 0x2e, 0x37, 0xa7, 0xf3, 0x18, 0xfa, 0x05, 0x98, 0xec, 0xe8, 0x5e, 0xb9, 0xf5, 0x55,
0x9f, 0x9a, 0xbc, 0x64, 0xf4, 0xcd, 0x80, 0xc6, 0x61, 0xc6, 0x2e, 0xc8, 0x29, 0x74, 0x94, 0x4f,
0xc9, 0xce, 0xaf, 0x7f, 0x4d, 0xf6, 0xcd, 0x95, 0x79, 0x29, 0xe7, 0x1a, 0x39, 0x82, 0xa6, 0xf0,
0x15, 0xf9, 0xbf, 0x5e, 0x5b, 0xb2, 0xb1, 0x7d, 0x63, 0x79, 0xb2, 0x40, 0x39, 0x81, 0x56, 0x6e,
0x0a, 0x52, 0xaf, 0xac, 0x78, 0xd4, 0xde, 0x5e, 0x91, 0x2d, 0x03, 0xe5, 0x1b, 0x5f, 0x00, 0xaa,
0x58, 0x6c, 0x01, 0xa8, 0x66, 0x93, 0x35, 0xf2, 0x12, 0xda, 0xd2, 0x00, 0xa4, 0x5e, 0x5b, 0x35,
0x90, 0xbd, 0xb3, 0x2a, 0x5d, 0xc6, 0x92, 0xab, 0x23, 0x8b, 0xbc, 0x65, 0x7f, 0x2c, 0x60, 0xd5,
0x36, 0xee, 0xac, 0x9d, 0xb5, 0xc4, 0x9f, 0xf4, 0xc1, 0xcf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xb7,
0xf8, 0x55, 0xb6, 0xc5, 0x07, 0x00, 0x00,
// 696 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x55, 0xdb, 0x6e, 0xd3, 0x40,
0x10, 0xad, 0xed, 0xdc, 0x3a, 0x69, 0x9a, 0xb0, 0x54, 0xc5, 0x32, 0x6d, 0x09, 0x06, 0xa1, 0x82,
0xaa, 0x14, 0xa5, 0x2f, 0x08, 0x44, 0x45, 0x45, 0xab, 0x72, 0x2b, 0x42, 0x16, 0x12, 0xbc, 0x55,
0xae, 0x33, 0x50, 0xd3, 0xd4, 0x36, 0xeb, 0x75, 0x45, 0xfe, 0x82, 0x2f, 0xe3, 0x0b, 0x78, 0xe3,
0x47, 0xd0, 0xae, 0x77, 0xb7, 0x8e, 0x13, 0x23, 0xc4, 0xe5, 0x6d, 0x77, 0x76, 0x7c, 0xce, 0xcc,
0x99, 0x33, 0x09, 0xac, 0xfb, 0x19, 0x3b, 0xdd, 0x4e, 0x91, 0x5e, 0x84, 0x01, 0x6e, 0x27, 0x34,
0x66, 0xf1, 0x36, 0x0f, 0x0d, 0xc4, 0x91, 0x74, 0x3e, 0xc6, 0x83, 0xf3, 0x30, 0xa0, 0xf1, 0x80,
0x07, 0xdd, 0x63, 0xa8, 0x79, 0xd9, 0x18, 0xc9, 0x32, 0x98, 0xe1, 0xc8, 0x36, 0xfa, 0xc6, 0xe6,
0xa2, 0x67, 0x86, 0x23, 0x42, 0xa0, 0x46, 0xe3, 0x31, 0xda, 0xa6, 0x88, 0x88, 0x33, 0xd9, 0x81,
0x16, 0xc5, 0x34, 0xce, 0x68, 0x80, 0xb6, 0xd5, 0x37, 0x36, 0xdb, 0xc3, 0x6b, 0x83, 0x29, 0xb4,
0x81, 0x27, 0x9f, 0x3d, 0x9d, 0xe8, 0x7e, 0x35, 0xa1, 0xfe, 0x36, 0x3e, 0xc3, 0x88, 0xac, 0x40,
0x9d, 0xf1, 0x83, 0x64, 0xc9, 0x2f, 0x9c, 0x88, 0x4d, 0x12, 0x4d, 0xc4, 0xcf, 0xc4, 0x86, 0x66,
0x40, 0xd1, 0x67, 0x38, 0x12, 0x3c, 0x96, 0xa7, 0xae, 0x64, 0x15, 0x1a, 0xf8, 0x25, 0x09, 0xe9,
0xc4, 0xae, 0x89, 0x07, 0x79, 0xe3, 0x5f, 0xa4, 0xd9, 0xc9, 0x27, 0x0c, 0x98, 0x5d, 0x17, 0x40,
0xea, 0xca, 0x59, 0x79, 0xf1, 0xa9, 0xdd, 0xe8, 0x5b, 0x9c, 0x55, 0x5c, 0xc8, 0x2e, 0xb4, 0xce,
0x91, 0xf9, 0x23, 0x9f, 0xf9, 0x76, 0xb3, 0x6f, 0x6d, 0xb6, 0x87, 0x6e, 0xa9, 0x15, 0x51, 0xf3,
0xe0, 0x48, 0x26, 0x1d, 0x44, 0x8c, 0x4e, 0x3c, 0xfd, 0x8d, 0xf3, 0x08, 0x3a, 0x53, 0x4f, 0xa4,
0x07, 0xd6, 0x19, 0x4e, 0x64, 0x6b, 0xfc, 0xc8, 0x89, 0x2f, 0xfc, 0x71, 0xa6, 0x3a, 0xcb, 0x2f,
0x0f, 0xcd, 0x07, 0x86, 0xfb, 0xdd, 0x80, 0xe6, 0x5e, 0x10, 0xc4, 0x59, 0xc4, 0x66, 0x74, 0xdf,
0x82, 0x46, 0x8a, 0x01, 0x45, 0x26, 0x3e, 0x6b, 0x0f, 0x57, 0xe6, 0x95, 0xe5, 0xc9, 0x9c, 0xcb,
0xe6, 0xac, 0x62, 0x73, 0x4f, 0x0a, 0xcd, 0xd5, 0x44, 0x73, 0xb7, 0x4b, 0x28, 0x92, 0xfd, 0xff,
0xb4, 0xf7, 0x1a, 0x5a, 0xca, 0x07, 0x7c, 0xba, 0x91, 0x7f, 0x8e, 0xf2, 0x43, 0x71, 0x9e, 0x3b,
0x71, 0x07, 0x5a, 0x18, 0x8d, 0x92, 0x38, 0x8c, 0x98, 0x18, 0xf9, 0xa2, 0xa7, 0xef, 0xee, 0x0f,
0x03, 0xba, 0x87, 0x18, 0x21, 0xf5, 0x19, 0x7a, 0xf8, 0x39, 0xc3, 0x74, 0x56, 0x36, 0x2d, 0x84,
0x59, 0x14, 0xe2, 0x59, 0x41, 0x08, 0x4b, 0x08, 0xb1, 0x55, 0x12, 0xa2, 0x84, 0x5b, 0x25, 0x08,
0xb9, 0x05, 0x9d, 0x5c, 0xf2, 0xe3, 0x29, 0xfb, 0x2d, 0xe5, 0xc1, 0x03, 0x11, 0xfb, 0x3b, 0xd5,
0xf6, 0xa1, 0x77, 0x59, 0x4c, 0x9a, 0xc4, 0x51, 0x8a, 0xe4, 0x3e, 0x34, 0xfd, 0x7c, 0x52, 0x02,
0xa3, 0x3d, 0x5c, 0x9d, 0x3f, 0x47, 0x4f, 0xa5, 0xb9, 0xef, 0x60, 0xe9, 0x90, 0xfa, 0x11, 0x53,
0x3a, 0xa9, 0x35, 0x36, 0x2a, 0xd6, 0xd8, 0xfc, 0xdd, 0x35, 0xee, 0x42, 0x47, 0x02, 0xe7, 0xb5,
0xb9, 0xef, 0xa1, 0xe3, 0xe1, 0x45, 0x7c, 0x86, 0xff, 0x9c, 0xaa, 0x07, 0xcb, 0x0a, 0x59, 0x72,
0xdd, 0x81, 0xe5, 0xe7, 0x51, 0x9a, 0x60, 0xa0, 0xfb, 0x9a, 0xfb, 0x5b, 0xe2, 0x3e, 0x85, 0xae,
0xce, 0xfb, 0x63, 0x09, 0x5f, 0x72, 0xfa, 0x0f, 0x14, 0xd3, 0x53, 0x45, 0xb6, 0xaa, 0x77, 0x32,
0x67, 0x53, 0xdb, 0x77, 0x13, 0x96, 0x04, 0xaf, 0xf2, 0x84, 0x29, 0x3c, 0xd1, 0x16, 0xb1, 0xdc,
0x12, 0xee, 0x63, 0xe8, 0x6a, 0x30, 0x59, 0xd1, 0xbd, 0x62, 0xe9, 0x55, 0x0b, 0x2e, 0x1b, 0x22,
0xd0, 0x7b, 0x15, 0xa6, 0x8c, 0xff, 0x42, 0xa7, 0xb2, 0x1a, 0x77, 0x17, 0xae, 0x14, 0x62, 0x12,
0xf4, 0x2e, 0xd4, 0x29, 0x0f, 0xd8, 0x86, 0xb0, 0xf9, 0xd5, 0xb2, 0xca, 0xd9, 0x18, 0xbd, 0x3c,
0x63, 0xf8, 0xcd, 0x82, 0xda, 0x5e, 0xc6, 0x4e, 0xc9, 0x11, 0xb4, 0x94, 0xe3, 0xc8, 0xc6, 0xaf,
0xf7, 0xc2, 0xb9, 0x51, 0xf9, 0x2e, 0x47, 0xb4, 0x40, 0xf6, 0xa1, 0x2e, 0x1c, 0x42, 0xae, 0x97,
0x73, 0x0b, 0x86, 0x74, 0xd6, 0xe6, 0x3f, 0x6a, 0x94, 0x43, 0x68, 0xe4, 0xc3, 0x27, 0x6b, 0x33,
0x4e, 0x29, 0xb8, 0xcd, 0x59, 0xaf, 0x78, 0xd5, 0x40, 0x2f, 0xa0, 0x29, 0xbd, 0x40, 0xca, 0xb9,
0xd3, 0x5e, 0x72, 0x36, 0xaa, 0x9e, 0x8b, 0x58, 0x72, 0x8a, 0x64, 0x96, 0xb7, 0x68, 0x95, 0x19,
0xac, 0xd2, 0xf0, 0xdd, 0x05, 0xf2, 0x06, 0x16, 0xf5, 0xf8, 0x48, 0x59, 0xd6, 0xf2, 0xb0, 0x9d,
0x7e, 0x75, 0x82, 0x42, 0x3c, 0x69, 0x88, 0x3f, 0xf6, 0x9d, 0x9f, 0x01, 0x00, 0x00, 0xff, 0xff,
0x91, 0x77, 0xf2, 0xa6, 0xf9, 0x07, 0x00, 0x00,
}

View File

@ -36,10 +36,10 @@ var _ server.Option
type AuthService interface {
Generate(ctx context.Context, in *GenerateRequest, opts ...client.CallOption) (*GenerateResponse, error)
Grant(ctx context.Context, in *GrantRequest, opts ...client.CallOption) (*GrantResponse, error)
Verify(ctx context.Context, in *VerifyRequest, opts ...client.CallOption) (*VerifyResponse, error)
Revoke(ctx context.Context, in *RevokeRequest, opts ...client.CallOption) (*RevokeResponse, error)
Inspect(ctx context.Context, in *InspectRequest, opts ...client.CallOption) (*InspectResponse, error)
Refresh(ctx context.Context, in *RefreshRequest, opts ...client.CallOption) (*RefreshResponse, error)
ListRules(ctx context.Context, in *ListRulesRequest, opts ...client.CallOption) (*ListRulesResponse, error)
}
type authService struct {
@ -74,16 +74,6 @@ func (c *authService) Grant(ctx context.Context, in *GrantRequest, opts ...clien
return out, nil
}
func (c *authService) Verify(ctx context.Context, in *VerifyRequest, opts ...client.CallOption) (*VerifyResponse, error) {
req := c.c.NewRequest(c.name, "Auth.Verify", in)
out := new(VerifyResponse)
err := c.c.Call(ctx, req, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *authService) Revoke(ctx context.Context, in *RevokeRequest, opts ...client.CallOption) (*RevokeResponse, error) {
req := c.c.NewRequest(c.name, "Auth.Revoke", in)
out := new(RevokeResponse)
@ -114,25 +104,35 @@ func (c *authService) Refresh(ctx context.Context, in *RefreshRequest, opts ...c
return out, nil
}
func (c *authService) ListRules(ctx context.Context, in *ListRulesRequest, opts ...client.CallOption) (*ListRulesResponse, error) {
req := c.c.NewRequest(c.name, "Auth.ListRules", in)
out := new(ListRulesResponse)
err := c.c.Call(ctx, req, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// Server API for Auth service
type AuthHandler interface {
Generate(context.Context, *GenerateRequest, *GenerateResponse) error
Grant(context.Context, *GrantRequest, *GrantResponse) error
Verify(context.Context, *VerifyRequest, *VerifyResponse) error
Revoke(context.Context, *RevokeRequest, *RevokeResponse) error
Inspect(context.Context, *InspectRequest, *InspectResponse) error
Refresh(context.Context, *RefreshRequest, *RefreshResponse) error
ListRules(context.Context, *ListRulesRequest, *ListRulesResponse) error
}
func RegisterAuthHandler(s server.Server, hdlr AuthHandler, opts ...server.HandlerOption) error {
type auth interface {
Generate(ctx context.Context, in *GenerateRequest, out *GenerateResponse) error
Grant(ctx context.Context, in *GrantRequest, out *GrantResponse) error
Verify(ctx context.Context, in *VerifyRequest, out *VerifyResponse) error
Revoke(ctx context.Context, in *RevokeRequest, out *RevokeResponse) error
Inspect(ctx context.Context, in *InspectRequest, out *InspectResponse) error
Refresh(ctx context.Context, in *RefreshRequest, out *RefreshResponse) error
ListRules(ctx context.Context, in *ListRulesRequest, out *ListRulesResponse) error
}
type Auth struct {
auth
@ -153,10 +153,6 @@ func (h *authHandler) Grant(ctx context.Context, in *GrantRequest, out *GrantRes
return h.AuthHandler.Grant(ctx, in, out)
}
func (h *authHandler) Verify(ctx context.Context, in *VerifyRequest, out *VerifyResponse) error {
return h.AuthHandler.Verify(ctx, in, out)
}
func (h *authHandler) Revoke(ctx context.Context, in *RevokeRequest, out *RevokeResponse) error {
return h.AuthHandler.Revoke(ctx, in, out)
}
@ -168,3 +164,7 @@ func (h *authHandler) Inspect(ctx context.Context, in *InspectRequest, out *Insp
func (h *authHandler) Refresh(ctx context.Context, in *RefreshRequest, out *RefreshResponse) error {
return h.AuthHandler.Refresh(ctx, in, out)
}
func (h *authHandler) ListRules(ctx context.Context, in *ListRulesRequest, out *ListRulesResponse) error {
return h.AuthHandler.ListRules(ctx, in, out)
}

View File

@ -5,10 +5,16 @@ package go.micro.auth;
service Auth {
rpc Generate(GenerateRequest) returns (GenerateResponse) {};
rpc Grant(GrantRequest) returns (GrantResponse) {};
rpc Verify(VerifyRequest) returns (VerifyResponse) {};
rpc Revoke(RevokeRequest) returns (RevokeResponse) {};
rpc Inspect(InspectRequest) returns (InspectResponse) {};
rpc Refresh(RefreshRequest) returns (RefreshResponse) {};
rpc ListRules(ListRulesRequest) returns (ListRulesResponse) {};
}
message Rule {
string id = 1;
string role = 2;
Resource resource = 3;
}
message Token {
@ -52,13 +58,6 @@ message GrantRequest {
message GrantResponse {}
message VerifyRequest {
Account account = 1;
Resource resource = 2;
}
message VerifyResponse {}
message RevokeRequest {
string role = 1;
Resource resource = 2;
@ -81,4 +80,11 @@ message RefreshRequest {
message RefreshResponse {
Token token = 1;
}
}
message ListRulesRequest {
}
message ListRulesResponse {
repeated Rule rules = 1;
}

View File

@ -2,7 +2,9 @@ package service
import (
"context"
"fmt"
"strings"
"sync"
"time"
"github.com/micro/go-micro/v2/auth"
@ -10,6 +12,7 @@ import (
"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"
)
// NewAuth returns a new instance of the Auth service
@ -24,6 +27,9 @@ type svc struct {
options auth.Options
auth pb.AuthService
jwt token.Provider
rules []*pb.Rule
sync.Mutex
}
func (s *svc) String() string {
@ -44,6 +50,13 @@ func (s *svc) Init(opts ...auth.Option) {
if key := s.options.PublicKey; len(key) > 0 {
s.jwt = jwt.NewTokenProvider(token.WithPublicKey(key))
}
// load rules periodically from the auth service
timer := time.NewTicker(time.Second * 30)
go func() {
s.loadRules()
<-timer.C
}()
}
func (s *svc) Options() auth.Options {
@ -95,18 +108,31 @@ func (s *svc) Revoke(role string, res *auth.Resource) error {
// Verify an account has access to a resource
func (s *svc) Verify(acc *auth.Account, res *auth.Resource) error {
_, err := s.auth.Verify(context.TODO(), &pb.VerifyRequest{
Account: &pb.Account{
Id: acc.ID,
Roles: acc.Roles,
},
Resource: &pb.Resource{
Type: res.Type,
Name: res.Name,
Endpoint: res.Endpoint,
},
})
return err
queries := [][]string{
{res.Type, "*"}, // check for wildcard resource type, e.g. service.*
{res.Type, res.Name, "*"}, // check for wildcard name, e.g. service.foo*
{res.Type, res.Name, res.Endpoint, "*"}, // check for wildcard endpoints, e.g. service.foo.ListFoo:*
{res.Type, res.Name, res.Endpoint}, // check for specific role, e.g. service.foo.ListFoo:admin
}
// 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})
}
}
for _, q := range queries {
for _, rule := range s.listRules(q...) {
if isValidRule(rule, acc, res) {
return nil
}
}
}
return auth.ErrForbidden
}
// Inspect a token
@ -150,6 +176,62 @@ func (s *svc) Refresh(secret string, opts ...auth.RefreshOption) (*auth.Token, e
return serializeToken(rsp.Token), nil
}
var ruleJoinKey = ":"
// isValidRule returns a bool, indicating if a rule permits access to a
// resource for a given account
func isValidRule(rule *pb.Rule, acc *auth.Account, res *auth.Resource) bool {
if rule.Role == "*" {
return true
}
for _, role := range acc.Roles {
if rule.Role == role {
return true
}
// allow user.anything if role is user.*
if strings.HasSuffix(rule.Role, ".*") && strings.HasPrefix(rule.Role, role+".") {
return true
}
}
return false
}
// listRules gets all the rules from the store which have an id
// prefix matching the filters
func (s *svc) listRules(filters ...string) []*pb.Rule {
s.Lock()
defer s.Unlock()
prefix := strings.Join(filters, ruleJoinKey)
var rules []*pb.Rule
for _, r := range s.rules {
if strings.HasPrefix(r.Id, prefix) {
rules = append(rules, r)
}
}
return rules
}
// loadRules retrieves the rules from the auth service
func (s *svc) loadRules() {
rsp, err := s.auth.ListRules(context.TODO(), &pb.ListRulesRequest{}, client.WithRetries(3))
s.Lock()
defer s.Unlock()
if err != nil {
log.Errorf("Error listing rules: %v", err)
s.rules = []*pb.Rule{}
return
}
s.rules = rsp.Rules
}
func serializeToken(t *pb.Token) *auth.Token {
return &auth.Token{
Token: t.Token,

View File

@ -1,74 +0,0 @@
package store
import (
"encoding/json"
"strings"
"github.com/micro/go-micro/v2/auth"
"github.com/micro/go-micro/v2/store"
)
// Rule is an access control rule
type Rule struct {
Role string `json:"rule"`
Resource *auth.Resource `json:"resource"`
}
var joinKey = ":"
// Key to be used when written to the store
func (r *Rule) Key() string {
comps := []string{r.Resource.Type, r.Resource.Name, r.Resource.Endpoint, r.Role}
return strings.Join(comps, joinKey)
}
// Bytes returns json encoded bytes
func (r *Rule) Bytes() []byte {
bytes, _ := json.Marshal(r)
return bytes
}
// isValidRule returns a bool, indicating if a rule permits access to a
// resource for a given account
func isValidRule(rule Rule, acc *auth.Account, res *auth.Resource) bool {
if rule.Role == "*" {
return true
}
for _, role := range acc.Roles {
if rule.Role == role {
return true
}
// allow user.anything if role is user.*
if strings.HasSuffix(rule.Role, ".*") && strings.HasPrefix(rule.Role, role+".") {
return true
}
}
return false
}
// listRules gets all the rules from the store which have a key
// prefix matching the filters
func (s *Store) listRules(filters ...string) ([]Rule, error) {
// get the records from the store
prefix := strings.Join(filters, joinKey)
recs, err := s.opts.Store.Read(prefix, store.ReadPrefix())
if err != nil {
return nil, err
}
// unmarshal the records
rules := make([]Rule, 0, len(recs))
for _, rec := range recs {
var r Rule
if err := json.Unmarshal(rec.Value, &r); err != nil {
return nil, err
}
rules = append(rules, r)
}
// return the rules
return rules, nil
}

View File

@ -1,171 +0,0 @@
package store
import (
"fmt"
"strings"
"github.com/micro/go-micro/v2/auth"
"github.com/micro/go-micro/v2/auth/token"
"github.com/micro/go-micro/v2/auth/token/basic"
"github.com/micro/go-micro/v2/store"
memStore "github.com/micro/go-micro/v2/store/memory"
)
// NewAuth returns a new default registry which is store
func NewAuth(opts ...auth.Option) auth.Auth {
var s Store
s.Init(opts...)
return &s
}
// Store implementation of auth
type Store struct {
secretProvider token.Provider
tokenProvider token.Provider
opts auth.Options
}
// String returns store
func (s *Store) String() string {
return "store"
}
// Init the auth
func (s *Store) Init(opts ...auth.Option) {
for _, o := range opts {
o(&s.opts)
}
// use the default store as a fallback
if s.opts.Store == nil {
s.opts.Store = store.DefaultStore
}
// noop will not work for auth
if s.opts.Store.String() == "noop" {
s.opts.Store = memStore.NewStore()
}
if s.tokenProvider == nil {
s.tokenProvider = basic.NewTokenProvider(token.WithStore(s.opts.Store))
}
if s.secretProvider == nil {
s.secretProvider = basic.NewTokenProvider(token.WithStore(s.opts.Store))
}
}
// Options returns the options
func (s *Store) Options() auth.Options {
return s.opts
}
// Generate a new account
func (s *Store) Generate(id string, opts ...auth.GenerateOption) (*auth.Account, error) {
// parse the options
options := auth.NewGenerateOptions(opts...)
// Generate a long-lived secret
secretOpts := []token.GenerateOption{
token.WithExpiry(options.SecretExpiry),
token.WithMetadata(options.Metadata),
token.WithRoles(options.Roles...),
}
secret, err := s.secretProvider.Generate(id, secretOpts...)
if err != nil {
return nil, err
}
// return the account
return &auth.Account{
ID: id,
Roles: options.Roles,
Metadata: options.Metadata,
Secret: secret,
}, nil
}
// Grant access to a resource
func (s *Store) Grant(role string, res *auth.Resource) error {
r := Rule{role, res}
return s.opts.Store.Write(&store.Record{Key: r.Key(), Value: r.Bytes()})
}
// Revoke access to a resource
func (s *Store) Revoke(role string, res *auth.Resource) error {
r := Rule{role, res}
err := s.opts.Store.Delete(r.Key())
if err == store.ErrNotFound {
return auth.ErrNotFound
}
return err
}
// Verify an account has access to a resource
func (s *Store) Verify(acc *auth.Account, res *auth.Resource) error {
queries := [][]string{
{res.Type, "*"}, // check for wildcard resource type, e.g. service.*
{res.Type, res.Name, "*"}, // check for wildcard name, e.g. service.foo*
{res.Type, res.Name, res.Endpoint, "*"}, // check for wildcard endpoints, e.g. service.foo.ListFoo:*
{res.Type, res.Name, res.Endpoint}, // check for specific role, e.g. service.foo.ListFoo:admin
}
// 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})
}
}
for _, q := range queries {
rules, err := s.listRules(q...)
if err != nil {
return err
}
for _, rule := range rules {
if isValidRule(rule, acc, res) {
return nil
}
}
}
return auth.ErrForbidden
}
// Inspect a token
func (s *Store) Inspect(t string) (*auth.Account, error) {
tok, err := s.tokenProvider.Inspect(t)
if err == token.ErrInvalidToken || err == token.ErrNotFound {
return nil, auth.ErrInvalidToken
} else if err != nil {
return nil, err
}
return &auth.Account{
ID: tok.Subject,
Roles: tok.Roles,
Metadata: tok.Metadata,
}, nil
}
// Refresh an account using a secret
func (s *Store) Refresh(secret string, opts ...auth.RefreshOption) (*auth.Token, error) {
sec, err := s.secretProvider.Inspect(secret)
if err == token.ErrInvalidToken || err == token.ErrNotFound {
return nil, auth.ErrInvalidToken
} else if err != nil {
return nil, err
}
options := auth.NewRefreshOptions(opts...)
return s.tokenProvider.Generate(sec.Subject,
token.WithExpiry(options.TokenExpiry),
token.WithMetadata(sec.Metadata),
token.WithRoles(sec.Roles...),
)
}

View File

@ -1,308 +0,0 @@
package store
import (
"log"
"testing"
"github.com/micro/go-micro/v2/auth"
memStore "github.com/micro/go-micro/v2/store/memory"
)
func TestGenerate(t *testing.T) {
s := memStore.NewStore()
a := NewAuth(auth.Store(s))
id := "test"
roles := []string{"admin"}
metadata := map[string]string{"foo": "bar"}
opts := []auth.GenerateOption{
auth.WithRoles(roles...),
auth.WithMetadata(metadata),
}
// generate the account
acc, err := a.Generate(id, opts...)
if err != nil {
t.Fatalf("Generate returned an error: %v, expected nil", err)
}
// validate the account attributes were set correctly
if acc.ID != id {
t.Errorf("Generate returned %v as the ID, expected %v", acc.ID, id)
}
if len(acc.Roles) != len(roles) {
t.Errorf("Generate returned %v as the roles, expected %v", acc.Roles, roles)
}
if len(acc.Metadata) != len(metadata) {
t.Errorf("Generate returned %v as the metadata, expected %v", acc.Metadata, metadata)
}
// validate the secret is valid
if _, err := a.Refresh(acc.Secret.Token); err != nil {
t.Errorf("Generate returned an invalid secret, error: %v", err)
}
}
func TestGrant(t *testing.T) {
s := memStore.NewStore()
a := NewAuth(auth.Store(s))
res := &auth.Resource{Type: "service", Name: "Test", Endpoint: "Foo.Bar"}
if err := a.Grant("users.*", res); err != nil {
t.Fatalf("Grant returned an error: %v, expected nil", err)
}
recs, err := s.List()
if err != nil {
t.Fatalf("Could not read from the store: %v", err)
}
if len(recs) != 1 {
t.Errorf("Expected Grant to write 1 record, actually wrote %v", len(recs))
}
}
func TestRevoke(t *testing.T) {
s := memStore.NewStore()
a := NewAuth(auth.Store(s))
res := &auth.Resource{Type: "service", Name: "Test", Endpoint: "Foo.Bar"}
if err := a.Grant("users.*", res); err != nil {
t.Fatalf("Grant returned an error: %v, expected nil", err)
}
recs, err := s.List()
if err != nil {
t.Fatalf("Could not read from the store: %v", err)
}
if len(recs) != 1 {
t.Fatalf("Expected Grant to write 1 record, actually wrote %v", len(recs))
}
if err := a.Revoke("users.*", res); err != nil {
t.Fatalf("Revoke returned an error: %v, expected nil", err)
}
recs, err = s.List()
if err != nil {
t.Fatalf("Could not read from the store: %v", err)
}
if len(recs) != 0 {
t.Fatalf("Expected Revoke to delete 1 record, actually deleted %v", 1-len(recs))
}
}
func TestInspect(t *testing.T) {
a := NewAuth()
t.Run("Valid Token", func(t *testing.T) {
id := "test"
roles := []string{"admin"}
metadata := map[string]string{"foo": "bar"}
opts := []auth.GenerateOption{
auth.WithRoles(roles...),
auth.WithMetadata(metadata),
}
// generate and inspect the token
acc, err := a.Generate("test", opts...)
if err != nil {
log.Fatalf("Generate returned an error: %v, expected nil", err)
}
tok, err := a.Refresh(acc.Secret.Token)
if err != nil {
log.Fatalf("Refresh returned an error: %v, expected nil", err)
}
acc2, err := a.Inspect(tok.Token)
if err != nil {
log.Fatalf("Inspect returned an error: %v, expected nil", err)
}
// validate the account attributes were retrieved correctly
if acc2.ID != id {
t.Errorf("Generate returned %v as the ID, expected %v", acc.ID, id)
}
if len(acc2.Roles) != len(roles) {
t.Errorf("Generate returned %v as the roles, expected %v", acc.Roles, roles)
}
if len(acc2.Metadata) != len(metadata) {
t.Errorf("Generate returned %v as the metadata, expected %v", acc.Metadata, metadata)
}
})
t.Run("Invalid Token", func(t *testing.T) {
_, err := a.Inspect("invalid token")
if err != auth.ErrInvalidToken {
t.Errorf("Inspect returned %v error, expected %v", err, auth.ErrInvalidToken)
}
})
}
func TestRefresh(t *testing.T) {
a := NewAuth()
t.Run("Valid Secret", func(t *testing.T) {
roles := []string{"admin"}
metadata := map[string]string{"foo": "bar"}
opts := []auth.GenerateOption{
auth.WithRoles(roles...),
auth.WithMetadata(metadata),
}
// generate the account
acc, err := a.Generate("test", opts...)
if err != nil {
log.Fatalf("Generate returned an error: %v, expected nil", err)
}
// refresh the token
tok, err := a.Refresh(acc.Secret.Token)
if err != nil {
log.Fatalf("Refresh returned an error: %v, expected nil", err)
}
// validate the account attributes were set correctly
if acc.ID != tok.Subject {
t.Errorf("Refresh returned %v as the ID, expected %v", acc.ID, tok.Subject)
}
if len(acc.Roles) != len(tok.Roles) {
t.Errorf("Refresh returned %v as the roles, expected %v", acc.Roles, tok.Subject)
}
if len(acc.Metadata) != len(tok.Metadata) {
t.Errorf("Refresh returned %v as the metadata, expected %v", acc.Metadata, tok.Metadata)
}
})
t.Run("Invalid Secret", func(t *testing.T) {
_, err := a.Refresh("invalid secret")
if err != auth.ErrInvalidToken {
t.Errorf("Inspect returned %v error, expected %v", err, auth.ErrInvalidToken)
}
})
}
func TestVerify(t *testing.T) {
testRules := []struct {
Role string
Resource *auth.Resource
}{
{
Role: "*",
Resource: &auth.Resource{Type: "service", Name: "go.micro.apps", Endpoint: "Apps.PublicList"},
},
{
Role: "*",
Resource: &auth.Resource{Type: "service", Name: "go.micro.web", Endpoint: "/foo"},
},
{
Role: "*",
Resource: &auth.Resource{Type: "service", Name: "go.micro.web", Endpoint: "/bar/*"},
},
{
Role: "user.*",
Resource: &auth.Resource{Type: "service", Name: "go.micro.apps", Endpoint: "Apps.List"},
},
{
Role: "user.developer",
Resource: &auth.Resource{Type: "service", Name: "go.micro.apps", Endpoint: "Apps.Update"},
},
{
Role: "admin",
Resource: &auth.Resource{Type: "service", Name: "go.micro.apps", Endpoint: "Apps.Delete"},
},
{
Role: "admin",
Resource: &auth.Resource{Type: "service", Name: "*", Endpoint: "*"},
},
}
a := NewAuth()
for _, r := range testRules {
if err := a.Grant(r.Role, r.Resource); err != nil {
t.Fatalf("Grant returned an error: %v, expected nil", err)
}
}
testTable := []struct {
Name string
Roles []string
Resource *auth.Resource
Error error
}{
{
Name: "An account with no roles accessing a public endpoint",
Resource: &auth.Resource{Type: "service", Name: "go.micro.apps", Endpoint: "Apps.PublicList"},
},
{
Name: "An account with no roles accessing a private endpoint",
Resource: &auth.Resource{Type: "service", Name: "go.micro.apps", Endpoint: "Apps.Update"},
Error: auth.ErrForbidden,
},
{
Name: "An account with the user role accessing a user* endpoint",
Roles: []string{"user"},
Resource: &auth.Resource{Type: "service", Name: "go.micro.apps", Endpoint: "Apps.List"},
},
{
Name: "An account with the user role accessing a user.admin endpoint",
Roles: []string{"user"},
Resource: &auth.Resource{Type: "service", Name: "go.micro.apps", Endpoint: "Apps.Delete"},
Error: auth.ErrForbidden,
},
{
Name: "An account with the developer role accessing a user.developer endpoint",
Roles: []string{"user.developer"},
Resource: &auth.Resource{Type: "service", Name: "go.micro.apps", Endpoint: "Apps.Update"},
},
{
Name: "An account with the developer role accessing an admin endpoint",
Roles: []string{"user.developer"},
Resource: &auth.Resource{Type: "service", Name: "go.micro.apps", Endpoint: "Apps.Delete"},
Error: auth.ErrForbidden,
},
{
Name: "An admin account accessing an admin endpoint",
Roles: []string{"admin"},
Resource: &auth.Resource{Type: "service", Name: "go.micro.apps", Endpoint: "Apps.Delete"},
},
{
Name: "An admin account accessing a generic service endpoint",
Roles: []string{"admin"},
Resource: &auth.Resource{Type: "service", Name: "go.micro.foo", Endpoint: "Foo.Bar"},
},
{
Name: "An admin account accessing an unauthorised endpoint",
Roles: []string{"admin"},
Resource: &auth.Resource{Type: "infra", Name: "go.micro.foo", Endpoint: "Foo.Bar"},
Error: auth.ErrForbidden,
},
{
Name: "A account with no roles accessing an unauthorised endpoint",
Resource: &auth.Resource{Type: "infra", Name: "go.micro.foo", Endpoint: "Foo.Bar"},
Error: auth.ErrForbidden,
},
{
Name: "Accessing a public web path",
Resource: &auth.Resource{Type: "service", Name: "go.micro.web", Endpoint: "/foo"},
},
{
Name: "Accessing a public web path with an invalid wildcard endpoint",
Resource: &auth.Resource{Type: "service", Name: "go.micro.web", Endpoint: "/foo/foo"},
Error: auth.ErrForbidden,
},
{
Name: "Accessing a public web path with wildcard endpoint",
Resource: &auth.Resource{Type: "service", Name: "go.micro.web", Endpoint: "/bar/foo"},
},
}
for _, tc := range testTable {
t.Run(tc.Name, func(t *testing.T) {
acc := &auth.Account{Roles: tc.Roles}
if err := a.Verify(acc, tc.Resource); err != tc.Error {
t.Errorf("Verify returned %v error, expected %v", err, tc.Error)
}
})
}
}

View File

@ -71,7 +71,6 @@ import (
// auth
svcAuth "github.com/micro/go-micro/v2/auth/service"
storeAuth "github.com/micro/go-micro/v2/auth/store"
// auth providers
"github.com/micro/go-micro/v2/auth/provider/basic"
@ -360,7 +359,6 @@ var (
DefaultAuths = map[string]func(...auth.Option) auth.Auth{
"service": svcAuth.NewAuth,
"store": storeAuth.NewAuth,
}
DefaultAuthProviders = map[string]func(...provider.Option) provider.Provider{