From 8f74abf7b2e624990335c6312c69fa298c9fb3f1 Mon Sep 17 00:00:00 2001 From: Brian Kassouf Date: Thu, 2 Jan 2020 16:54:09 -0800 Subject: [PATCH 1/4] Add identity templating helper to sdk/framework --- helper/identity/identity.go | 81 ++++ sdk/framework/identity.go | 52 +++ sdk/framework/identity_test.go | 100 +++++ {helper => sdk/helper}/identity/templating.go | 21 +- .../helper}/identity/templating_test.go | 24 +- sdk/logical/identity.pb.go | 154 +++++-- sdk/logical/identity.proto | 26 ++ sdk/logical/system_view.go | 9 + sdk/plugin/grpc_system.go | 26 ++ sdk/plugin/grpc_system_test.go | 28 ++ sdk/plugin/pb/backend.pb.go | 411 +++++++++++------- sdk/plugin/pb/backend.proto | 9 + vault/dynamic_system_view.go | 52 ++- vault/dynamic_system_view_test.go | 151 +++++++ vault/identity_store_oidc.go | 17 +- vault/policy.go | 17 +- .../hashicorp/vault/api/plugin_helpers.go | 3 + .../hashicorp/vault/sdk/framework/identity.go | 52 +++ .../vault/sdk/helper/identity/templating.go | 358 +++++++++++++++ .../vault/sdk/logical/identity.pb.go | 154 +++++-- .../vault/sdk/logical/identity.proto | 26 ++ .../vault/sdk/logical/system_view.go | 9 + .../hashicorp/vault/sdk/plugin/grpc_system.go | 26 ++ .../vault/sdk/plugin/pb/backend.pb.go | 411 +++++++++++------- .../vault/sdk/plugin/pb/backend.proto | 9 + vendor/modules.txt | 1 + 26 files changed, 1806 insertions(+), 421 deletions(-) create mode 100644 sdk/framework/identity.go create mode 100644 sdk/framework/identity_test.go rename {helper => sdk/helper}/identity/templating.go (95%) rename {helper => sdk/helper}/identity/templating_test.go (97%) create mode 100644 vault/dynamic_system_view_test.go create mode 100644 vendor/github.com/hashicorp/vault/sdk/framework/identity.go create mode 100644 vendor/github.com/hashicorp/vault/sdk/helper/identity/templating.go diff --git a/helper/identity/identity.go b/helper/identity/identity.go index 46789c0357a0..7e9d4c0e848d 100644 --- a/helper/identity/identity.go +++ b/helper/identity/identity.go @@ -5,6 +5,7 @@ import ( proto "github.com/golang/protobuf/proto" "github.com/hashicorp/errwrap" + "github.com/hashicorp/vault/sdk/logical" ) func (g *Group) Clone() (*Group, error) { @@ -63,3 +64,83 @@ func (p *Alias) Clone() (*Alias, error) { return &clonedAlias, nil } + +// ToSDKAlias converts the provided alias to an SDK compatible alias. +func ToSDKAlias(a *Alias) *logical.Alias { + if a == nil { + return nil + } + metadata := make(map[string]string, len(a.Metadata)) + for k, v := range a.Metadata { + metadata[k] = v + } + + return &logical.Alias{ + Name: a.Name, + ID: a.ID, + MountAccessor: a.MountAccessor, + MountType: a.MountType, + Metadata: metadata, + NamespaceID: a.NamespaceID, + } +} + +// ToSDKEntity converts the provided entity to an SDK compatible entity. +func ToSDKEntity(e *Entity) *logical.Entity { + if e == nil { + return nil + } + + aliases := make([]*logical.Alias, len(e.Aliases)) + + for i, a := range e.Aliases { + aliases[i] = ToSDKAlias(a) + } + + metadata := make(map[string]string, len(e.Metadata)) + for k, v := range e.Metadata { + metadata[k] = v + } + + return &logical.Entity{ + ID: e.ID, + Name: e.Name, + Disabled: e.Disabled, + Aliases: aliases, + Metadata: metadata, + NamespaceID: e.NamespaceID, + } +} + +// ToSDKGroup converts the provided group to an SDK compatible group. +func ToSDKGroup(g *Group) *logical.Group { + if g == nil { + return nil + } + + metadata := make(map[string]string, len(g.Metadata)) + for k, v := range g.Metadata { + metadata[k] = v + } + + return &logical.Group{ + ID: g.ID, + Name: g.Name, + Metadata: metadata, + NamespaceID: g.NamespaceID, + } +} + +// ToSDKGroups converts the provided group list to an SDK compatible group list. +func ToSDKGroups(groups []*Group) []*logical.Group { + if groups == nil { + return nil + } + + ret := make([]*logical.Group, len(groups)) + + for i, g := range groups { + ret[i] = ToSDKGroup(g) + } + return ret +} diff --git a/sdk/framework/identity.go b/sdk/framework/identity.go new file mode 100644 index 000000000000..0745a082e8e4 --- /dev/null +++ b/sdk/framework/identity.go @@ -0,0 +1,52 @@ +package framework + +import ( + "errors" + + "github.com/hashicorp/errwrap" + "github.com/hashicorp/vault/sdk/helper/identity" + "github.com/hashicorp/vault/sdk/logical" +) + +func PopulateIdentityTemplate(tpl string, entityID string, sysView logical.SystemView) (string, error) { + entity, err := sysView.EntityInfo(entityID) + if err != nil { + return "", err + } + if entity == nil { + return "", errors.New("no entity found") + } + + groups, err := sysView.GroupsForEntity(entityID) + if err != nil { + return "", err + } + + // TODO: Namespace bound? + input := identity.PopulateStringInput{ + String: tpl, + Entity: entity, + Groups: groups, + Mode: identity.ACLTemplating, + } + + _, out, err := identity.PopulateString(input) + if err != nil { + return "", err + } + + return out, nil +} + +func ValidateIdentityTemplate(tpl string) (bool, error) { + hasTemplating, _, err := identity.PopulateString(identity.PopulateStringInput{ + Mode: identity.ACLTemplating, + ValidityCheckOnly: true, + String: tpl, + }) + if err != nil { + return false, errwrap.Wrapf("failed to validate policy templating: {{err}}", err) + } + + return hasTemplating, nil +} diff --git a/sdk/framework/identity_test.go b/sdk/framework/identity_test.go new file mode 100644 index 000000000000..8459dd35346b --- /dev/null +++ b/sdk/framework/identity_test.go @@ -0,0 +1,100 @@ +package framework + +import ( + "testing" + + "github.com/hashicorp/vault/sdk/logical" +) + +func TestIdentityTemplating(t *testing.T) { + sysView := &logical.StaticSystemView{ + EntityVal: &logical.Entity{ + ID: "test-id", + Name: "test", + Aliases: []*logical.Alias{ + { + ID: "alias-id", + Name: "test alias", + MountAccessor: "test_mount", + MountType: "secret", + Metadata: map[string]string{ + "alias-metadata": "metadata-value", + }, + }, + }, + Metadata: map[string]string{ + "entity-metadata": "metadata-value", + }, + }, + GroupsVal: []*logical.Group{ + { + ID: "group1-id", + Name: "group1", + Metadata: map[string]string{ + "group-metadata": "metadata-value", + }, + }, + }, + } + + tCases := []struct { + tpl string + expected string + }{ + { + tpl: "{{identity.entity.id}}", + expected: "test-id", + }, + { + tpl: "{{identity.entity.name}}", + expected: "test", + }, + { + tpl: "{{identity.entity.metadata.entity-metadata}}", + expected: "metadata-value", + }, + { + tpl: "{{identity.entity.aliases.test_mount.id}}", + expected: "alias-id", + }, + { + tpl: "{{identity.entity.aliases.test_mount.id}}", + expected: "alias-id", + }, + { + tpl: "{{identity.entity.aliases.test_mount.name}}", + expected: "test alias", + }, + { + tpl: "{{identity.entity.aliases.test_mount.metadata.alias-metadata}}", + expected: "metadata-value", + }, + { + tpl: "{{identity.groups.ids.group1-id.name}}", + expected: "group1", + }, + { + tpl: "{{identity.groups.names.group1.id}}", + expected: "group1-id", + }, + { + tpl: "{{identity.groups.names.group1.metadata.group-metadata}}", + expected: "metadata-value", + }, + { + tpl: "{{identity.groups.ids.group1-id.metadata.group-metadata}}", + expected: "metadata-value", + }, + } + + for _, tCase := range tCases { + out, err := PopulateIdentityTemplate(tCase.tpl, "test", sysView) + if err != nil { + t.Fatal(err) + } + + if out != tCase.expected { + t.Fatalf("got %q, expected %q", out, tCase.expected) + } + } +} diff --git a/helper/identity/templating.go b/sdk/helper/identity/templating.go similarity index 95% rename from helper/identity/templating.go rename to sdk/helper/identity/templating.go index aea81d3f036d..acb6b9fb8fda 100644 --- a/helper/identity/templating.go +++ b/sdk/helper/identity/templating.go @@ -9,7 +9,7 @@ import ( "time" "github.com/hashicorp/errwrap" - "github.com/hashicorp/vault/helper/namespace" + "github.com/hashicorp/vault/sdk/logical" ) var ( @@ -27,9 +27,9 @@ const ( type PopulateStringInput struct { String string ValidityCheckOnly bool - Entity *Entity - Groups []*Group - Namespace *namespace.Namespace + Entity *logical.Entity + Groups []*logical.Group + NamespaceID string Mode int // processing mode, ACLTemplate or JSONTemplating Now time.Time // optional, defaults to current time @@ -165,7 +165,7 @@ func PopulateString(p PopulateStringInput) (bool, string, error) { func performTemplating(input string, p *PopulateStringInput) (string, error) { - performAliasTemplating := func(trimmed string, alias *Alias) (string, error) { + performAliasTemplating := func(trimmed string, alias *logical.Alias) (string, error) { switch { case trimmed == "id": return p.templateHandler(alias.ID) @@ -210,7 +210,7 @@ func performTemplating(input string, p *PopulateStringInput) (string, error) { if len(split) != 2 { return "", errors.New("invalid alias selector") } - var alias *Alias + var alias *logical.Alias for _, a := range p.Entity.Aliases { if split[0] == a.MountAccessor { alias = a @@ -223,7 +223,7 @@ func performTemplating(input string, p *PopulateStringInput) (string, error) { } // An empty alias is sufficient for generating defaults - alias = &Alias{Metadata: make(map[string]string)} + alias = &logical.Alias{Metadata: make(map[string]string)} } return performAliasTemplating(split[1], alias) } @@ -254,17 +254,16 @@ func performTemplating(input string, p *PopulateStringInput) (string, error) { if len(accessorSplit) != 2 { return "", errors.New("invalid groups accessor") } - var found *Group + var found *logical.Group for _, group := range p.Groups { var compare string if ids { compare = group.ID } else { - if p.Namespace != nil && group.NamespaceID == p.Namespace.ID { - compare = group.Name - } else { + if p.NamespaceID != "" && group.NamespaceID != p.NamespaceID { continue } + compare = group.Name } if compare == accessorSplit[0] { diff --git a/helper/identity/templating_test.go b/sdk/helper/identity/templating_test.go similarity index 97% rename from helper/identity/templating_test.go rename to sdk/helper/identity/templating_test.go index 81b2796783ce..e1ef99e33684 100644 --- a/helper/identity/templating_test.go +++ b/sdk/helper/identity/templating_test.go @@ -8,7 +8,7 @@ import ( "testing" "time" - "github.com/hashicorp/vault/helper/namespace" + "github.com/hashicorp/vault/sdk/logical" ) // intentionally != time.Now() to catch latent used of time.Now instead of @@ -332,16 +332,16 @@ func TestPopulate_Basic(t *testing.T) { } for _, test := range tests { - var entity *Entity + var entity *logical.Entity if !test.nilEntity { - entity = &Entity{ + entity = &logical.Entity{ ID: "entityID", Name: test.entityName, Metadata: test.metadata, } } if test.aliasAccessor != "" { - entity.Aliases = []*Alias{ + entity.Aliases = []*logical.Alias{ { MountAccessor: test.aliasAccessor, ID: test.aliasID, @@ -350,19 +350,19 @@ func TestPopulate_Basic(t *testing.T) { }, } } - var groups []*Group + var groups []*logical.Group if test.groupName != "" { - groups = append(groups, &Group{ + groups = append(groups, &logical.Group{ ID: "groupID", Name: test.groupName, Metadata: test.groupMetadata, - NamespaceID: namespace.RootNamespace.ID, + NamespaceID: "root", }) } if test.groupMemberships != nil { for i, groupName := range test.groupMemberships { - groups = append(groups, &Group{ + groups = append(groups, &logical.Group{ ID: fmt.Sprintf("%s_%d", groupName, i), Name: groupName, }) @@ -375,7 +375,7 @@ func TestPopulate_Basic(t *testing.T) { String: test.input, Entity: entity, Groups: groups, - Namespace: namespace.RootNamespace, + NamespaceID: "root", Now: test.now, }) if err != nil { @@ -421,7 +421,7 @@ func TestPopulate_CurrentTime(t *testing.T) { } func TestPopulate_FullObject(t *testing.T) { - var testEntity = &Entity{ + var testEntity = &logical.Entity{ ID: "abc-123", Name: "Entity Name", Metadata: map[string]string{ @@ -429,7 +429,7 @@ func TestPopulate_FullObject(t *testing.T) { "size": "small", "non-printable": "\"\n\t", }, - Aliases: []*Alias{ + Aliases: []*logical.Alias{ { MountAccessor: "aws_123", Metadata: map[string]string{ @@ -440,7 +440,7 @@ func TestPopulate_FullObject(t *testing.T) { }, } - var testGroups = []*Group{ + var testGroups = []*logical.Group{ {ID: "a08b0c02", Name: "g1"}, {ID: "239bef91", Name: "g2"}, } diff --git a/sdk/logical/identity.pb.go b/sdk/logical/identity.pb.go index 51fde70f3a60..94102de78d62 100644 --- a/sdk/logical/identity.pb.go +++ b/sdk/logical/identity.pb.go @@ -30,7 +30,10 @@ type Entity struct { // Metadata represents the custom data tied to this entity Metadata map[string]string `sentinel:"" 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"` // Disabled is true if the entity is disabled. - Disabled bool `sentinel:"" protobuf:"varint,5,opt,name=disabled,proto3" json:"disabled,omitempty"` + Disabled bool `sentinel:"" protobuf:"varint,5,opt,name=disabled,proto3" json:"disabled,omitempty"` + // NamespaceID is the identifier of the namespace to which this entity + // belongs to. + NamespaceID string `sentinel:"" protobuf:"bytes,6,opt,name=namespace_id,json=namespaceID,proto3" json:"namespace_id,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -96,6 +99,13 @@ func (m *Entity) GetDisabled() bool { return false } +func (m *Entity) GetNamespaceID() string { + if m != nil { + return m.NamespaceID + } + return "" +} + type Alias struct { // MountType is the backend mount's type to which this identity belongs MountType string `sentinel:"" protobuf:"bytes,1,opt,name=mount_type,json=mountType,proto3" json:"mount_type,omitempty"` @@ -105,10 +115,15 @@ type Alias struct { // Name is the identifier of this identity in its authentication source Name string `sentinel:"" protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` // Metadata represents the custom data tied to this alias - Metadata map[string]string `sentinel:"" 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"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Metadata map[string]string `sentinel:"" 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"` + // ID is the unique identifier for the alias + ID string `sentinel:"" protobuf:"bytes,5,opt,name=ID,proto3" json:"ID,omitempty"` + // NamespaceID is the identifier of the namespace to which this alias + // belongs. + NamespaceID string `sentinel:"" protobuf:"bytes,6,opt,name=namespace_id,json=namespaceID,proto3" json:"namespace_id,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *Alias) Reset() { *m = Alias{} } @@ -164,35 +179,122 @@ func (m *Alias) GetMetadata() map[string]string { return nil } +func (m *Alias) GetID() string { + if m != nil { + return m.ID + } + return "" +} + +func (m *Alias) GetNamespaceID() string { + if m != nil { + return m.NamespaceID + } + return "" +} + +type Group struct { + // ID is the unique identifier for the group + ID string `sentinel:"" protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"` + // Name is the human-friendly unique identifier for the group + Name string `sentinel:"" protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + // Metadata represents the custom data tied to this group + Metadata map[string]string `sentinel:"" 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"` + // NamespaceID is the identifier of the namespace to which this group + // belongs to. + NamespaceID string `sentinel:"" protobuf:"bytes,4,opt,name=namespace_id,json=namespaceID,proto3" json:"namespace_id,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Group) Reset() { *m = Group{} } +func (m *Group) String() string { return proto.CompactTextString(m) } +func (*Group) ProtoMessage() {} +func (*Group) Descriptor() ([]byte, []int) { + return fileDescriptor_4a34d35719c603a1, []int{2} +} + +func (m *Group) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Group.Unmarshal(m, b) +} +func (m *Group) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Group.Marshal(b, m, deterministic) +} +func (m *Group) XXX_Merge(src proto.Message) { + xxx_messageInfo_Group.Merge(m, src) +} +func (m *Group) XXX_Size() int { + return xxx_messageInfo_Group.Size(m) +} +func (m *Group) XXX_DiscardUnknown() { + xxx_messageInfo_Group.DiscardUnknown(m) +} + +var xxx_messageInfo_Group proto.InternalMessageInfo + +func (m *Group) GetID() string { + if m != nil { + return m.ID + } + return "" +} + +func (m *Group) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *Group) GetMetadata() map[string]string { + if m != nil { + return m.Metadata + } + return nil +} + +func (m *Group) GetNamespaceID() string { + if m != nil { + return m.NamespaceID + } + return "" +} + func init() { proto.RegisterType((*Entity)(nil), "logical.Entity") proto.RegisterMapType((map[string]string)(nil), "logical.Entity.MetadataEntry") proto.RegisterType((*Alias)(nil), "logical.Alias") proto.RegisterMapType((map[string]string)(nil), "logical.Alias.MetadataEntry") + proto.RegisterType((*Group)(nil), "logical.Group") + proto.RegisterMapType((map[string]string)(nil), "logical.Group.MetadataEntry") } func init() { proto.RegisterFile("sdk/logical/identity.proto", fileDescriptor_4a34d35719c603a1) } var fileDescriptor_4a34d35719c603a1 = []byte{ - // 310 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x92, 0xbf, 0x6a, 0xc3, 0x30, - 0x10, 0xc6, 0x91, 0x9d, 0xbf, 0x57, 0x12, 0x8a, 0xe8, 0x60, 0x42, 0x03, 0x21, 0xd0, 0xe2, 0xc9, - 0x86, 0x76, 0x49, 0xdb, 0x29, 0x25, 0x19, 0x32, 0x74, 0x31, 0x9d, 0xba, 0x94, 0x8b, 0x2d, 0x62, - 0x11, 0xd9, 0x32, 0x96, 0x1c, 0xf0, 0x9b, 0xf6, 0x19, 0xfa, 0x14, 0x25, 0xb2, 0x62, 0x12, 0x4a, - 0xa7, 0x6e, 0xba, 0xdf, 0x77, 0x77, 0xba, 0xfb, 0x38, 0x98, 0xa8, 0x64, 0x1f, 0x0a, 0xb9, 0xe3, - 0x31, 0x8a, 0x90, 0x27, 0x2c, 0xd7, 0x5c, 0xd7, 0x41, 0x51, 0x4a, 0x2d, 0x69, 0xdf, 0xf2, 0xf9, - 0x37, 0x81, 0xde, 0xda, 0x28, 0x74, 0x0c, 0xce, 0x66, 0xe5, 0x91, 0x19, 0xf1, 0x87, 0x91, 0xb3, - 0x59, 0x51, 0x0a, 0x9d, 0x1c, 0x33, 0xe6, 0x39, 0x86, 0x98, 0x37, 0xf5, 0xa1, 0x8f, 0x82, 0xa3, - 0x62, 0xca, 0x73, 0x67, 0xae, 0x7f, 0xf5, 0x30, 0x0e, 0x6c, 0xa7, 0x60, 0x79, 0xe4, 0xd1, 0x49, - 0xa6, 0x4f, 0x30, 0xc8, 0x98, 0xc6, 0x04, 0x35, 0x7a, 0x1d, 0x93, 0x3a, 0x6d, 0x53, 0x9b, 0x0f, - 0x83, 0x37, 0xab, 0xaf, 0x73, 0x5d, 0xd6, 0x51, 0x9b, 0x4e, 0x27, 0x30, 0x48, 0xb8, 0xc2, 0xad, - 0x60, 0x89, 0xd7, 0x9d, 0x11, 0x7f, 0x10, 0xb5, 0xf1, 0xe4, 0x05, 0x46, 0x17, 0x65, 0xf4, 0x1a, - 0xdc, 0x3d, 0xab, 0xed, 0xd8, 0xc7, 0x27, 0xbd, 0x81, 0xee, 0x01, 0x45, 0x75, 0x1a, 0xbc, 0x09, - 0x9e, 0x9d, 0x05, 0x99, 0x7f, 0x11, 0xe8, 0x9a, 0x31, 0xe9, 0x14, 0x20, 0x93, 0x55, 0xae, 0x3f, - 0x75, 0x5d, 0x30, 0x5b, 0x3c, 0x34, 0xe4, 0xbd, 0x2e, 0x18, 0xbd, 0x83, 0x71, 0x23, 0x63, 0x1c, - 0x33, 0xa5, 0x64, 0x69, 0x7b, 0x8d, 0x0c, 0x5d, 0x5a, 0xd8, 0x3a, 0xe4, 0x9e, 0x39, 0xb4, 0xf8, - 0xb5, 0xf7, 0xed, 0xa5, 0x45, 0x7f, 0xad, 0xfd, 0xaf, 0xd5, 0x5e, 0xfd, 0x8f, 0xfb, 0x1d, 0xd7, - 0x69, 0xb5, 0x0d, 0x62, 0x99, 0x85, 0x29, 0xaa, 0x94, 0xc7, 0xb2, 0x2c, 0xc2, 0x03, 0x56, 0x42, - 0x87, 0x67, 0x97, 0xb0, 0xed, 0x99, 0x0b, 0x78, 0xfc, 0x09, 0x00, 0x00, 0xff, 0xff, 0xfa, 0xa9, - 0x8a, 0x39, 0x1f, 0x02, 0x00, 0x00, + // 365 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x93, 0x4f, 0x6b, 0xfa, 0x30, + 0x18, 0xc7, 0x69, 0x6b, 0xfd, 0xf3, 0xf8, 0x53, 0x7e, 0x84, 0x1d, 0x8a, 0x4c, 0x70, 0xc2, 0x46, + 0x4f, 0x2d, 0x6c, 0x17, 0xb7, 0x9d, 0x1c, 0xca, 0xf0, 0xb0, 0x4b, 0xd9, 0x69, 0x17, 0x89, 0x4d, + 0xd0, 0x60, 0xdb, 0x94, 0x26, 0x15, 0xfa, 0x1a, 0xc6, 0x5e, 0xd6, 0xde, 0xd7, 0x30, 0x8d, 0xa5, + 0x3a, 0x84, 0x1d, 0xb6, 0x5b, 0xf2, 0x7d, 0x9e, 0x7e, 0x9b, 0xcf, 0x37, 0x79, 0x60, 0x20, 0xc8, + 0xd6, 0x8f, 0xf8, 0x9a, 0x85, 0x38, 0xf2, 0x19, 0xa1, 0x89, 0x64, 0xb2, 0xf0, 0xd2, 0x8c, 0x4b, + 0x8e, 0x5a, 0x5a, 0x1f, 0x7f, 0x98, 0xd0, 0x9c, 0xab, 0x0a, 0xea, 0x83, 0xb9, 0x98, 0x39, 0xc6, + 0xc8, 0x70, 0x3b, 0x81, 0xb9, 0x98, 0x21, 0x04, 0x8d, 0x04, 0xc7, 0xd4, 0x31, 0x95, 0xa2, 0xd6, + 0xc8, 0x85, 0x16, 0x8e, 0x18, 0x16, 0x54, 0x38, 0xd6, 0xc8, 0x72, 0xbb, 0xb7, 0x7d, 0x4f, 0x3b, + 0x79, 0xd3, 0xbd, 0x1e, 0x1c, 0xca, 0xe8, 0x1e, 0xda, 0x31, 0x95, 0x98, 0x60, 0x89, 0x9d, 0x86, + 0x6a, 0x1d, 0x56, 0xad, 0xe5, 0x0f, 0xbd, 0x17, 0x5d, 0x9f, 0x27, 0x32, 0x2b, 0x82, 0xaa, 0x1d, + 0x0d, 0xa0, 0x4d, 0x98, 0xc0, 0xab, 0x88, 0x12, 0xc7, 0x1e, 0x19, 0x6e, 0x3b, 0xa8, 0xf6, 0xe8, + 0x0a, 0xfe, 0xed, 0x0f, 0x22, 0x52, 0x1c, 0xd2, 0x25, 0x23, 0x4e, 0x53, 0x1d, 0xae, 0x5b, 0x69, + 0x0b, 0x32, 0x78, 0x84, 0xde, 0x91, 0x33, 0xfa, 0x0f, 0xd6, 0x96, 0x16, 0x9a, 0x6c, 0xbf, 0x44, + 0x17, 0x60, 0xef, 0x70, 0x94, 0x1f, 0xd8, 0xca, 0xcd, 0x83, 0x39, 0x31, 0xc6, 0xef, 0x26, 0xd8, + 0x8a, 0x04, 0x0d, 0x01, 0x62, 0x9e, 0x27, 0x72, 0x29, 0x8b, 0x94, 0xea, 0x8f, 0x3b, 0x4a, 0x79, + 0x2d, 0x52, 0x8a, 0xae, 0xa1, 0x5f, 0x96, 0x71, 0x18, 0x52, 0x21, 0x78, 0xa6, 0xbd, 0x7a, 0x4a, + 0x9d, 0x6a, 0xb1, 0x0a, 0xd1, 0xaa, 0x85, 0x38, 0xf9, 0x16, 0xcd, 0xe5, 0x71, 0x8a, 0x67, 0x93, + 0x29, 0xaf, 0xc8, 0xae, 0xae, 0xe8, 0xaf, 0xd3, 0xf8, 0x34, 0xc0, 0x7e, 0xce, 0x78, 0x9e, 0xfe, + 0xe8, 0x71, 0xd4, 0xb9, 0xac, 0x13, 0x2e, 0xe5, 0x72, 0x96, 0xeb, 0x94, 0xa3, 0xf1, 0xbb, 0x1c, + 0x4f, 0xee, 0xdb, 0xcd, 0x9a, 0xc9, 0x4d, 0xbe, 0xf2, 0x42, 0x1e, 0xfb, 0x1b, 0x2c, 0x36, 0x2c, + 0xe4, 0x59, 0xea, 0xef, 0x70, 0x1e, 0x49, 0xbf, 0x36, 0x27, 0xab, 0xa6, 0x9a, 0x8f, 0xbb, 0xaf, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xa8, 0xe2, 0x28, 0xc0, 0x3d, 0x03, 0x00, 0x00, } diff --git a/sdk/logical/identity.proto b/sdk/logical/identity.proto index 65e27435f08d..75d3f60a2641 100644 --- a/sdk/logical/identity.proto +++ b/sdk/logical/identity.proto @@ -19,6 +19,10 @@ message Entity { // Disabled is true if the entity is disabled. bool disabled = 5; + + // NamespaceID is the identifier of the namespace to which this entity + // belongs to. + string namespace_id = 6; } message Alias { @@ -34,4 +38,26 @@ message Alias { // Metadata represents the custom data tied to this alias map metadata = 4; + + // ID is the unique identifier for the alias + string ID = 5; + + // NamespaceID is the identifier of the namespace to which this alias + // belongs. + string namespace_id = 6; } + +message Group { + // ID is the unique identifier for the group + string ID = 1; + + // Name is the human-friendly unique identifier for the group + string name = 2; + + // Metadata represents the custom data tied to this group + map metadata = 3; + + // NamespaceID is the identifier of the namespace to which this group + // belongs to. + string namespace_id = 4; +} diff --git a/sdk/logical/system_view.go b/sdk/logical/system_view.go index ef88a4322949..2c5d9c3bed07 100644 --- a/sdk/logical/system_view.go +++ b/sdk/logical/system_view.go @@ -62,6 +62,10 @@ type SystemView interface { // for the given entity id EntityInfo(entityID string) (*Entity, error) + // GroupsForEntity returns the group membership information for the provided + // entity id + GroupsForEntity(entityID string) ([]*Group, error) + // PluginEnv returns Vault environment information used by plugins PluginEnv(context.Context) (*PluginEnvironment, error) } @@ -82,6 +86,7 @@ type StaticSystemView struct { LocalMountVal bool ReplicationStateVal consts.ReplicationState EntityVal *Entity + GroupsVal []*Group Features license.Features VaultVersion string PluginEnvironment *PluginEnvironment @@ -149,6 +154,10 @@ func (d StaticSystemView) EntityInfo(entityID string) (*Entity, error) { return d.EntityVal, nil } +func (d StaticSystemView) GroupsForEntity(entityID string) ([]*Group, error) { + return d.GroupsVal, nil +} + func (d StaticSystemView) HasFeature(feature license.Features) bool { return d.Features.HasFeature(feature) } diff --git a/sdk/plugin/grpc_system.go b/sdk/plugin/grpc_system.go index 9047baff41d3..6e27c9b96360 100644 --- a/sdk/plugin/grpc_system.go +++ b/sdk/plugin/grpc_system.go @@ -138,6 +138,20 @@ func (s *gRPCSystemViewClient) EntityInfo(entityID string) (*logical.Entity, err return reply.Entity, nil } +func (s *gRPCSystemViewClient) GroupsForEntity(entityID string) ([]*logical.Group, error) { + reply, err := s.client.GroupsForEntity(context.Background(), &pb.EntityInfoArgs{ + EntityID: entityID, + }) + if err != nil { + return nil, err + } + if reply.Err != "" { + return nil, errors.New(reply.Err) + } + + return reply.Groups, nil +} + func (s *gRPCSystemViewClient) PluginEnv(ctx context.Context) (*logical.PluginEnvironment, error) { reply, err := s.client.PluginEnv(ctx, &pb.Empty{}) if err != nil { @@ -237,6 +251,18 @@ func (s *gRPCSystemViewServer) EntityInfo(ctx context.Context, args *pb.EntityIn }, nil } +func (s *gRPCSystemViewServer) GroupsForEntity(ctx context.Context, args *pb.EntityInfoArgs) (*pb.GroupsForEntityReply, error) { + groups, err := s.impl.GroupsForEntity(args.EntityID) + if err != nil { + return &pb.GroupsForEntityReply{ + Err: pb.ErrToString(err), + }, nil + } + return &pb.GroupsForEntityReply{ + Groups: groups, + }, nil +} + func (s *gRPCSystemViewServer) PluginEnv(ctx context.Context, _ *pb.Empty) (*pb.PluginEnvReply, error) { pluginEnv, err := s.impl.PluginEnv(ctx) if err != nil { diff --git a/sdk/plugin/grpc_system_test.go b/sdk/plugin/grpc_system_test.go index e3af218cf120..748cec1d137c 100644 --- a/sdk/plugin/grpc_system_test.go +++ b/sdk/plugin/grpc_system_test.go @@ -183,6 +183,34 @@ func TestSystem_GRPC_entityInfo(t *testing.T) { } } +func TestSystem_GRPC_groupsForEntity(t *testing.T) { + sys := logical.TestSystemView() + sys.GroupsVal = []*logical.Group{ + { + ID: "group1-id", + Name: "group1", + Metadata: map[string]string{ + "group-metadata": "metadata-value", + }, + }, + } + client, _ := plugin.TestGRPCConn(t, func(s *grpc.Server) { + pb.RegisterSystemViewServer(s, &gRPCSystemViewServer{ + impl: sys, + }) + }) + defer client.Close() + testSystemView := newGRPCSystemView(client) + + actual, err := testSystemView.GroupsForEntity("") + if err != nil { + t.Fatal(err) + } + if !proto.Equal(sys.GroupsVal[0], actual[0]) { + t.Fatalf("expected: %v, got: %v", sys.GroupsVal, actual) + } +} + func TestSystem_GRPC_pluginEnv(t *testing.T) { sys := logical.TestSystemView() sys.PluginEnvironment = &logical.PluginEnvironment{ diff --git a/sdk/plugin/pb/backend.pb.go b/sdk/plugin/pb/backend.pb.go index 566bf63f433c..8c7f57c1025e 100644 --- a/sdk/plugin/pb/backend.pb.go +++ b/sdk/plugin/pb/backend.pb.go @@ -2568,6 +2568,53 @@ func (m *EntityInfoReply) GetErr() string { return "" } +type GroupsForEntityReply struct { + Groups []*logical.Group `sentinel:"" protobuf:"bytes,1,rep,name=groups,proto3" json:"groups,omitempty"` + Err string `sentinel:"" protobuf:"bytes,2,opt,name=err,proto3" json:"err,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GroupsForEntityReply) Reset() { *m = GroupsForEntityReply{} } +func (m *GroupsForEntityReply) String() string { return proto.CompactTextString(m) } +func (*GroupsForEntityReply) ProtoMessage() {} +func (*GroupsForEntityReply) Descriptor() ([]byte, []int) { + return fileDescriptor_4dbf1dfe0c11846b, []int{42} +} + +func (m *GroupsForEntityReply) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GroupsForEntityReply.Unmarshal(m, b) +} +func (m *GroupsForEntityReply) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GroupsForEntityReply.Marshal(b, m, deterministic) +} +func (m *GroupsForEntityReply) XXX_Merge(src proto.Message) { + xxx_messageInfo_GroupsForEntityReply.Merge(m, src) +} +func (m *GroupsForEntityReply) XXX_Size() int { + return xxx_messageInfo_GroupsForEntityReply.Size(m) +} +func (m *GroupsForEntityReply) XXX_DiscardUnknown() { + xxx_messageInfo_GroupsForEntityReply.DiscardUnknown(m) +} + +var xxx_messageInfo_GroupsForEntityReply proto.InternalMessageInfo + +func (m *GroupsForEntityReply) GetGroups() []*logical.Group { + if m != nil { + return m.Groups + } + return nil +} + +func (m *GroupsForEntityReply) GetErr() string { + if m != nil { + return m.Err + } + return "" +} + type PluginEnvReply struct { PluginEnvironment *logical.PluginEnvironment `sentinel:"" protobuf:"bytes,1,opt,name=plugin_environment,json=pluginEnvironment,proto3" json:"plugin_environment,omitempty"` Err string `sentinel:"" protobuf:"bytes,2,opt,name=err,proto3" json:"err,omitempty"` @@ -2580,7 +2627,7 @@ func (m *PluginEnvReply) Reset() { *m = PluginEnvReply{} } func (m *PluginEnvReply) String() string { return proto.CompactTextString(m) } func (*PluginEnvReply) ProtoMessage() {} func (*PluginEnvReply) Descriptor() ([]byte, []int) { - return fileDescriptor_4dbf1dfe0c11846b, []int{42} + return fileDescriptor_4dbf1dfe0c11846b, []int{43} } func (m *PluginEnvReply) XXX_Unmarshal(b []byte) error { @@ -2627,7 +2674,7 @@ func (m *Connection) Reset() { *m = Connection{} } func (m *Connection) String() string { return proto.CompactTextString(m) } func (*Connection) ProtoMessage() {} func (*Connection) Descriptor() ([]byte, []int) { - return fileDescriptor_4dbf1dfe0c11846b, []int{43} + return fileDescriptor_4dbf1dfe0c11846b, []int{44} } func (m *Connection) XXX_Unmarshal(b []byte) error { @@ -2703,6 +2750,7 @@ func init() { proto.RegisterType((*LocalMountReply)(nil), "pb.LocalMountReply") proto.RegisterType((*EntityInfoArgs)(nil), "pb.EntityInfoArgs") proto.RegisterType((*EntityInfoReply)(nil), "pb.EntityInfoReply") + proto.RegisterType((*GroupsForEntityReply)(nil), "pb.GroupsForEntityReply") proto.RegisterType((*PluginEnvReply)(nil), "pb.PluginEnvReply") proto.RegisterType((*Connection)(nil), "pb.Connection") } @@ -2710,164 +2758,167 @@ func init() { func init() { proto.RegisterFile("sdk/plugin/pb/backend.proto", fileDescriptor_4dbf1dfe0c11846b) } var fileDescriptor_4dbf1dfe0c11846b = []byte{ - // 2504 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x59, 0xcd, 0x72, 0x1b, 0xc7, - 0x11, 0x2e, 0x00, 0xc4, 0x5f, 0xe3, 0x7f, 0x48, 0x2b, 0x2b, 0x48, 0x8e, 0xe8, 0x75, 0x24, 0xd3, - 0x8c, 0x0d, 0x5a, 0x54, 0x14, 0xcb, 0x49, 0x25, 0x29, 0x9a, 0xa2, 0x65, 0xc6, 0xa4, 0xcd, 0x5a, - 0x42, 0x71, 0xfe, 0xaa, 0xe0, 0xc1, 0xee, 0x10, 0xdc, 0xe2, 0x62, 0x77, 0x33, 0x3b, 0x4b, 0x11, - 0xb9, 0xe4, 0x96, 0x47, 0xc8, 0x1b, 0xe4, 0x9c, 0x6b, 0x6e, 0xb9, 0xba, 0x72, 0xcf, 0x2b, 0xe4, - 0x39, 0x52, 0xd3, 0x33, 0xfb, 0x07, 0x80, 0xb6, 0x5c, 0xe5, 0xdc, 0x76, 0xba, 0x7b, 0x7a, 0x66, - 0x7a, 0xbe, 0xfe, 0xba, 0x07, 0x80, 0x7b, 0x91, 0x73, 0xb5, 0x17, 0x7a, 0xf1, 0xcc, 0xf5, 0xf7, - 0xc2, 0xe9, 0xde, 0x94, 0xda, 0x57, 0xcc, 0x77, 0x46, 0x21, 0x0f, 0x44, 0x40, 0xca, 0xe1, 0x74, - 0xf8, 0x60, 0x16, 0x04, 0x33, 0x8f, 0xed, 0xa1, 0x64, 0x1a, 0x5f, 0xec, 0x09, 0x77, 0xce, 0x22, - 0x41, 0xe7, 0xa1, 0x32, 0x1a, 0x0e, 0xa5, 0x07, 0x2f, 0x98, 0xb9, 0x36, 0xf5, 0xf6, 0x5c, 0x87, - 0xf9, 0xc2, 0x15, 0x0b, 0xad, 0x33, 0xf2, 0x3a, 0xb5, 0x8a, 0xd2, 0x98, 0x75, 0xa8, 0x1e, 0xcd, - 0x43, 0xb1, 0x30, 0xb7, 0xa1, 0xf6, 0x29, 0xa3, 0x0e, 0xe3, 0xe4, 0x0e, 0xd4, 0x2e, 0xf1, 0xcb, - 0x28, 0x6d, 0x57, 0x76, 0x9a, 0x96, 0x1e, 0x99, 0x7f, 0x00, 0x38, 0x93, 0x73, 0x8e, 0x38, 0x0f, - 0x38, 0xb9, 0x0b, 0x0d, 0xc6, 0xf9, 0x44, 0x2c, 0x42, 0x66, 0x94, 0xb6, 0x4b, 0x3b, 0x1d, 0xab, - 0xce, 0x38, 0x1f, 0x2f, 0x42, 0x46, 0x7e, 0x00, 0xf2, 0x73, 0x32, 0x8f, 0x66, 0x46, 0x79, 0xbb, - 0x24, 0x3d, 0x30, 0xce, 0x4f, 0xa3, 0x59, 0x32, 0xc7, 0x0e, 0x1c, 0x66, 0x54, 0xb6, 0x4b, 0x3b, - 0x15, 0x9c, 0x73, 0x18, 0x38, 0xcc, 0xfc, 0x5b, 0x09, 0xaa, 0x67, 0x54, 0x5c, 0x46, 0x84, 0xc0, - 0x06, 0x0f, 0x02, 0xa1, 0x17, 0xc7, 0x6f, 0xb2, 0x03, 0xbd, 0xd8, 0xa7, 0xb1, 0xb8, 0x94, 0xa7, - 0xb2, 0xa9, 0x60, 0x8e, 0x51, 0x46, 0xf5, 0xb2, 0x98, 0xbc, 0x0d, 0x1d, 0x2f, 0xb0, 0xa9, 0x37, - 0x89, 0x44, 0xc0, 0xe9, 0x4c, 0xae, 0x23, 0xed, 0xda, 0x28, 0x3c, 0x57, 0x32, 0xb2, 0x0b, 0x83, - 0x88, 0x51, 0x6f, 0xf2, 0x8a, 0xd3, 0x30, 0x35, 0xdc, 0x50, 0x0e, 0xa5, 0xe2, 0x4b, 0x4e, 0x43, - 0x6d, 0x6b, 0xfe, 0xab, 0x06, 0x75, 0x8b, 0xfd, 0x29, 0x66, 0x91, 0x20, 0x5d, 0x28, 0xbb, 0x0e, - 0x9e, 0xb6, 0x69, 0x95, 0x5d, 0x87, 0x8c, 0x80, 0x58, 0x2c, 0xf4, 0xe4, 0xd2, 0x6e, 0xe0, 0x1f, - 0x7a, 0x71, 0x24, 0x18, 0xd7, 0x67, 0x5e, 0xa3, 0x21, 0xf7, 0xa1, 0x19, 0x84, 0x8c, 0xa3, 0x0c, - 0x03, 0xd0, 0xb4, 0x32, 0x81, 0x3c, 0x78, 0x48, 0xc5, 0xa5, 0xb1, 0x81, 0x0a, 0xfc, 0x96, 0x32, - 0x87, 0x0a, 0x6a, 0x54, 0x95, 0x4c, 0x7e, 0x13, 0x13, 0x6a, 0x11, 0xb3, 0x39, 0x13, 0x46, 0x6d, - 0xbb, 0xb4, 0xd3, 0xda, 0x87, 0x51, 0x38, 0x1d, 0x9d, 0xa3, 0xc4, 0xd2, 0x1a, 0x72, 0x1f, 0x36, - 0x64, 0x5c, 0x8c, 0x3a, 0x5a, 0x34, 0xa4, 0xc5, 0x41, 0x2c, 0x2e, 0x2d, 0x94, 0x92, 0x7d, 0xa8, - 0xab, 0x3b, 0x8d, 0x8c, 0xc6, 0x76, 0x65, 0xa7, 0xb5, 0x6f, 0x48, 0x03, 0x7d, 0xca, 0x91, 0x82, - 0x41, 0x74, 0xe4, 0x0b, 0xbe, 0xb0, 0x12, 0x43, 0xf2, 0x16, 0xb4, 0x6d, 0xcf, 0x65, 0xbe, 0x98, - 0x88, 0xe0, 0x8a, 0xf9, 0x46, 0x13, 0x77, 0xd4, 0x52, 0xb2, 0xb1, 0x14, 0x91, 0x7d, 0x78, 0x23, - 0x6f, 0x32, 0xa1, 0xb6, 0xcd, 0xa2, 0x28, 0xe0, 0x06, 0xa0, 0xed, 0x66, 0xce, 0xf6, 0x40, 0xab, - 0xa4, 0x5b, 0xc7, 0x8d, 0x42, 0x8f, 0x2e, 0x26, 0x3e, 0x9d, 0x33, 0xa3, 0xa5, 0xdc, 0x6a, 0xd9, - 0xe7, 0x74, 0xce, 0xc8, 0x03, 0x68, 0xcd, 0x83, 0xd8, 0x17, 0x93, 0x30, 0x70, 0x7d, 0x61, 0xb4, - 0xd1, 0x02, 0x50, 0x74, 0x26, 0x25, 0xe4, 0x4d, 0x50, 0x23, 0x05, 0xc6, 0x8e, 0x8a, 0x2b, 0x4a, - 0x10, 0x8e, 0x0f, 0xa1, 0xab, 0xd4, 0xe9, 0x7e, 0xba, 0x68, 0xd2, 0x41, 0x69, 0xba, 0x93, 0x0f, - 0xa0, 0x89, 0x78, 0x70, 0xfd, 0x8b, 0xc0, 0xe8, 0x61, 0xdc, 0x36, 0x73, 0x61, 0x91, 0x98, 0x38, - 0xf6, 0x2f, 0x02, 0xab, 0xf1, 0x4a, 0x7f, 0x91, 0x5f, 0xc0, 0xbd, 0xc2, 0x79, 0x39, 0x9b, 0x53, - 0xd7, 0x77, 0xfd, 0xd9, 0x24, 0x8e, 0x58, 0x64, 0xf4, 0x11, 0xe1, 0x46, 0xee, 0xd4, 0x56, 0x62, - 0xf0, 0x32, 0x62, 0x11, 0xb9, 0x07, 0x4d, 0x95, 0xa4, 0x13, 0xd7, 0x31, 0x06, 0xb8, 0xa5, 0x86, - 0x12, 0x1c, 0x3b, 0xe4, 0x1d, 0xe8, 0x85, 0x81, 0xe7, 0xda, 0x8b, 0x49, 0x70, 0xcd, 0x38, 0x77, - 0x1d, 0x66, 0x90, 0xed, 0xd2, 0x4e, 0xc3, 0xea, 0x2a, 0xf1, 0x17, 0x5a, 0xba, 0x2e, 0x35, 0x36, - 0xd1, 0x70, 0x25, 0x35, 0x46, 0x00, 0x76, 0xe0, 0xfb, 0xcc, 0x46, 0xf8, 0x6d, 0xe1, 0x09, 0xbb, - 0xf2, 0x84, 0x87, 0xa9, 0xd4, 0xca, 0x59, 0x0c, 0x3f, 0x81, 0x76, 0x1e, 0x0a, 0xa4, 0x0f, 0x95, - 0x2b, 0xb6, 0xd0, 0xf0, 0x97, 0x9f, 0x64, 0x1b, 0xaa, 0xd7, 0xd4, 0x8b, 0x19, 0x42, 0x5e, 0x03, - 0x51, 0x4d, 0xb1, 0x94, 0xe2, 0x67, 0xe5, 0x67, 0x25, 0xf3, 0xbf, 0x55, 0xd8, 0x90, 0xe0, 0x23, - 0x4f, 0xa1, 0xe3, 0x31, 0x1a, 0xb1, 0x49, 0x10, 0xca, 0x05, 0x22, 0x74, 0xd5, 0xda, 0xef, 0xcb, - 0x69, 0x27, 0x52, 0xf1, 0x85, 0x92, 0x5b, 0x6d, 0x2f, 0x37, 0x92, 0x29, 0xed, 0xfa, 0x82, 0x71, - 0x9f, 0x7a, 0x13, 0x4c, 0x06, 0x95, 0x60, 0xed, 0x44, 0xf8, 0x5c, 0x26, 0xc5, 0x32, 0x8e, 0x2a, - 0xab, 0x38, 0x1a, 0x42, 0x03, 0x63, 0xe7, 0xb2, 0x48, 0x27, 0x7b, 0x3a, 0x26, 0xfb, 0xd0, 0x98, - 0x33, 0x41, 0x75, 0xae, 0xc9, 0x94, 0xb8, 0x93, 0xe4, 0xcc, 0xe8, 0x54, 0x2b, 0x54, 0x42, 0xa4, - 0x76, 0x2b, 0x19, 0x51, 0x5b, 0xcd, 0x88, 0x21, 0x34, 0x52, 0xd0, 0xd5, 0xd5, 0x0d, 0x27, 0x63, - 0x49, 0xb3, 0x21, 0xe3, 0x6e, 0xe0, 0x18, 0x0d, 0x04, 0x8a, 0x1e, 0x49, 0x92, 0xf4, 0xe3, 0xb9, - 0x82, 0x50, 0x53, 0x91, 0xa4, 0x1f, 0xcf, 0x57, 0x11, 0x03, 0x4b, 0x88, 0xf9, 0x11, 0x54, 0xa9, - 0xe7, 0xd2, 0x08, 0x53, 0x48, 0xde, 0xac, 0xe6, 0xfb, 0xd1, 0x81, 0x94, 0x5a, 0x4a, 0x49, 0x9e, - 0x40, 0x67, 0xc6, 0x83, 0x38, 0x9c, 0xe0, 0x90, 0x45, 0x46, 0x1b, 0x4f, 0xbb, 0x6c, 0xdd, 0x46, - 0xa3, 0x03, 0x65, 0x23, 0x33, 0x70, 0x1a, 0xc4, 0xbe, 0x33, 0xb1, 0x5d, 0x87, 0x47, 0x46, 0x07, - 0x83, 0x07, 0x28, 0x3a, 0x94, 0x12, 0x99, 0x62, 0x2a, 0x05, 0xd2, 0x00, 0x77, 0xd1, 0xa6, 0x83, - 0xd2, 0xb3, 0x24, 0xca, 0x3f, 0x86, 0x41, 0x52, 0x98, 0x32, 0xcb, 0x1e, 0x5a, 0xf6, 0x13, 0x45, - 0x6a, 0xbc, 0x03, 0x7d, 0x76, 0x23, 0x29, 0xd4, 0x15, 0x93, 0x39, 0xbd, 0x99, 0x08, 0xe1, 0xe9, - 0x94, 0xea, 0x26, 0xf2, 0x53, 0x7a, 0x33, 0x16, 0x9e, 0xcc, 0x7f, 0xb5, 0x3a, 0xe6, 0xff, 0x00, - 0x8b, 0x51, 0x13, 0x25, 0x98, 0xff, 0xbb, 0x30, 0xf0, 0x83, 0x89, 0xc3, 0x2e, 0x68, 0xec, 0x09, - 0xb5, 0xee, 0x42, 0x27, 0x53, 0xcf, 0x0f, 0x9e, 0x2b, 0x39, 0x2e, 0xbb, 0x18, 0xfe, 0x1c, 0x3a, - 0x85, 0xeb, 0x5e, 0x03, 0xfa, 0xad, 0x3c, 0xe8, 0x9b, 0x79, 0xa0, 0xff, 0x7b, 0x03, 0x00, 0xef, - 0x5d, 0x4d, 0x5d, 0xae, 0x16, 0x79, 0x30, 0x94, 0xd7, 0x80, 0x81, 0x72, 0xe6, 0x0b, 0x0d, 0x5c, - 0x3d, 0xfa, 0x46, 0xcc, 0x26, 0xf5, 0xa2, 0x9a, 0xab, 0x17, 0xef, 0xc1, 0x86, 0xc4, 0xa7, 0x51, - 0xcb, 0x68, 0x3d, 0xdb, 0x11, 0x22, 0x59, 0xa1, 0x18, 0xad, 0x56, 0x92, 0xa6, 0xbe, 0x9a, 0x34, - 0x79, 0x34, 0x36, 0x8a, 0x68, 0x7c, 0x1b, 0x3a, 0x36, 0x67, 0x58, 0xbb, 0x26, 0xb2, 0x19, 0xd1, - 0x68, 0x6d, 0x27, 0xc2, 0xb1, 0x3b, 0x67, 0x32, 0x7e, 0xf2, 0xe2, 0x00, 0x55, 0xf2, 0x73, 0xed, - 0xbd, 0xb6, 0xd6, 0xde, 0x2b, 0x76, 0x02, 0x1e, 0xd3, 0x8c, 0x8f, 0xdf, 0xb9, 0xac, 0xe9, 0x14, - 0xb2, 0xa6, 0x90, 0x1a, 0xdd, 0xa5, 0xd4, 0x58, 0xc2, 0x6f, 0x6f, 0x05, 0xbf, 0x6f, 0x41, 0x5b, - 0x06, 0x20, 0x0a, 0xa9, 0xcd, 0xa4, 0x83, 0xbe, 0x0a, 0x44, 0x2a, 0x3b, 0x76, 0x30, 0xdb, 0xe3, - 0xe9, 0x74, 0x71, 0x19, 0x78, 0x2c, 0x23, 0xec, 0x56, 0x2a, 0x3b, 0x76, 0xe4, 0x7e, 0x11, 0x81, - 0x04, 0x11, 0x88, 0xdf, 0xc3, 0x0f, 0xa1, 0x99, 0x46, 0xfd, 0x3b, 0x81, 0xe9, 0x1f, 0x25, 0x68, - 0xe7, 0x49, 0x51, 0x4e, 0x1e, 0x8f, 0x4f, 0x70, 0x72, 0xc5, 0x92, 0x9f, 0xb2, 0x9d, 0xe0, 0xcc, - 0x67, 0xaf, 0xe8, 0xd4, 0x53, 0x0e, 0x1a, 0x56, 0x26, 0x90, 0x5a, 0xd7, 0xb7, 0x39, 0x9b, 0x27, - 0xa8, 0xaa, 0x58, 0x99, 0x80, 0x7c, 0x04, 0xe0, 0x46, 0x51, 0xcc, 0xd4, 0xcd, 0x6d, 0x20, 0x65, - 0x0c, 0x47, 0xaa, 0xc7, 0x1c, 0x25, 0x3d, 0xe6, 0x68, 0x9c, 0xf4, 0x98, 0x56, 0x13, 0xad, 0xf1, - 0x4a, 0xef, 0x40, 0x4d, 0x5e, 0xd0, 0xf8, 0x04, 0x91, 0x57, 0xb1, 0xf4, 0xc8, 0xfc, 0x0b, 0xd4, - 0x54, 0x17, 0xf2, 0x7f, 0x25, 0xfa, 0xbb, 0xd0, 0x50, 0xbe, 0x5d, 0x47, 0xe7, 0x4a, 0x1d, 0xc7, - 0xc7, 0x8e, 0xf9, 0x75, 0x19, 0x1a, 0x16, 0x8b, 0xc2, 0xc0, 0x8f, 0x58, 0xae, 0x4b, 0x2a, 0x7d, - 0x6b, 0x97, 0x54, 0x5e, 0xdb, 0x25, 0x25, 0xbd, 0x57, 0x25, 0xd7, 0x7b, 0x0d, 0xa1, 0xc1, 0x99, - 0xe3, 0x72, 0x66, 0x0b, 0xdd, 0xa7, 0xa5, 0x63, 0xa9, 0x7b, 0x45, 0xb9, 0x2c, 0xef, 0x11, 0xd6, - 0x90, 0xa6, 0x95, 0x8e, 0xc9, 0xe3, 0x7c, 0x73, 0xa1, 0xda, 0xb6, 0x2d, 0xd5, 0x5c, 0xa8, 0xed, - 0xae, 0xe9, 0x2e, 0x9e, 0x64, 0x4d, 0x5a, 0x1d, 0xb3, 0xf9, 0x6e, 0x7e, 0xc2, 0xfa, 0x2e, 0xed, - 0x7b, 0xab, 0xd9, 0x5f, 0x97, 0xa1, 0xbf, 0xbc, 0xb7, 0x35, 0x08, 0xdc, 0x82, 0xaa, 0xaa, 0x7d, - 0x1a, 0xbe, 0x62, 0xa5, 0xea, 0x55, 0x96, 0x88, 0xee, 0x57, 0xcb, 0xa4, 0xf1, 0xed, 0xd0, 0x2b, - 0x12, 0xca, 0xbb, 0xd0, 0x97, 0x21, 0x0a, 0x99, 0x93, 0xf5, 0x73, 0x8a, 0x01, 0x7b, 0x5a, 0x9e, - 0x76, 0x74, 0xbb, 0x30, 0x48, 0x4c, 0x33, 0x6e, 0xa8, 0x15, 0x6c, 0x8f, 0x12, 0x8a, 0xb8, 0x03, - 0xb5, 0x8b, 0x80, 0xcf, 0xa9, 0xd0, 0x24, 0xa8, 0x47, 0x05, 0x92, 0x43, 0xb6, 0x6d, 0x28, 0x4c, - 0x26, 0x42, 0xf9, 0x66, 0x91, 0xe4, 0x93, 0xbe, 0x27, 0x90, 0x05, 0x1b, 0x56, 0x23, 0x79, 0x47, - 0x98, 0xbf, 0x85, 0xde, 0x52, 0x0b, 0xb9, 0x26, 0x90, 0xd9, 0xf2, 0xe5, 0xc2, 0xf2, 0x05, 0xcf, - 0x95, 0x25, 0xcf, 0xbf, 0x83, 0xc1, 0xa7, 0xd4, 0x77, 0x3c, 0xa6, 0xfd, 0x1f, 0xf0, 0x59, 0x24, - 0x8b, 0xa1, 0x7e, 0xd1, 0x4c, 0x74, 0xf5, 0xe9, 0x58, 0x4d, 0x2d, 0x39, 0x76, 0xc8, 0x43, 0xa8, - 0x73, 0x65, 0xad, 0x01, 0xd0, 0xca, 0xf5, 0xb8, 0x56, 0xa2, 0x33, 0xbf, 0x02, 0x52, 0x70, 0x2d, - 0x1f, 0x33, 0x0b, 0xb2, 0x23, 0xd1, 0xaf, 0x40, 0xa1, 0xb3, 0xaa, 0x9d, 0xc7, 0xa4, 0x95, 0x6a, - 0xc9, 0x36, 0x54, 0x18, 0xe7, 0x7a, 0x09, 0x6c, 0x32, 0xb3, 0xa7, 0xa3, 0x25, 0x55, 0x66, 0x1f, - 0xba, 0xc7, 0xbe, 0x2b, 0x5c, 0xea, 0xb9, 0x7f, 0x66, 0x72, 0xe7, 0xe6, 0x13, 0xe8, 0x65, 0x12, - 0xb5, 0xa0, 0x76, 0x53, 0xba, 0xdd, 0xcd, 0x4f, 0x60, 0x70, 0x1e, 0x32, 0xdb, 0xa5, 0x1e, 0xbe, - 0x1e, 0xd5, 0xb4, 0x07, 0x50, 0x95, 0x77, 0x95, 0xf0, 0x4e, 0x13, 0x27, 0xa2, 0x5a, 0xc9, 0xcd, - 0xaf, 0xc0, 0x50, 0xc7, 0x3b, 0xba, 0x71, 0x23, 0xc1, 0x7c, 0x9b, 0x1d, 0x5e, 0x32, 0xfb, 0xea, - 0x7b, 0x0c, 0xe0, 0x35, 0xdc, 0x5d, 0xb7, 0x42, 0xb2, 0xbf, 0x96, 0x2d, 0x47, 0x93, 0x0b, 0x59, - 0x82, 0x70, 0x8d, 0x86, 0x05, 0x28, 0xfa, 0x44, 0x4a, 0x24, 0x1c, 0x98, 0x9c, 0x17, 0x69, 0x5a, - 0xd7, 0xa3, 0x24, 0x1e, 0x95, 0xdb, 0xe3, 0xf1, 0xcf, 0x12, 0x34, 0xcf, 0x99, 0x88, 0x43, 0x3c, - 0xcb, 0x3d, 0x68, 0x4e, 0x79, 0x70, 0xc5, 0x78, 0x76, 0x94, 0x86, 0x12, 0x1c, 0x3b, 0xe4, 0x31, - 0xd4, 0x0e, 0x03, 0xff, 0xc2, 0x9d, 0xe1, 0x5b, 0x5a, 0xf3, 0x4b, 0x3a, 0x77, 0xa4, 0x74, 0x8a, - 0x5f, 0xb4, 0x21, 0xd9, 0x86, 0x96, 0xfe, 0x65, 0xe2, 0xe5, 0xcb, 0xe3, 0xe7, 0x49, 0x93, 0x9d, - 0x13, 0x0d, 0x3f, 0x82, 0x56, 0x6e, 0xe2, 0x77, 0xaa, 0x78, 0x3f, 0x04, 0xc0, 0xd5, 0x55, 0x8c, - 0xfa, 0xd9, 0xd5, 0x37, 0xd5, 0xd1, 0x1e, 0x40, 0x53, 0xf6, 0x73, 0x4a, 0x9d, 0xd4, 0xda, 0x52, - 0x56, 0x6b, 0xcd, 0x87, 0x30, 0x38, 0xf6, 0xaf, 0xa9, 0xe7, 0x3a, 0x54, 0xb0, 0xcf, 0xd8, 0x02, - 0x43, 0xb0, 0xb2, 0x03, 0xf3, 0x1c, 0xda, 0xfa, 0x71, 0xff, 0x5a, 0x7b, 0x6c, 0xeb, 0x3d, 0x7e, - 0x73, 0x2e, 0xbe, 0x0b, 0x3d, 0xed, 0xf4, 0xc4, 0xd5, 0x99, 0x28, 0x5b, 0x15, 0xce, 0x2e, 0xdc, - 0x1b, 0xed, 0x5a, 0x8f, 0xcc, 0x67, 0xd0, 0xcf, 0x99, 0xa6, 0xc7, 0xb9, 0x62, 0x8b, 0x28, 0xf9, - 0xd1, 0x43, 0x7e, 0x27, 0x11, 0x28, 0x67, 0x11, 0x30, 0xa1, 0xab, 0x67, 0xbe, 0x60, 0xe2, 0x96, - 0xd3, 0x7d, 0x96, 0x6e, 0xe4, 0x05, 0xd3, 0xce, 0x1f, 0x41, 0x95, 0xc9, 0x93, 0xe6, 0xcb, 0x70, - 0x3e, 0x02, 0x96, 0x52, 0xaf, 0x59, 0xf0, 0x59, 0xba, 0xe0, 0x59, 0xac, 0x16, 0x7c, 0x4d, 0x5f, - 0xe6, 0xdb, 0xe9, 0x36, 0xce, 0x62, 0x71, 0xdb, 0x8d, 0x3e, 0x84, 0x81, 0x36, 0x7a, 0xce, 0x3c, - 0x26, 0xd8, 0x2d, 0x47, 0x7a, 0x04, 0xa4, 0x60, 0x76, 0x9b, 0xbb, 0xfb, 0xd0, 0x18, 0x8f, 0x4f, - 0x52, 0x6d, 0x91, 0x62, 0xcd, 0x1d, 0x68, 0x8f, 0xa9, 0x6c, 0x25, 0x1c, 0x65, 0x61, 0x40, 0x5d, - 0xa8, 0xb1, 0x4e, 0xc0, 0x64, 0x68, 0xee, 0xc3, 0xd6, 0x21, 0xb5, 0x2f, 0x5d, 0x7f, 0xf6, 0xdc, - 0x8d, 0x64, 0x2f, 0xa5, 0x67, 0x0c, 0xa1, 0xe1, 0x68, 0x81, 0x9e, 0x92, 0x8e, 0xcd, 0xf7, 0xe1, - 0x8d, 0xdc, 0x0f, 0x3e, 0xe7, 0x82, 0x26, 0xdb, 0xdc, 0x82, 0x6a, 0x24, 0x47, 0x38, 0xa3, 0x6a, - 0xa9, 0x81, 0xf9, 0x39, 0x6c, 0xe5, 0xcb, 0xab, 0xec, 0x6c, 0xf0, 0xf0, 0x49, 0xcf, 0x51, 0xca, - 0xf5, 0x1c, 0xfa, 0x28, 0xe5, 0xac, 0x5a, 0xf4, 0xa1, 0xf2, 0xeb, 0x2f, 0xc7, 0x1a, 0x83, 0xf2, - 0xd3, 0xfc, 0xa3, 0x5c, 0xbe, 0xe8, 0x4f, 0x2d, 0x5f, 0x68, 0x3c, 0x4a, 0xaf, 0xd5, 0x78, 0xac, - 0xc2, 0xe0, 0x7d, 0x18, 0x9c, 0x7a, 0x81, 0x7d, 0x75, 0xe4, 0xe7, 0xa2, 0x61, 0x40, 0x9d, 0xf9, - 0xf9, 0x60, 0x24, 0x43, 0xf3, 0x1d, 0xe8, 0x9d, 0x04, 0x36, 0xf5, 0x4e, 0x83, 0xd8, 0x17, 0x69, - 0x14, 0xf0, 0x17, 0x38, 0x6d, 0xaa, 0x06, 0xe6, 0xfb, 0xd0, 0xd5, 0x05, 0xd8, 0xbf, 0x08, 0x12, - 0xc2, 0xca, 0x4a, 0x75, 0xa9, 0xd8, 0xc6, 0x9b, 0x27, 0xd0, 0xcb, 0xcc, 0x95, 0xdf, 0x77, 0xa0, - 0xa6, 0xd4, 0xfa, 0x6c, 0xbd, 0xf4, 0x1d, 0xab, 0x2c, 0x2d, 0xad, 0x5e, 0x73, 0xa8, 0x39, 0x74, - 0xcf, 0xf0, 0x97, 0xd0, 0x23, 0xff, 0x5a, 0x39, 0x3b, 0x06, 0xa2, 0x7e, 0x1b, 0x9d, 0x30, 0xff, - 0xda, 0xe5, 0x81, 0x8f, 0xad, 0x73, 0x49, 0x37, 0x28, 0x89, 0xe3, 0x74, 0x52, 0x62, 0x61, 0x0d, - 0xc2, 0x65, 0xd1, 0xda, 0x18, 0x42, 0xf6, 0x3b, 0x8b, 0xac, 0x00, 0x9c, 0xcd, 0x03, 0xc1, 0x26, - 0xd4, 0x71, 0x12, 0x10, 0x83, 0x12, 0x1d, 0x38, 0x0e, 0xdf, 0xff, 0x7b, 0x05, 0xea, 0x1f, 0x2b, - 0x5e, 0x25, 0xbf, 0x84, 0x4e, 0xa1, 0x18, 0x93, 0x37, 0xb0, 0x69, 0x5b, 0x2e, 0xfd, 0xc3, 0x3b, - 0x2b, 0x62, 0x75, 0xae, 0x0f, 0xa0, 0x9d, 0xaf, 0x91, 0x04, 0xeb, 0x21, 0xfe, 0xea, 0x3b, 0x44, - 0x4f, 0xab, 0x05, 0xf4, 0x1c, 0xb6, 0xd6, 0x55, 0x2f, 0x72, 0x3f, 0x5b, 0x61, 0xb5, 0x72, 0x0e, - 0xdf, 0xbc, 0x4d, 0x9b, 0x54, 0xbd, 0xfa, 0xa1, 0xc7, 0xa8, 0x1f, 0x87, 0xf9, 0x1d, 0x64, 0x9f, - 0xe4, 0x31, 0x74, 0x0a, 0xfc, 0xad, 0xce, 0xb9, 0x42, 0xe9, 0xf9, 0x29, 0x8f, 0xa0, 0x8a, 0x35, - 0x83, 0x74, 0x0a, 0xc5, 0x6b, 0xd8, 0x4d, 0x87, 0x6a, 0xed, 0xa7, 0x00, 0x59, 0x6f, 0x41, 0x88, - 0xf2, 0x9b, 0xef, 0x3e, 0x86, 0x9b, 0x45, 0x59, 0xd2, 0x7f, 0x6c, 0xe0, 0x4f, 0x08, 0xb9, 0xfd, - 0xe2, 0x42, 0x69, 0x1d, 0xda, 0xff, 0x4f, 0x09, 0xea, 0xc9, 0xcf, 0xca, 0x8f, 0x61, 0x43, 0x32, - 0x3a, 0xd9, 0xcc, 0x91, 0x62, 0x52, 0x0d, 0x86, 0x5b, 0x4b, 0x42, 0xb5, 0xc0, 0x08, 0x2a, 0x2f, - 0x98, 0x50, 0x1b, 0x2a, 0x52, 0xfb, 0x70, 0xb3, 0x28, 0x4b, 0xed, 0xcf, 0xe2, 0xa2, 0xbd, 0x66, - 0xe6, 0x82, 0x7d, 0xca, 0xb9, 0x1f, 0x42, 0x4d, 0x71, 0xa6, 0x8a, 0xe5, 0x0a, 0xdb, 0x2a, 0xcc, - 0xac, 0xb2, 0xeb, 0xfe, 0x5f, 0x37, 0x00, 0xce, 0x17, 0x91, 0x60, 0xf3, 0xdf, 0xb8, 0xec, 0x15, - 0xd9, 0x85, 0x9e, 0xfe, 0xa1, 0x04, 0xdf, 0x6f, 0x92, 0x84, 0x72, 0x31, 0xc1, 0x2e, 0x30, 0xa5, - 0xde, 0x47, 0xd0, 0x3a, 0xa5, 0x37, 0xaf, 0x63, 0x57, 0xd7, 0x84, 0x9c, 0xb7, 0xc1, 0x8a, 0x52, - 0x20, 0xea, 0x9f, 0x42, 0x6f, 0x89, 0x8e, 0xf3, 0xf6, 0xf8, 0x1b, 0xc7, 0x5a, 0xba, 0x7e, 0x26, - 0x9f, 0x30, 0x45, 0x4a, 0xce, 0x4f, 0xd4, 0xcf, 0xa9, 0x75, 0x9c, 0xfd, 0xa2, 0xf8, 0xf8, 0xc1, - 0x77, 0xa7, 0xb1, 0xcc, 0x9a, 0x09, 0x67, 0x0f, 0xef, 0xae, 0xd3, 0xa4, 0x99, 0x97, 0x27, 0xce, - 0x95, 0xcc, 0x5b, 0x65, 0xd5, 0xf7, 0x00, 0x32, 0xee, 0xcc, 0xdb, 0xe3, 0xf5, 0x2e, 0xd3, 0xea, - 0x53, 0x80, 0x8c, 0x11, 0x15, 0x2a, 0x8a, 0x84, 0xaa, 0xa6, 0x2d, 0xb3, 0xe6, 0x2e, 0x34, 0x53, - 0x16, 0xcb, 0xaf, 0x81, 0x0e, 0x8a, 0xa4, 0xf8, 0xf1, 0xee, 0xef, 0x77, 0x66, 0xae, 0xb8, 0x8c, - 0xa7, 0x23, 0x3b, 0x98, 0xef, 0x5d, 0xd2, 0xe8, 0xd2, 0xb5, 0x03, 0x1e, 0xee, 0x5d, 0x4b, 0x30, - 0xec, 0x15, 0xfe, 0xb5, 0x9a, 0xd6, 0xf0, 0xf5, 0xf6, 0xe4, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, - 0x66, 0x13, 0x8f, 0x1a, 0xcd, 0x1a, 0x00, 0x00, + // 2545 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x59, 0xdb, 0x72, 0x1b, 0xc7, + 0xd1, 0x2e, 0x00, 0xc4, 0xa9, 0x71, 0x1e, 0xd2, 0xfa, 0x57, 0x90, 0xfc, 0x8b, 0x5e, 0x47, 0x32, + 0xcd, 0xd8, 0xa0, 0x45, 0xc5, 0xb1, 0x9c, 0x54, 0xe2, 0xa2, 0x29, 0x4a, 0x66, 0x4c, 0xda, 0xac, + 0x25, 0x14, 0xe7, 0x54, 0x05, 0x0f, 0x76, 0x87, 0xe0, 0x16, 0x17, 0xbb, 0x9b, 0xd9, 0x59, 0x8a, + 0xc8, 0x4d, 0xde, 0x22, 0x6f, 0x90, 0xeb, 0xdc, 0xe6, 0x2e, 0x97, 0x71, 0xe5, 0x3e, 0xaf, 0x90, + 0xe7, 0x48, 0x4d, 0xcf, 0xec, 0x09, 0x00, 0x6d, 0xb9, 0xca, 0xb9, 0xdb, 0xe9, 0xee, 0xe9, 0x99, + 0xe9, 0xf9, 0xfa, 0xeb, 0x1e, 0x00, 0xee, 0x45, 0xce, 0xd5, 0x5e, 0xe8, 0xc5, 0x33, 0xd7, 0xdf, + 0x0b, 0xa7, 0x7b, 0x53, 0x6a, 0x5f, 0x31, 0xdf, 0x19, 0x85, 0x3c, 0x10, 0x01, 0x29, 0x87, 0xd3, + 0xe1, 0x83, 0x59, 0x10, 0xcc, 0x3c, 0xb6, 0x87, 0x92, 0x69, 0x7c, 0xb1, 0x27, 0xdc, 0x39, 0x8b, + 0x04, 0x9d, 0x87, 0xca, 0x68, 0x38, 0x94, 0x1e, 0xbc, 0x60, 0xe6, 0xda, 0xd4, 0xdb, 0x73, 0x1d, + 0xe6, 0x0b, 0x57, 0x2c, 0xb4, 0xce, 0xc8, 0xeb, 0xd4, 0x2a, 0x4a, 0x63, 0xd6, 0xa1, 0x7a, 0x34, + 0x0f, 0xc5, 0xc2, 0xdc, 0x86, 0xda, 0x67, 0x8c, 0x3a, 0x8c, 0x93, 0x3b, 0x50, 0xbb, 0xc4, 0x2f, + 0xa3, 0xb4, 0x5d, 0xd9, 0x69, 0x5a, 0x7a, 0x64, 0xfe, 0x1e, 0xe0, 0x4c, 0xce, 0x39, 0xe2, 0x3c, + 0xe0, 0xe4, 0x2e, 0x34, 0x18, 0xe7, 0x13, 0xb1, 0x08, 0x99, 0x51, 0xda, 0x2e, 0xed, 0x74, 0xac, + 0x3a, 0xe3, 0x7c, 0xbc, 0x08, 0x19, 0xf9, 0x3f, 0x90, 0x9f, 0x93, 0x79, 0x34, 0x33, 0xca, 0xdb, + 0x25, 0xe9, 0x81, 0x71, 0x7e, 0x1a, 0xcd, 0x92, 0x39, 0x76, 0xe0, 0x30, 0xa3, 0xb2, 0x5d, 0xda, + 0xa9, 0xe0, 0x9c, 0xc3, 0xc0, 0x61, 0xe6, 0x5f, 0x4a, 0x50, 0x3d, 0xa3, 0xe2, 0x32, 0x22, 0x04, + 0x36, 0x78, 0x10, 0x08, 0xbd, 0x38, 0x7e, 0x93, 0x1d, 0xe8, 0xc5, 0x3e, 0x8d, 0xc5, 0xa5, 0x3c, + 0x95, 0x4d, 0x05, 0x73, 0x8c, 0x32, 0xaa, 0x97, 0xc5, 0xe4, 0x6d, 0xe8, 0x78, 0x81, 0x4d, 0xbd, + 0x49, 0x24, 0x02, 0x4e, 0x67, 0x72, 0x1d, 0x69, 0xd7, 0x46, 0xe1, 0xb9, 0x92, 0x91, 0x5d, 0x18, + 0x44, 0x8c, 0x7a, 0x93, 0x57, 0x9c, 0x86, 0xa9, 0xe1, 0x86, 0x72, 0x28, 0x15, 0x5f, 0x71, 0x1a, + 0x6a, 0x5b, 0xf3, 0x1f, 0x35, 0xa8, 0x5b, 0xec, 0x8f, 0x31, 0x8b, 0x04, 0xe9, 0x42, 0xd9, 0x75, + 0xf0, 0xb4, 0x4d, 0xab, 0xec, 0x3a, 0x64, 0x04, 0xc4, 0x62, 0xa1, 0x27, 0x97, 0x76, 0x03, 0xff, + 0xd0, 0x8b, 0x23, 0xc1, 0xb8, 0x3e, 0xf3, 0x1a, 0x0d, 0xb9, 0x0f, 0xcd, 0x20, 0x64, 0x1c, 0x65, + 0x18, 0x80, 0xa6, 0x95, 0x09, 0xe4, 0xc1, 0x43, 0x2a, 0x2e, 0x8d, 0x0d, 0x54, 0xe0, 0xb7, 0x94, + 0x39, 0x54, 0x50, 0xa3, 0xaa, 0x64, 0xf2, 0x9b, 0x98, 0x50, 0x8b, 0x98, 0xcd, 0x99, 0x30, 0x6a, + 0xdb, 0xa5, 0x9d, 0xd6, 0x3e, 0x8c, 0xc2, 0xe9, 0xe8, 0x1c, 0x25, 0x96, 0xd6, 0x90, 0xfb, 0xb0, + 0x21, 0xe3, 0x62, 0xd4, 0xd1, 0xa2, 0x21, 0x2d, 0x0e, 0x62, 0x71, 0x69, 0xa1, 0x94, 0xec, 0x43, + 0x5d, 0xdd, 0x69, 0x64, 0x34, 0xb6, 0x2b, 0x3b, 0xad, 0x7d, 0x43, 0x1a, 0xe8, 0x53, 0x8e, 0x14, + 0x0c, 0xa2, 0x23, 0x5f, 0xf0, 0x85, 0x95, 0x18, 0x92, 0xb7, 0xa0, 0x6d, 0x7b, 0x2e, 0xf3, 0xc5, + 0x44, 0x04, 0x57, 0xcc, 0x37, 0x9a, 0xb8, 0xa3, 0x96, 0x92, 0x8d, 0xa5, 0x88, 0xec, 0xc3, 0x1b, + 0x79, 0x93, 0x09, 0xb5, 0x6d, 0x16, 0x45, 0x01, 0x37, 0x00, 0x6d, 0x37, 0x73, 0xb6, 0x07, 0x5a, + 0x25, 0xdd, 0x3a, 0x6e, 0x14, 0x7a, 0x74, 0x31, 0xf1, 0xe9, 0x9c, 0x19, 0x2d, 0xe5, 0x56, 0xcb, + 0xbe, 0xa0, 0x73, 0x46, 0x1e, 0x40, 0x6b, 0x1e, 0xc4, 0xbe, 0x98, 0x84, 0x81, 0xeb, 0x0b, 0xa3, + 0x8d, 0x16, 0x80, 0xa2, 0x33, 0x29, 0x21, 0x6f, 0x82, 0x1a, 0x29, 0x30, 0x76, 0x54, 0x5c, 0x51, + 0x82, 0x70, 0x7c, 0x08, 0x5d, 0xa5, 0x4e, 0xf7, 0xd3, 0x45, 0x93, 0x0e, 0x4a, 0xd3, 0x9d, 0x7c, + 0x00, 0x4d, 0xc4, 0x83, 0xeb, 0x5f, 0x04, 0x46, 0x0f, 0xe3, 0xb6, 0x99, 0x0b, 0x8b, 0xc4, 0xc4, + 0xb1, 0x7f, 0x11, 0x58, 0x8d, 0x57, 0xfa, 0x8b, 0xfc, 0x02, 0xee, 0x15, 0xce, 0xcb, 0xd9, 0x9c, + 0xba, 0xbe, 0xeb, 0xcf, 0x26, 0x71, 0xc4, 0x22, 0xa3, 0x8f, 0x08, 0x37, 0x72, 0xa7, 0xb6, 0x12, + 0x83, 0x97, 0x11, 0x8b, 0xc8, 0x3d, 0x68, 0xaa, 0x24, 0x9d, 0xb8, 0x8e, 0x31, 0xc0, 0x2d, 0x35, + 0x94, 0xe0, 0xd8, 0x21, 0xef, 0x40, 0x2f, 0x0c, 0x3c, 0xd7, 0x5e, 0x4c, 0x82, 0x6b, 0xc6, 0xb9, + 0xeb, 0x30, 0x83, 0x6c, 0x97, 0x76, 0x1a, 0x56, 0x57, 0x89, 0xbf, 0xd4, 0xd2, 0x75, 0xa9, 0xb1, + 0x89, 0x86, 0x2b, 0xa9, 0x31, 0x02, 0xb0, 0x03, 0xdf, 0x67, 0x36, 0xc2, 0x6f, 0x0b, 0x4f, 0xd8, + 0x95, 0x27, 0x3c, 0x4c, 0xa5, 0x56, 0xce, 0x62, 0xf8, 0x1c, 0xda, 0x79, 0x28, 0x90, 0x3e, 0x54, + 0xae, 0xd8, 0x42, 0xc3, 0x5f, 0x7e, 0x92, 0x6d, 0xa8, 0x5e, 0x53, 0x2f, 0x66, 0x08, 0x79, 0x0d, + 0x44, 0x35, 0xc5, 0x52, 0x8a, 0x9f, 0x95, 0x9f, 0x96, 0xcc, 0xff, 0x54, 0x61, 0x43, 0x82, 0x8f, + 0x7c, 0x08, 0x1d, 0x8f, 0xd1, 0x88, 0x4d, 0x82, 0x50, 0x2e, 0x10, 0xa1, 0xab, 0xd6, 0x7e, 0x5f, + 0x4e, 0x3b, 0x91, 0x8a, 0x2f, 0x95, 0xdc, 0x6a, 0x7b, 0xb9, 0x91, 0x4c, 0x69, 0xd7, 0x17, 0x8c, + 0xfb, 0xd4, 0x9b, 0x60, 0x32, 0xa8, 0x04, 0x6b, 0x27, 0xc2, 0x67, 0x32, 0x29, 0x96, 0x71, 0x54, + 0x59, 0xc5, 0xd1, 0x10, 0x1a, 0x18, 0x3b, 0x97, 0x45, 0x3a, 0xd9, 0xd3, 0x31, 0xd9, 0x87, 0xc6, + 0x9c, 0x09, 0xaa, 0x73, 0x4d, 0xa6, 0xc4, 0x9d, 0x24, 0x67, 0x46, 0xa7, 0x5a, 0xa1, 0x12, 0x22, + 0xb5, 0x5b, 0xc9, 0x88, 0xda, 0x6a, 0x46, 0x0c, 0xa1, 0x91, 0x82, 0xae, 0xae, 0x6e, 0x38, 0x19, + 0x4b, 0x9a, 0x0d, 0x19, 0x77, 0x03, 0xc7, 0x68, 0x20, 0x50, 0xf4, 0x48, 0x92, 0xa4, 0x1f, 0xcf, + 0x15, 0x84, 0x9a, 0x8a, 0x24, 0xfd, 0x78, 0xbe, 0x8a, 0x18, 0x58, 0x42, 0xcc, 0x8f, 0xa0, 0x4a, + 0x3d, 0x97, 0x46, 0x98, 0x42, 0xf2, 0x66, 0x35, 0xdf, 0x8f, 0x0e, 0xa4, 0xd4, 0x52, 0x4a, 0xf2, + 0x04, 0x3a, 0x33, 0x1e, 0xc4, 0xe1, 0x04, 0x87, 0x2c, 0x32, 0xda, 0x78, 0xda, 0x65, 0xeb, 0x36, + 0x1a, 0x1d, 0x28, 0x1b, 0x99, 0x81, 0xd3, 0x20, 0xf6, 0x9d, 0x89, 0xed, 0x3a, 0x3c, 0x32, 0x3a, + 0x18, 0x3c, 0x40, 0xd1, 0xa1, 0x94, 0xc8, 0x14, 0x53, 0x29, 0x90, 0x06, 0xb8, 0x8b, 0x36, 0x1d, + 0x94, 0x9e, 0x25, 0x51, 0xfe, 0x31, 0x0c, 0x92, 0xc2, 0x94, 0x59, 0xf6, 0xd0, 0xb2, 0x9f, 0x28, + 0x52, 0xe3, 0x1d, 0xe8, 0xb3, 0x1b, 0x49, 0xa1, 0xae, 0x98, 0xcc, 0xe9, 0xcd, 0x44, 0x08, 0x4f, + 0xa7, 0x54, 0x37, 0x91, 0x9f, 0xd2, 0x9b, 0xb1, 0xf0, 0x64, 0xfe, 0xab, 0xd5, 0x31, 0xff, 0x07, + 0x58, 0x8c, 0x9a, 0x28, 0xc1, 0xfc, 0xdf, 0x85, 0x81, 0x1f, 0x4c, 0x1c, 0x76, 0x41, 0x63, 0x4f, + 0xa8, 0x75, 0x17, 0x3a, 0x99, 0x7a, 0x7e, 0xf0, 0x4c, 0xc9, 0x71, 0xd9, 0xc5, 0xf0, 0xe7, 0xd0, + 0x29, 0x5c, 0xf7, 0x1a, 0xd0, 0x6f, 0xe5, 0x41, 0xdf, 0xcc, 0x03, 0xfd, 0x5f, 0x1b, 0x00, 0x78, + 0xef, 0x6a, 0xea, 0x72, 0xb5, 0xc8, 0x83, 0xa1, 0xbc, 0x06, 0x0c, 0x94, 0x33, 0x5f, 0x68, 0xe0, + 0xea, 0xd1, 0xb7, 0x62, 0x36, 0xa9, 0x17, 0xd5, 0x5c, 0xbd, 0x78, 0x0f, 0x36, 0x24, 0x3e, 0x8d, + 0x5a, 0x46, 0xeb, 0xd9, 0x8e, 0x10, 0xc9, 0x0a, 0xc5, 0x68, 0xb5, 0x92, 0x34, 0xf5, 0xd5, 0xa4, + 0xc9, 0xa3, 0xb1, 0x51, 0x44, 0xe3, 0xdb, 0xd0, 0xb1, 0x39, 0xc3, 0xda, 0x35, 0x91, 0xcd, 0x88, + 0x46, 0x6b, 0x3b, 0x11, 0x8e, 0xdd, 0x39, 0x93, 0xf1, 0x93, 0x17, 0x07, 0xa8, 0x92, 0x9f, 0x6b, + 0xef, 0xb5, 0xb5, 0xf6, 0x5e, 0xb1, 0x13, 0xf0, 0x98, 0x66, 0x7c, 0xfc, 0xce, 0x65, 0x4d, 0xa7, + 0x90, 0x35, 0x85, 0xd4, 0xe8, 0x2e, 0xa5, 0xc6, 0x12, 0x7e, 0x7b, 0x2b, 0xf8, 0x7d, 0x0b, 0xda, + 0x32, 0x00, 0x51, 0x48, 0x6d, 0x26, 0x1d, 0xf4, 0x55, 0x20, 0x52, 0xd9, 0xb1, 0x83, 0xd9, 0x1e, + 0x4f, 0xa7, 0x8b, 0xcb, 0xc0, 0x63, 0x19, 0x61, 0xb7, 0x52, 0xd9, 0xb1, 0x23, 0xf7, 0x8b, 0x08, + 0x24, 0x88, 0x40, 0xfc, 0x1e, 0x7e, 0x04, 0xcd, 0x34, 0xea, 0xdf, 0x0b, 0x4c, 0x7f, 0x2b, 0x41, + 0x3b, 0x4f, 0x8a, 0x72, 0xf2, 0x78, 0x7c, 0x82, 0x93, 0x2b, 0x96, 0xfc, 0x94, 0xed, 0x04, 0x67, + 0x3e, 0x7b, 0x45, 0xa7, 0x9e, 0x72, 0xd0, 0xb0, 0x32, 0x81, 0xd4, 0xba, 0xbe, 0xcd, 0xd9, 0x3c, + 0x41, 0x55, 0xc5, 0xca, 0x04, 0xe4, 0x63, 0x00, 0x37, 0x8a, 0x62, 0xa6, 0x6e, 0x6e, 0x03, 0x29, + 0x63, 0x38, 0x52, 0x3d, 0xe6, 0x28, 0xe9, 0x31, 0x47, 0xe3, 0xa4, 0xc7, 0xb4, 0x9a, 0x68, 0x8d, + 0x57, 0x7a, 0x07, 0x6a, 0xf2, 0x82, 0xc6, 0x27, 0x88, 0xbc, 0x8a, 0xa5, 0x47, 0xe6, 0x9f, 0xa1, + 0xa6, 0xba, 0x90, 0xff, 0x29, 0xd1, 0xdf, 0x85, 0x86, 0xf2, 0xed, 0x3a, 0x3a, 0x57, 0xea, 0x38, + 0x3e, 0x76, 0xcc, 0x6f, 0xca, 0xd0, 0xb0, 0x58, 0x14, 0x06, 0x7e, 0xc4, 0x72, 0x5d, 0x52, 0xe9, + 0x3b, 0xbb, 0xa4, 0xf2, 0xda, 0x2e, 0x29, 0xe9, 0xbd, 0x2a, 0xb9, 0xde, 0x6b, 0x08, 0x0d, 0xce, + 0x1c, 0x97, 0x33, 0x5b, 0xe8, 0x3e, 0x2d, 0x1d, 0x4b, 0xdd, 0x2b, 0xca, 0x65, 0x79, 0x8f, 0xb0, + 0x86, 0x34, 0xad, 0x74, 0x4c, 0x1e, 0xe7, 0x9b, 0x0b, 0xd5, 0xb6, 0x6d, 0xa9, 0xe6, 0x42, 0x6d, + 0x77, 0x4d, 0x77, 0xf1, 0x24, 0x6b, 0xd2, 0xea, 0x98, 0xcd, 0x77, 0xf3, 0x13, 0xd6, 0x77, 0x69, + 0x3f, 0x58, 0xcd, 0xfe, 0xa6, 0x0c, 0xfd, 0xe5, 0xbd, 0xad, 0x41, 0xe0, 0x16, 0x54, 0x55, 0xed, + 0xd3, 0xf0, 0x15, 0x2b, 0x55, 0xaf, 0xb2, 0x44, 0x74, 0x9f, 0x2c, 0x93, 0xc6, 0x77, 0x43, 0xaf, + 0x48, 0x28, 0xef, 0x42, 0x5f, 0x86, 0x28, 0x64, 0x4e, 0xd6, 0xcf, 0x29, 0x06, 0xec, 0x69, 0x79, + 0xda, 0xd1, 0xed, 0xc2, 0x20, 0x31, 0xcd, 0xb8, 0xa1, 0x56, 0xb0, 0x3d, 0x4a, 0x28, 0xe2, 0x0e, + 0xd4, 0x2e, 0x02, 0x3e, 0xa7, 0x42, 0x93, 0xa0, 0x1e, 0x15, 0x48, 0x0e, 0xd9, 0xb6, 0xa1, 0x30, + 0x99, 0x08, 0xe5, 0x9b, 0x45, 0x92, 0x4f, 0xfa, 0x9e, 0x40, 0x16, 0x6c, 0x58, 0x8d, 0xe4, 0x1d, + 0x61, 0xfe, 0x06, 0x7a, 0x4b, 0x2d, 0xe4, 0x9a, 0x40, 0x66, 0xcb, 0x97, 0x0b, 0xcb, 0x17, 0x3c, + 0x57, 0x96, 0x3c, 0xff, 0x16, 0x06, 0x9f, 0x51, 0xdf, 0xf1, 0x98, 0xf6, 0x7f, 0xc0, 0x67, 0x91, + 0x2c, 0x86, 0xfa, 0x45, 0x33, 0xd1, 0xd5, 0xa7, 0x63, 0x35, 0xb5, 0xe4, 0xd8, 0x21, 0x0f, 0xa1, + 0xce, 0x95, 0xb5, 0x06, 0x40, 0x2b, 0xd7, 0xe3, 0x5a, 0x89, 0xce, 0xfc, 0x1a, 0x48, 0xc1, 0xb5, + 0x7c, 0xcc, 0x2c, 0xc8, 0x8e, 0x44, 0xbf, 0x02, 0x85, 0xce, 0xaa, 0x76, 0x1e, 0x93, 0x56, 0xaa, + 0x25, 0xdb, 0x50, 0x61, 0x9c, 0xeb, 0x25, 0xb0, 0xc9, 0xcc, 0x9e, 0x8e, 0x96, 0x54, 0x99, 0x7d, + 0xe8, 0x1e, 0xfb, 0xae, 0x70, 0xa9, 0xe7, 0xfe, 0x89, 0xc9, 0x9d, 0x9b, 0x4f, 0xa0, 0x97, 0x49, + 0xd4, 0x82, 0xda, 0x4d, 0xe9, 0x76, 0x37, 0x3f, 0x81, 0xc1, 0x79, 0xc8, 0x6c, 0x97, 0x7a, 0xf8, + 0x7a, 0x54, 0xd3, 0x1e, 0x40, 0x55, 0xde, 0x55, 0xc2, 0x3b, 0x4d, 0x9c, 0x88, 0x6a, 0x25, 0x37, + 0xbf, 0x06, 0x43, 0x1d, 0xef, 0xe8, 0xc6, 0x8d, 0x04, 0xf3, 0x6d, 0x76, 0x78, 0xc9, 0xec, 0xab, + 0x1f, 0x30, 0x80, 0xd7, 0x70, 0x77, 0xdd, 0x0a, 0xc9, 0xfe, 0x5a, 0xb6, 0x1c, 0x4d, 0x2e, 0x64, + 0x09, 0xc2, 0x35, 0x1a, 0x16, 0xa0, 0xe8, 0xb9, 0x94, 0x48, 0x38, 0x30, 0x39, 0x2f, 0xd2, 0xb4, + 0xae, 0x47, 0x49, 0x3c, 0x2a, 0xb7, 0xc7, 0xe3, 0xef, 0x25, 0x68, 0x9e, 0x33, 0x11, 0x87, 0x78, + 0x96, 0x7b, 0xd0, 0x9c, 0xf2, 0xe0, 0x8a, 0xf1, 0xec, 0x28, 0x0d, 0x25, 0x38, 0x76, 0xc8, 0x63, + 0xa8, 0x1d, 0x06, 0xfe, 0x85, 0x3b, 0xc3, 0xb7, 0xb4, 0xe6, 0x97, 0x74, 0xee, 0x48, 0xe9, 0x14, + 0xbf, 0x68, 0x43, 0xb2, 0x0d, 0x2d, 0xfd, 0xcb, 0xc4, 0xcb, 0x97, 0xc7, 0xcf, 0x92, 0x26, 0x3b, + 0x27, 0x1a, 0x7e, 0x0c, 0xad, 0xdc, 0xc4, 0xef, 0x55, 0xf1, 0xfe, 0x1f, 0x00, 0x57, 0x57, 0x31, + 0xea, 0x67, 0x57, 0xdf, 0x54, 0x47, 0x7b, 0x00, 0x4d, 0xd9, 0xcf, 0x29, 0x75, 0x52, 0x6b, 0x4b, + 0x59, 0xad, 0x35, 0x1f, 0xc2, 0xe0, 0xd8, 0xbf, 0xa6, 0x9e, 0xeb, 0x50, 0xc1, 0x3e, 0x67, 0x0b, + 0x0c, 0xc1, 0xca, 0x0e, 0xcc, 0x73, 0x68, 0xeb, 0xc7, 0xfd, 0x6b, 0xed, 0xb1, 0xad, 0xf7, 0xf8, + 0xed, 0xb9, 0xf8, 0x2e, 0xf4, 0xb4, 0xd3, 0x13, 0x57, 0x67, 0xa2, 0x6c, 0x55, 0x38, 0xbb, 0x70, + 0x6f, 0xb4, 0x6b, 0x3d, 0x32, 0x9f, 0x42, 0x3f, 0x67, 0x9a, 0x1e, 0xe7, 0x8a, 0x2d, 0xa2, 0xe4, + 0x47, 0x0f, 0xf9, 0x9d, 0x44, 0xa0, 0x9c, 0x45, 0xc0, 0x84, 0xae, 0x9e, 0xf9, 0x82, 0x89, 0x5b, + 0x4e, 0xf7, 0x79, 0xba, 0x91, 0x17, 0x4c, 0x3b, 0x7f, 0x04, 0x55, 0x26, 0x4f, 0x9a, 0x2f, 0xc3, + 0xf9, 0x08, 0x58, 0x4a, 0xbd, 0x66, 0xc1, 0xa7, 0xe9, 0x82, 0x67, 0xb1, 0x5a, 0xf0, 0x35, 0x7d, + 0x99, 0x6f, 0xa7, 0xdb, 0x38, 0x8b, 0xc5, 0x6d, 0x37, 0xfa, 0x10, 0x06, 0xda, 0xe8, 0x19, 0xf3, + 0x98, 0x60, 0xb7, 0x1c, 0xe9, 0x11, 0x90, 0x82, 0xd9, 0x6d, 0xee, 0xee, 0x43, 0x63, 0x3c, 0x3e, + 0x49, 0xb5, 0x45, 0x8a, 0x35, 0x77, 0xa0, 0x3d, 0xa6, 0xb2, 0x95, 0x70, 0x94, 0x85, 0x01, 0x75, + 0xa1, 0xc6, 0x3a, 0x01, 0x93, 0xa1, 0xb9, 0x0f, 0x5b, 0x87, 0xd4, 0xbe, 0x74, 0xfd, 0xd9, 0x33, + 0x37, 0x92, 0xbd, 0x94, 0x9e, 0x31, 0x84, 0x86, 0xa3, 0x05, 0x7a, 0x4a, 0x3a, 0x36, 0xdf, 0x87, + 0x37, 0x72, 0x3f, 0xf8, 0x9c, 0x0b, 0x9a, 0x6c, 0x73, 0x0b, 0xaa, 0x91, 0x1c, 0xe1, 0x8c, 0xaa, + 0xa5, 0x06, 0xe6, 0x17, 0xb0, 0x95, 0x2f, 0xaf, 0xb2, 0xb3, 0xc1, 0xc3, 0x27, 0x3d, 0x47, 0x29, + 0xd7, 0x73, 0xe8, 0xa3, 0x94, 0xb3, 0x6a, 0xd1, 0x87, 0xca, 0xaf, 0xbe, 0x1a, 0x6b, 0x0c, 0xca, + 0x4f, 0xf3, 0x0f, 0x72, 0xf9, 0xa2, 0x3f, 0xb5, 0x7c, 0xa1, 0xf1, 0x28, 0xbd, 0x56, 0xe3, 0xb1, + 0x0a, 0x83, 0xf7, 0x61, 0x70, 0xea, 0x05, 0xf6, 0xd5, 0x91, 0x9f, 0x8b, 0x86, 0x01, 0x75, 0xe6, + 0xe7, 0x83, 0x91, 0x0c, 0xcd, 0x77, 0xa0, 0x77, 0x12, 0xd8, 0xd4, 0x3b, 0x0d, 0x62, 0x5f, 0xa4, + 0x51, 0xc0, 0x5f, 0xe0, 0xb4, 0xa9, 0x1a, 0x98, 0xef, 0x43, 0x57, 0x17, 0x60, 0xff, 0x22, 0x48, + 0x08, 0x2b, 0x2b, 0xd5, 0xa5, 0x62, 0x1b, 0x6f, 0x9e, 0x40, 0x2f, 0x33, 0x57, 0x7e, 0xdf, 0x81, + 0x9a, 0x52, 0xeb, 0xb3, 0xf5, 0xd2, 0x77, 0xac, 0xb2, 0xb4, 0xb4, 0x7a, 0xcd, 0xa1, 0xce, 0x60, + 0xeb, 0x85, 0x7c, 0xe4, 0x46, 0xcf, 0x03, 0xae, 0x8d, 0x75, 0xb6, 0xd4, 0xf0, 0xf1, 0xab, 0x92, + 0x31, 0xff, 0x34, 0x46, 0x73, 0x4b, 0x6b, 0xd7, 0x78, 0x9c, 0x43, 0xf7, 0x0c, 0x7f, 0x5b, 0x3d, + 0xf2, 0xaf, 0x95, 0xaf, 0x63, 0x20, 0xea, 0xd7, 0xd6, 0x09, 0xf3, 0xaf, 0x5d, 0x1e, 0xf8, 0xd8, + 0x8c, 0x97, 0x74, 0xcb, 0x93, 0xf8, 0x4d, 0x27, 0x25, 0x16, 0xd6, 0x20, 0x5c, 0x16, 0xad, 0xbd, + 0x15, 0xc8, 0x7e, 0xb9, 0x91, 0x35, 0x85, 0xb3, 0x79, 0x20, 0xd8, 0x84, 0x3a, 0x4e, 0x92, 0x16, + 0xa0, 0x44, 0x07, 0x8e, 0xc3, 0xf7, 0xff, 0x5a, 0x81, 0xfa, 0xa7, 0x8a, 0xa9, 0xc9, 0x2f, 0xa1, + 0x53, 0x28, 0xef, 0xe4, 0x0d, 0x6c, 0x03, 0x97, 0x9b, 0x89, 0xe1, 0x9d, 0x15, 0xb1, 0x3a, 0xd7, + 0x07, 0xd0, 0xce, 0x57, 0x5d, 0x82, 0x15, 0x16, 0x7f, 0x47, 0x1e, 0xa2, 0xa7, 0xd5, 0x92, 0x7c, + 0x0e, 0x5b, 0xeb, 0xea, 0x21, 0xb9, 0x9f, 0xad, 0xb0, 0x5a, 0x8b, 0x87, 0x6f, 0xde, 0xa6, 0x4d, + 0xea, 0x68, 0xfd, 0xd0, 0x63, 0xd4, 0x8f, 0xc3, 0xfc, 0x0e, 0xb2, 0x4f, 0xf2, 0x18, 0x3a, 0x85, + 0x8a, 0xa0, 0xce, 0xb9, 0x52, 0x24, 0xf2, 0x53, 0x1e, 0x41, 0x15, 0xab, 0x10, 0xe9, 0x14, 0xca, + 0xe1, 0xb0, 0x9b, 0x0e, 0xd5, 0xda, 0x1f, 0x02, 0x64, 0xdd, 0x0a, 0x21, 0xca, 0x6f, 0xbe, 0x9f, + 0x19, 0x6e, 0x16, 0x65, 0x49, 0x47, 0xb3, 0x81, 0x3f, 0x4a, 0xe4, 0xf6, 0x8b, 0x0b, 0xa5, 0x95, + 0x6d, 0xff, 0xdf, 0x25, 0xa8, 0x27, 0x3f, 0x54, 0x3f, 0x86, 0x0d, 0x59, 0x23, 0xc8, 0x66, 0x8e, + 0x66, 0x93, 0xfa, 0x32, 0xdc, 0x5a, 0x12, 0xaa, 0x05, 0x46, 0x50, 0x79, 0xc1, 0x84, 0xda, 0x50, + 0xb1, 0x58, 0x0c, 0x37, 0x8b, 0xb2, 0xd4, 0xfe, 0x2c, 0x2e, 0xda, 0x6b, 0xae, 0x2f, 0xd8, 0xa7, + 0x2c, 0xfe, 0x11, 0xd4, 0x14, 0x0b, 0xab, 0x58, 0xae, 0xf0, 0xb7, 0xc2, 0xcc, 0x2a, 0x5f, 0xef, + 0xff, 0x73, 0x03, 0xe0, 0x7c, 0x11, 0x09, 0x36, 0xff, 0xb5, 0xcb, 0x5e, 0x91, 0x5d, 0xe8, 0xe9, + 0x9f, 0x5e, 0xf0, 0x45, 0x28, 0x69, 0x2d, 0x17, 0x13, 0xec, 0x2b, 0x53, 0x32, 0x7f, 0x04, 0xad, + 0x53, 0x7a, 0xf3, 0x3a, 0x76, 0x75, 0x4d, 0xf1, 0x79, 0x1b, 0xac, 0x51, 0x05, 0xea, 0xff, 0x29, + 0xf4, 0x96, 0x08, 0x3e, 0x6f, 0x8f, 0xbf, 0x9a, 0xac, 0x2d, 0x00, 0x4f, 0xe5, 0xa3, 0xa8, 0x48, + 0xf2, 0xf9, 0x89, 0xfa, 0x81, 0xb6, 0xae, 0x0a, 0xbc, 0x28, 0x3e, 0xa7, 0xf0, 0x25, 0x6b, 0x2c, + 0xf3, 0x70, 0x52, 0x05, 0x86, 0x77, 0xd7, 0x69, 0xd2, 0xcc, 0xcb, 0x53, 0xf1, 0x4a, 0xe6, 0xad, + 0xf2, 0xf4, 0x7b, 0x00, 0x19, 0x1b, 0xe7, 0xed, 0xf1, 0x7a, 0x97, 0x89, 0xfa, 0x43, 0x80, 0x8c, + 0x63, 0x15, 0x2a, 0x8a, 0x14, 0xad, 0xa6, 0x2d, 0xf3, 0xf0, 0x2e, 0x34, 0x53, 0x16, 0xcb, 0xaf, + 0x81, 0x0e, 0x96, 0x48, 0xf1, 0x13, 0xe8, 0x2d, 0x11, 0xef, 0xda, 0x75, 0x30, 0x3c, 0xeb, 0x18, + 0xfa, 0xd3, 0xdd, 0xdf, 0xed, 0xcc, 0x5c, 0x71, 0x19, 0x4f, 0x47, 0x76, 0x30, 0xdf, 0xbb, 0xa4, + 0xd1, 0xa5, 0x6b, 0x07, 0x3c, 0xdc, 0xbb, 0x96, 0x68, 0xda, 0x2b, 0xfc, 0x91, 0x36, 0xad, 0xe1, + 0x83, 0xf2, 0xc9, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0xe9, 0x9a, 0xc2, 0x92, 0x60, 0x1b, 0x00, + 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -3473,6 +3524,9 @@ type SystemViewClient interface { EntityInfo(ctx context.Context, in *EntityInfoArgs, opts ...grpc.CallOption) (*EntityInfoReply, error) // PluginEnv returns Vault environment information used by plugins PluginEnv(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*PluginEnvReply, error) + // GroupsForEntity returns the group membersship information for the given + // entity id + GroupsForEntity(ctx context.Context, in *EntityInfoArgs, opts ...grpc.CallOption) (*GroupsForEntityReply, error) } type systemViewClient struct { @@ -3573,6 +3627,15 @@ func (c *systemViewClient) PluginEnv(ctx context.Context, in *Empty, opts ...grp return out, nil } +func (c *systemViewClient) GroupsForEntity(ctx context.Context, in *EntityInfoArgs, opts ...grpc.CallOption) (*GroupsForEntityReply, error) { + out := new(GroupsForEntityReply) + err := c.cc.Invoke(ctx, "/pb.SystemView/GroupsForEntity", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // SystemViewServer is the server API for SystemView service. type SystemViewServer interface { // DefaultLeaseTTL returns the default lease TTL set in Vault configuration @@ -3608,6 +3671,9 @@ type SystemViewServer interface { EntityInfo(context.Context, *EntityInfoArgs) (*EntityInfoReply, error) // PluginEnv returns Vault environment information used by plugins PluginEnv(context.Context, *Empty) (*PluginEnvReply, error) + // GroupsForEntity returns the group membersship information for the given + // entity id + GroupsForEntity(context.Context, *EntityInfoArgs) (*GroupsForEntityReply, error) } // UnimplementedSystemViewServer can be embedded to have forward compatible implementations. @@ -3644,6 +3710,9 @@ func (*UnimplementedSystemViewServer) EntityInfo(ctx context.Context, req *Entit func (*UnimplementedSystemViewServer) PluginEnv(ctx context.Context, req *Empty) (*PluginEnvReply, error) { return nil, status.Errorf(codes.Unimplemented, "method PluginEnv not implemented") } +func (*UnimplementedSystemViewServer) GroupsForEntity(ctx context.Context, req *EntityInfoArgs) (*GroupsForEntityReply, error) { + return nil, status.Errorf(codes.Unimplemented, "method GroupsForEntity not implemented") +} func RegisterSystemViewServer(s *grpc.Server, srv SystemViewServer) { s.RegisterService(&_SystemView_serviceDesc, srv) @@ -3829,6 +3898,24 @@ func _SystemView_PluginEnv_Handler(srv interface{}, ctx context.Context, dec fun return interceptor(ctx, in, info, handler) } +func _SystemView_GroupsForEntity_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(EntityInfoArgs) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SystemViewServer).GroupsForEntity(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pb.SystemView/GroupsForEntity", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SystemViewServer).GroupsForEntity(ctx, req.(*EntityInfoArgs)) + } + return interceptor(ctx, in, info, handler) +} + var _SystemView_serviceDesc = grpc.ServiceDesc{ ServiceName: "pb.SystemView", HandlerType: (*SystemViewServer)(nil), @@ -3873,6 +3960,10 @@ var _SystemView_serviceDesc = grpc.ServiceDesc{ MethodName: "PluginEnv", Handler: _SystemView_PluginEnv_Handler, }, + { + MethodName: "GroupsForEntity", + Handler: _SystemView_GroupsForEntity_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "sdk/plugin/pb/backend.proto", diff --git a/sdk/plugin/pb/backend.proto b/sdk/plugin/pb/backend.proto index 5b23d5e23333..0c5710f69c40 100644 --- a/sdk/plugin/pb/backend.proto +++ b/sdk/plugin/pb/backend.proto @@ -544,6 +544,11 @@ message EntityInfoReply { string err = 2; } +message GroupsForEntityReply { + repeated logical.Group groups = 1; + string err = 2; +} + message PluginEnvReply { logical.PluginEnvironment plugin_environment = 1; string err = 2; @@ -594,6 +599,10 @@ service SystemView { // PluginEnv returns Vault environment information used by plugins rpc PluginEnv(Empty) returns (PluginEnvReply); + + // GroupsForEntity returns the group membersship information for the given + // entity id + rpc GroupsForEntity(EntityInfoArgs) returns (GroupsForEntityReply); } message Connection { diff --git a/vault/dynamic_system_view.go b/vault/dynamic_system_view.go index 72dc9f725b10..5c4d398c8563 100644 --- a/vault/dynamic_system_view.go +++ b/vault/dynamic_system_view.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/errwrap" + "github.com/hashicorp/vault/helper/identity" "github.com/hashicorp/vault/helper/namespace" "github.com/hashicorp/vault/sdk/helper/consts" "github.com/hashicorp/vault/sdk/helper/license" @@ -267,22 +268,19 @@ func (d dynamicSystemView) EntityInfo(entityID string) (*logical.Entity, error) aliases := make([]*logical.Alias, len(entity.Aliases)) for i, a := range entity.Aliases { - alias := &logical.Alias{ - MountAccessor: a.MountAccessor, - Name: a.Name, + + // Don't return aliases from other namespaces + if a.NamespaceID != d.mountEntry.NamespaceID { + continue } + + alias := identity.ToSDKAlias(a) + // MountType is not stored with the entity and must be looked up if mount := d.core.router.validateMountByAccessor(a.MountAccessor); mount != nil { alias.MountType = mount.MountType } - if a.Metadata != nil { - alias.Metadata = make(map[string]string, len(a.Metadata)) - for k, v := range a.Metadata { - alias.Metadata[k] = v - } - } - aliases[i] = alias } ret.Aliases = aliases @@ -290,6 +288,40 @@ func (d dynamicSystemView) EntityInfo(entityID string) (*logical.Entity, error) return ret, nil } +func (d dynamicSystemView) GroupsForEntity(entityID string) ([]*logical.Group, error) { + // Requests from token created from the token backend will not have entity information. + // Return missing entity instead of error when requesting from MemDB. + if entityID == "" { + return nil, nil + } + + if d.core == nil { + return nil, fmt.Errorf("system view core is nil") + } + if d.core.identityStore == nil { + return nil, fmt.Errorf("system view identity store is nil") + } + + groups, inheritedGroups, err := d.core.identityStore.groupsByEntityID(entityID) + if err != nil { + return nil, err + } + + groups = append(groups, inheritedGroups...) + + logicalGroups := make([]*logical.Group, len(groups)) + for i, g := range groups { + // Don't return groups from other namespaces + if g.NamespaceID != d.mountEntry.NamespaceID { + continue + } + + logicalGroups[i] = identity.ToSDKGroup(g) + } + + return logicalGroups, nil +} + func (d dynamicSystemView) PluginEnv(_ context.Context) (*logical.PluginEnvironment, error) { return &logical.PluginEnvironment{ VaultVersion: version.GetVersion().Version, diff --git a/vault/dynamic_system_view_test.go b/vault/dynamic_system_view_test.go new file mode 100644 index 000000000000..6820282ee1c0 --- /dev/null +++ b/vault/dynamic_system_view_test.go @@ -0,0 +1,151 @@ +package vault + +import ( + "testing" + + log "github.com/hashicorp/go-hclog" + ldapcred "github.com/hashicorp/vault/builtin/credential/ldap" + "github.com/hashicorp/vault/helper/namespace" + "github.com/hashicorp/vault/sdk/framework" + "github.com/hashicorp/vault/sdk/logical" +) + +func TestIdentity_BackendTemplating(t *testing.T) { + var err error + coreConfig := &CoreConfig{ + DisableMlock: true, + DisableCache: true, + Logger: log.NewNullLogger(), + CredentialBackends: map[string]logical.Factory{ + "ldap": ldapcred.Factory, + }, + } + + cluster := NewTestCluster(t, coreConfig, &TestClusterOptions{}) + + cluster.Start() + defer cluster.Cleanup() + + core := cluster.Cores[0].Core + + TestWaitActive(t, core) + + req := logical.TestRequest(t, logical.UpdateOperation, "sys/auth/ldap") + req.ClientToken = cluster.RootToken + req.Data["type"] = "ldap" + resp, err := core.HandleRequest(namespace.RootContext(nil), req) + if err != nil { + t.Fatalf("err: %v", err) + } + if resp != nil { + t.Fatalf("bad: %v", resp) + } + + req = logical.TestRequest(t, logical.ReadOperation, "sys/auth") + req.ClientToken = cluster.RootToken + resp, err = core.HandleRequest(namespace.RootContext(nil), req) + if err != nil { + t.Fatalf("err: %v", err) + } + + accessor := resp.Data["ldap/"].(map[string]interface{})["accessor"].(string) + + // Create an entity + req = logical.TestRequest(t, logical.UpdateOperation, "identity/entity") + req.ClientToken = cluster.RootToken + req.Data["name"] = "entity1" + req.Data["metadata"] = map[string]string{ + "organization": "hashicorp", + "team": "vault", + } + resp, err = core.HandleRequest(namespace.RootContext(nil), req) + if err != nil { + t.Fatal(err) + } + + entityID := resp.Data["id"].(string) + + // Create an alias + req = logical.TestRequest(t, logical.UpdateOperation, "identity/entity-alias") + req.ClientToken = cluster.RootToken + req.Data["name"] = "alias1" + req.Data["canonical_id"] = entityID + req.Data["mount_accessor"] = accessor + resp, err = core.HandleRequest(namespace.RootContext(nil), req) + if err != nil { + t.Fatal(err) + } + + aliasID := resp.Data["id"].(string) + + // Create a group + req = logical.TestRequest(t, logical.UpdateOperation, "identity/group") + req.ClientToken = cluster.RootToken + req.Data["name"] = "group1" + req.Data["member_entity_ids"] = []string{entityID} + req.Data["metadata"] = map[string]string{ + "group": "vault", + } + resp, err = core.HandleRequest(namespace.RootContext(nil), req) + if err != nil { + t.Fatal(err) + } + + groupID := resp.Data["id"].(string) + + // Get the ldap mount + sysView := core.router.MatchingSystemView(namespace.RootContext(nil), "auth/ldap/") + + tCases := []struct { + tpl string + expected string + }{ + { + tpl: "{{identity.entity.id}}", + expected: entityID, + }, + { + tpl: "{{identity.entity.name}}", + expected: "entity1", + }, + { + tpl: "{{identity.entity.metadata.organization}}", + expected: "hashicorp", + }, + { + tpl: "{{identity.entity.aliases." + accessor + ".id}}", + expected: aliasID, + }, + { + tpl: "{{identity.entity.aliases." + accessor + ".name}}", + expected: "alias1", + }, + { + tpl: "{{identity.groups.ids." + groupID + ".name}}", + expected: "group1", + }, + { + tpl: "{{identity.groups.names.group1.id}}", + expected: groupID, + }, + { + tpl: "{{identity.groups.names.group1.metadata.group}}", + expected: "vault", + }, + { + tpl: "{{identity.groups.ids." + groupID + ".metadata.group}}", + expected: "vault", + }, + } + + for _, tCase := range tCases { + out, err := framework.PopulateIdentityTemplate(tCase.tpl, entityID, sysView) + if err != nil { + t.Fatal(err) + } + + if out != tCase.expected { + t.Fatalf("got %q, expected %q", out, tCase.expected) + } + } +} diff --git a/vault/identity_store_oidc.go b/vault/identity_store_oidc.go index c36c5c35c181..7f5be5934fba 100644 --- a/vault/identity_store_oidc.go +++ b/vault/identity_store_oidc.go @@ -21,6 +21,7 @@ import ( "github.com/hashicorp/vault/helper/namespace" "github.com/hashicorp/vault/sdk/framework" "github.com/hashicorp/vault/sdk/helper/base62" + identitytpl "github.com/hashicorp/vault/sdk/helper/identity" "github.com/hashicorp/vault/sdk/helper/strutil" "github.com/hashicorp/vault/sdk/logical" "github.com/patrickmn/go-cache" @@ -794,11 +795,11 @@ func (tok *idToken) generatePayload(logger hclog.Logger, template string, entity // Parse and integrate the populated role template. Structural errors with the template _should_ // be caught during role configuration. Error found during runtime will be logged, but they will // not block generation of the basic ID token. They should not be returned to the requester. - _, populatedTemplate, err := identity.PopulateString(identity.PopulateStringInput{ - Mode: identity.JSONTemplating, + _, populatedTemplate, err := identitytpl.PopulateString(identitytpl.PopulateStringInput{ + Mode: identitytpl.JSONTemplating, String: template, - Entity: entity, - Groups: groups, + Entity: identity.ToSDKEntity(entity), + Groups: identity.ToSDKGroups(groups), // namespace? }) @@ -899,11 +900,11 @@ func (i *IdentityStore) pathOIDCCreateUpdateRole(ctx context.Context, req *logic // Validate that template can be parsed and results in valid JSON if role.Template != "" { - _, populatedTemplate, err := identity.PopulateString(identity.PopulateStringInput{ - Mode: identity.JSONTemplating, + _, populatedTemplate, err := identitytpl.PopulateString(identitytpl.PopulateStringInput{ + Mode: identitytpl.JSONTemplating, String: role.Template, - Entity: new(identity.Entity), - Groups: make([]*identity.Group, 0), + Entity: new(logical.Entity), + Groups: make([]*logical.Group, 0), // namespace? }) diff --git a/vault/policy.go b/vault/policy.go index 42b247ea742e..f90605e3dd2f 100644 --- a/vault/policy.go +++ b/vault/policy.go @@ -13,6 +13,7 @@ import ( "github.com/hashicorp/vault/helper/identity" "github.com/hashicorp/vault/helper/namespace" "github.com/hashicorp/vault/sdk/helper/hclutil" + identitytpl "github.com/hashicorp/vault/sdk/helper/identity" "github.com/hashicorp/vault/sdk/helper/parseutil" "github.com/mitchellh/copystructure" ) @@ -281,20 +282,20 @@ func parsePaths(result *Policy, list *ast.ObjectList, performTemplating bool, en // Check the path if performTemplating { - _, templated, err := identity.PopulateString(identity.PopulateStringInput{ - Mode: identity.ACLTemplating, - String: key, - Entity: entity, - Groups: groups, - Namespace: result.namespace, + _, templated, err := identitytpl.PopulateString(identitytpl.PopulateStringInput{ + Mode: identitytpl.ACLTemplating, + String: key, + Entity: identity.ToSDKEntity(entity), + Groups: identity.ToSDKGroups(groups), + NamespaceID: result.namespace.ID, }) if err != nil { continue } key = templated } else { - hasTemplating, _, err := identity.PopulateString(identity.PopulateStringInput{ - Mode: identity.ACLTemplating, + hasTemplating, _, err := identitytpl.PopulateString(identitytpl.PopulateStringInput{ + Mode: identitytpl.ACLTemplating, ValidityCheckOnly: true, String: key, }) diff --git a/vendor/github.com/hashicorp/vault/api/plugin_helpers.go b/vendor/github.com/hashicorp/vault/api/plugin_helpers.go index e664d5ebc495..3aa4e6e46a9d 100644 --- a/vendor/github.com/hashicorp/vault/api/plugin_helpers.go +++ b/vendor/github.com/hashicorp/vault/api/plugin_helpers.go @@ -118,6 +118,9 @@ func VaultPluginTLSProvider(apiTLSConfig *TLSConfig) func() (*tls.Config, error) return nil, errwrap.Wrapf("error during api client creation: {{err}}", err) } + // Reset token value to make sure nothing has been set by default + client.ClearToken() + secret, err := client.Logical().Unwrap(unwrapToken) if err != nil { return nil, errwrap.Wrapf("error during token unwrap request: {{err}}", err) diff --git a/vendor/github.com/hashicorp/vault/sdk/framework/identity.go b/vendor/github.com/hashicorp/vault/sdk/framework/identity.go new file mode 100644 index 000000000000..0745a082e8e4 --- /dev/null +++ b/vendor/github.com/hashicorp/vault/sdk/framework/identity.go @@ -0,0 +1,52 @@ +package framework + +import ( + "errors" + + "github.com/hashicorp/errwrap" + "github.com/hashicorp/vault/sdk/helper/identity" + "github.com/hashicorp/vault/sdk/logical" +) + +func PopulateIdentityTemplate(tpl string, entityID string, sysView logical.SystemView) (string, error) { + entity, err := sysView.EntityInfo(entityID) + if err != nil { + return "", err + } + if entity == nil { + return "", errors.New("no entity found") + } + + groups, err := sysView.GroupsForEntity(entityID) + if err != nil { + return "", err + } + + // TODO: Namespace bound? + input := identity.PopulateStringInput{ + String: tpl, + Entity: entity, + Groups: groups, + Mode: identity.ACLTemplating, + } + + _, out, err := identity.PopulateString(input) + if err != nil { + return "", err + } + + return out, nil +} + +func ValidateIdentityTemplate(tpl string) (bool, error) { + hasTemplating, _, err := identity.PopulateString(identity.PopulateStringInput{ + Mode: identity.ACLTemplating, + ValidityCheckOnly: true, + String: tpl, + }) + if err != nil { + return false, errwrap.Wrapf("failed to validate policy templating: {{err}}", err) + } + + return hasTemplating, nil +} diff --git a/vendor/github.com/hashicorp/vault/sdk/helper/identity/templating.go b/vendor/github.com/hashicorp/vault/sdk/helper/identity/templating.go new file mode 100644 index 000000000000..acb6b9fb8fda --- /dev/null +++ b/vendor/github.com/hashicorp/vault/sdk/helper/identity/templating.go @@ -0,0 +1,358 @@ +package identity + +import ( + "encoding/json" + "errors" + "fmt" + "strconv" + "strings" + "time" + + "github.com/hashicorp/errwrap" + "github.com/hashicorp/vault/sdk/logical" +) + +var ( + ErrUnbalancedTemplatingCharacter = errors.New("unbalanced templating characters") + ErrNoEntityAttachedToToken = errors.New("string contains entity template directives but no entity was provided") + ErrNoGroupsAttachedToToken = errors.New("string contains groups template directives but no groups were provided") + ErrTemplateValueNotFound = errors.New("no value could be found for one of the template directives") +) + +const ( + ACLTemplating = iota // must be the first value for backwards compatibility + JSONTemplating +) + +type PopulateStringInput struct { + String string + ValidityCheckOnly bool + Entity *logical.Entity + Groups []*logical.Group + NamespaceID string + Mode int // processing mode, ACLTemplate or JSONTemplating + Now time.Time // optional, defaults to current time + + templateHandler templateHandlerFunc + groupIDs []string + groupNames []string +} + +// templateHandlerFunc allows generating string outputs based on data type, and +// different handlers can be used based on mode. For example in ACL mode, strings +// are emitted verbatim, but they're wrapped in double quotes for JSON mode. And +// some structures, like slices, might be rendered in one mode but prohibited in +// another. +type templateHandlerFunc func(interface{}, ...string) (string, error) + +// aclTemplateHandler processes known parameter data types when operating +// in ACL mode. +func aclTemplateHandler(v interface{}, keys ...string) (string, error) { + switch t := v.(type) { + case string: + if t == "" { + return "", ErrTemplateValueNotFound + } + return t, nil + case []string: + return "", ErrTemplateValueNotFound + case map[string]string: + if len(keys) > 0 { + val, ok := t[keys[0]] + if ok { + return val, nil + } + } + return "", ErrTemplateValueNotFound + } + + return "", fmt.Errorf("unknown type: %T", v) +} + +// jsonTemplateHandler processes known parameter data types when operating +// in JSON mode. +func jsonTemplateHandler(v interface{}, keys ...string) (string, error) { + jsonMarshaller := func(v interface{}) (string, error) { + enc, err := json.Marshal(v) + if err != nil { + return "", err + } + return string(enc), nil + } + + switch t := v.(type) { + case string: + return strconv.Quote(t), nil + case []string: + return jsonMarshaller(t) + case map[string]string: + if len(keys) > 0 { + return strconv.Quote(t[keys[0]]), nil + } + if t == nil { + return "{}", nil + } + return jsonMarshaller(t) + } + + return "", fmt.Errorf("unknown type: %T", v) +} + +func PopulateString(p PopulateStringInput) (bool, string, error) { + if p.String == "" { + return false, "", nil + } + + // preprocess groups + for _, g := range p.Groups { + p.groupNames = append(p.groupNames, g.Name) + p.groupIDs = append(p.groupIDs, g.ID) + } + + // set up mode-specific handler + switch p.Mode { + case ACLTemplating: + p.templateHandler = aclTemplateHandler + case JSONTemplating: + p.templateHandler = jsonTemplateHandler + default: + return false, "", fmt.Errorf("unknown mode %q", p.Mode) + } + + var subst bool + splitStr := strings.Split(p.String, "{{") + + if len(splitStr) >= 1 { + if strings.Contains(splitStr[0], "}}") { + return false, "", ErrUnbalancedTemplatingCharacter + } + if len(splitStr) == 1 { + return false, p.String, nil + } + } + + var b strings.Builder + if !p.ValidityCheckOnly { + b.Grow(2 * len(p.String)) + } + + for i, str := range splitStr { + if i == 0 { + if !p.ValidityCheckOnly { + b.WriteString(str) + } + continue + } + splitPiece := strings.Split(str, "}}") + switch len(splitPiece) { + case 2: + subst = true + if !p.ValidityCheckOnly { + tmplStr, err := performTemplating(strings.TrimSpace(splitPiece[0]), &p) + if err != nil { + return false, "", err + } + b.WriteString(tmplStr) + b.WriteString(splitPiece[1]) + } + default: + return false, "", ErrUnbalancedTemplatingCharacter + } + } + + return subst, b.String(), nil +} + +func performTemplating(input string, p *PopulateStringInput) (string, error) { + + performAliasTemplating := func(trimmed string, alias *logical.Alias) (string, error) { + switch { + case trimmed == "id": + return p.templateHandler(alias.ID) + + case trimmed == "name": + return p.templateHandler(alias.Name) + + case trimmed == "metadata": + return p.templateHandler(alias.Metadata) + + case strings.HasPrefix(trimmed, "metadata."): + split := strings.SplitN(trimmed, ".", 2) + return p.templateHandler(alias.Metadata, split[1]) + } + + return "", ErrTemplateValueNotFound + } + + performEntityTemplating := func(trimmed string) (string, error) { + switch { + case trimmed == "id": + return p.templateHandler(p.Entity.ID) + + case trimmed == "name": + return p.templateHandler(p.Entity.Name) + + case trimmed == "metadata": + return p.templateHandler(p.Entity.Metadata) + + case strings.HasPrefix(trimmed, "metadata."): + split := strings.SplitN(trimmed, ".", 2) + return p.templateHandler(p.Entity.Metadata, split[1]) + + case trimmed == "groups.names": + return p.templateHandler(p.groupNames) + + case trimmed == "groups.ids": + return p.templateHandler(p.groupIDs) + + case strings.HasPrefix(trimmed, "aliases."): + split := strings.SplitN(strings.TrimPrefix(trimmed, "aliases."), ".", 2) + if len(split) != 2 { + return "", errors.New("invalid alias selector") + } + var alias *logical.Alias + for _, a := range p.Entity.Aliases { + if split[0] == a.MountAccessor { + alias = a + break + } + } + if alias == nil { + if p.Mode == ACLTemplating { + return "", errors.New("alias not found") + } + + // An empty alias is sufficient for generating defaults + alias = &logical.Alias{Metadata: make(map[string]string)} + } + return performAliasTemplating(split[1], alias) + } + + return "", ErrTemplateValueNotFound + } + + performGroupsTemplating := func(trimmed string) (string, error) { + var ids bool + + selectorSplit := strings.SplitN(trimmed, ".", 2) + + switch { + case len(selectorSplit) != 2: + return "", errors.New("invalid groups selector") + + case selectorSplit[0] == "ids": + ids = true + + case selectorSplit[0] == "names": + + default: + return "", errors.New("invalid groups selector") + } + trimmed = selectorSplit[1] + + accessorSplit := strings.SplitN(trimmed, ".", 2) + if len(accessorSplit) != 2 { + return "", errors.New("invalid groups accessor") + } + var found *logical.Group + for _, group := range p.Groups { + var compare string + if ids { + compare = group.ID + } else { + if p.NamespaceID != "" && group.NamespaceID != p.NamespaceID { + continue + } + compare = group.Name + } + + if compare == accessorSplit[0] { + found = group + break + } + } + + if found == nil { + return "", fmt.Errorf("entity is not a member of group %q", accessorSplit[0]) + } + + trimmed = accessorSplit[1] + + switch { + case trimmed == "id": + return found.ID, nil + + case trimmed == "name": + if found.Name == "" { + return "", ErrTemplateValueNotFound + } + return found.Name, nil + + case strings.HasPrefix(trimmed, "metadata."): + val, ok := found.Metadata[strings.TrimPrefix(trimmed, "metadata.")] + if !ok { + return "", ErrTemplateValueNotFound + } + return val, nil + } + + return "", ErrTemplateValueNotFound + } + + performTimeTemplating := func(trimmed string) (string, error) { + now := p.Now + if now.IsZero() { + now = time.Now() + } + + opsSplit := strings.SplitN(trimmed, ".", 3) + + if opsSplit[0] != "now" { + return "", fmt.Errorf("invalid time selector %q", opsSplit[0]) + } + + result := now + switch len(opsSplit) { + case 1: + // return current time + case 2: + return "", errors.New("missing time operand") + + case 3: + duration, err := time.ParseDuration(opsSplit[2]) + if err != nil { + return "", errwrap.Wrapf("invalid duration: {{err}}", err) + } + + switch opsSplit[1] { + case "plus": + result = result.Add(duration) + case "minus": + result = result.Add(-duration) + default: + return "", fmt.Errorf("invalid time operator %q", opsSplit[1]) + } + } + + return strconv.FormatInt(result.Unix(), 10), nil + } + + switch { + case strings.HasPrefix(input, "identity.entity."): + if p.Entity == nil { + return "", ErrNoEntityAttachedToToken + } + return performEntityTemplating(strings.TrimPrefix(input, "identity.entity.")) + + case strings.HasPrefix(input, "identity.groups."): + if len(p.Groups) == 0 { + return "", ErrNoGroupsAttachedToToken + } + return performGroupsTemplating(strings.TrimPrefix(input, "identity.groups.")) + + case strings.HasPrefix(input, "time."): + return performTimeTemplating(strings.TrimPrefix(input, "time.")) + } + + return "", ErrTemplateValueNotFound +} diff --git a/vendor/github.com/hashicorp/vault/sdk/logical/identity.pb.go b/vendor/github.com/hashicorp/vault/sdk/logical/identity.pb.go index 51fde70f3a60..94102de78d62 100644 --- a/vendor/github.com/hashicorp/vault/sdk/logical/identity.pb.go +++ b/vendor/github.com/hashicorp/vault/sdk/logical/identity.pb.go @@ -30,7 +30,10 @@ type Entity struct { // Metadata represents the custom data tied to this entity Metadata map[string]string `sentinel:"" 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"` // Disabled is true if the entity is disabled. - Disabled bool `sentinel:"" protobuf:"varint,5,opt,name=disabled,proto3" json:"disabled,omitempty"` + Disabled bool `sentinel:"" protobuf:"varint,5,opt,name=disabled,proto3" json:"disabled,omitempty"` + // NamespaceID is the identifier of the namespace to which this entity + // belongs to. + NamespaceID string `sentinel:"" protobuf:"bytes,6,opt,name=namespace_id,json=namespaceID,proto3" json:"namespace_id,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -96,6 +99,13 @@ func (m *Entity) GetDisabled() bool { return false } +func (m *Entity) GetNamespaceID() string { + if m != nil { + return m.NamespaceID + } + return "" +} + type Alias struct { // MountType is the backend mount's type to which this identity belongs MountType string `sentinel:"" protobuf:"bytes,1,opt,name=mount_type,json=mountType,proto3" json:"mount_type,omitempty"` @@ -105,10 +115,15 @@ type Alias struct { // Name is the identifier of this identity in its authentication source Name string `sentinel:"" protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` // Metadata represents the custom data tied to this alias - Metadata map[string]string `sentinel:"" 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"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Metadata map[string]string `sentinel:"" 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"` + // ID is the unique identifier for the alias + ID string `sentinel:"" protobuf:"bytes,5,opt,name=ID,proto3" json:"ID,omitempty"` + // NamespaceID is the identifier of the namespace to which this alias + // belongs. + NamespaceID string `sentinel:"" protobuf:"bytes,6,opt,name=namespace_id,json=namespaceID,proto3" json:"namespace_id,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *Alias) Reset() { *m = Alias{} } @@ -164,35 +179,122 @@ func (m *Alias) GetMetadata() map[string]string { return nil } +func (m *Alias) GetID() string { + if m != nil { + return m.ID + } + return "" +} + +func (m *Alias) GetNamespaceID() string { + if m != nil { + return m.NamespaceID + } + return "" +} + +type Group struct { + // ID is the unique identifier for the group + ID string `sentinel:"" protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"` + // Name is the human-friendly unique identifier for the group + Name string `sentinel:"" protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + // Metadata represents the custom data tied to this group + Metadata map[string]string `sentinel:"" 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"` + // NamespaceID is the identifier of the namespace to which this group + // belongs to. + NamespaceID string `sentinel:"" protobuf:"bytes,4,opt,name=namespace_id,json=namespaceID,proto3" json:"namespace_id,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Group) Reset() { *m = Group{} } +func (m *Group) String() string { return proto.CompactTextString(m) } +func (*Group) ProtoMessage() {} +func (*Group) Descriptor() ([]byte, []int) { + return fileDescriptor_4a34d35719c603a1, []int{2} +} + +func (m *Group) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Group.Unmarshal(m, b) +} +func (m *Group) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Group.Marshal(b, m, deterministic) +} +func (m *Group) XXX_Merge(src proto.Message) { + xxx_messageInfo_Group.Merge(m, src) +} +func (m *Group) XXX_Size() int { + return xxx_messageInfo_Group.Size(m) +} +func (m *Group) XXX_DiscardUnknown() { + xxx_messageInfo_Group.DiscardUnknown(m) +} + +var xxx_messageInfo_Group proto.InternalMessageInfo + +func (m *Group) GetID() string { + if m != nil { + return m.ID + } + return "" +} + +func (m *Group) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *Group) GetMetadata() map[string]string { + if m != nil { + return m.Metadata + } + return nil +} + +func (m *Group) GetNamespaceID() string { + if m != nil { + return m.NamespaceID + } + return "" +} + func init() { proto.RegisterType((*Entity)(nil), "logical.Entity") proto.RegisterMapType((map[string]string)(nil), "logical.Entity.MetadataEntry") proto.RegisterType((*Alias)(nil), "logical.Alias") proto.RegisterMapType((map[string]string)(nil), "logical.Alias.MetadataEntry") + proto.RegisterType((*Group)(nil), "logical.Group") + proto.RegisterMapType((map[string]string)(nil), "logical.Group.MetadataEntry") } func init() { proto.RegisterFile("sdk/logical/identity.proto", fileDescriptor_4a34d35719c603a1) } var fileDescriptor_4a34d35719c603a1 = []byte{ - // 310 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x92, 0xbf, 0x6a, 0xc3, 0x30, - 0x10, 0xc6, 0x91, 0x9d, 0xbf, 0x57, 0x12, 0x8a, 0xe8, 0x60, 0x42, 0x03, 0x21, 0xd0, 0xe2, 0xc9, - 0x86, 0x76, 0x49, 0xdb, 0x29, 0x25, 0x19, 0x32, 0x74, 0x31, 0x9d, 0xba, 0x94, 0x8b, 0x2d, 0x62, - 0x11, 0xd9, 0x32, 0x96, 0x1c, 0xf0, 0x9b, 0xf6, 0x19, 0xfa, 0x14, 0x25, 0xb2, 0x62, 0x12, 0x4a, - 0xa7, 0x6e, 0xba, 0xdf, 0x77, 0x77, 0xba, 0xfb, 0x38, 0x98, 0xa8, 0x64, 0x1f, 0x0a, 0xb9, 0xe3, - 0x31, 0x8a, 0x90, 0x27, 0x2c, 0xd7, 0x5c, 0xd7, 0x41, 0x51, 0x4a, 0x2d, 0x69, 0xdf, 0xf2, 0xf9, - 0x37, 0x81, 0xde, 0xda, 0x28, 0x74, 0x0c, 0xce, 0x66, 0xe5, 0x91, 0x19, 0xf1, 0x87, 0x91, 0xb3, - 0x59, 0x51, 0x0a, 0x9d, 0x1c, 0x33, 0xe6, 0x39, 0x86, 0x98, 0x37, 0xf5, 0xa1, 0x8f, 0x82, 0xa3, - 0x62, 0xca, 0x73, 0x67, 0xae, 0x7f, 0xf5, 0x30, 0x0e, 0x6c, 0xa7, 0x60, 0x79, 0xe4, 0xd1, 0x49, - 0xa6, 0x4f, 0x30, 0xc8, 0x98, 0xc6, 0x04, 0x35, 0x7a, 0x1d, 0x93, 0x3a, 0x6d, 0x53, 0x9b, 0x0f, - 0x83, 0x37, 0xab, 0xaf, 0x73, 0x5d, 0xd6, 0x51, 0x9b, 0x4e, 0x27, 0x30, 0x48, 0xb8, 0xc2, 0xad, - 0x60, 0x89, 0xd7, 0x9d, 0x11, 0x7f, 0x10, 0xb5, 0xf1, 0xe4, 0x05, 0x46, 0x17, 0x65, 0xf4, 0x1a, - 0xdc, 0x3d, 0xab, 0xed, 0xd8, 0xc7, 0x27, 0xbd, 0x81, 0xee, 0x01, 0x45, 0x75, 0x1a, 0xbc, 0x09, - 0x9e, 0x9d, 0x05, 0x99, 0x7f, 0x11, 0xe8, 0x9a, 0x31, 0xe9, 0x14, 0x20, 0x93, 0x55, 0xae, 0x3f, - 0x75, 0x5d, 0x30, 0x5b, 0x3c, 0x34, 0xe4, 0xbd, 0x2e, 0x18, 0xbd, 0x83, 0x71, 0x23, 0x63, 0x1c, - 0x33, 0xa5, 0x64, 0x69, 0x7b, 0x8d, 0x0c, 0x5d, 0x5a, 0xd8, 0x3a, 0xe4, 0x9e, 0x39, 0xb4, 0xf8, - 0xb5, 0xf7, 0xed, 0xa5, 0x45, 0x7f, 0xad, 0xfd, 0xaf, 0xd5, 0x5e, 0xfd, 0x8f, 0xfb, 0x1d, 0xd7, - 0x69, 0xb5, 0x0d, 0x62, 0x99, 0x85, 0x29, 0xaa, 0x94, 0xc7, 0xb2, 0x2c, 0xc2, 0x03, 0x56, 0x42, - 0x87, 0x67, 0x97, 0xb0, 0xed, 0x99, 0x0b, 0x78, 0xfc, 0x09, 0x00, 0x00, 0xff, 0xff, 0xfa, 0xa9, - 0x8a, 0x39, 0x1f, 0x02, 0x00, 0x00, + // 365 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x93, 0x4f, 0x6b, 0xfa, 0x30, + 0x18, 0xc7, 0x69, 0x6b, 0xfd, 0xf3, 0xf8, 0x53, 0x7e, 0x84, 0x1d, 0x8a, 0x4c, 0x70, 0xc2, 0x46, + 0x4f, 0x2d, 0x6c, 0x17, 0xb7, 0x9d, 0x1c, 0xca, 0xf0, 0xb0, 0x4b, 0xd9, 0x69, 0x17, 0x89, 0x4d, + 0xd0, 0x60, 0xdb, 0x94, 0x26, 0x15, 0xfa, 0x1a, 0xc6, 0x5e, 0xd6, 0xde, 0xd7, 0x30, 0x8d, 0xa5, + 0x3a, 0x84, 0x1d, 0xb6, 0x5b, 0xf2, 0x7d, 0x9e, 0x7e, 0x9b, 0xcf, 0x37, 0x79, 0x60, 0x20, 0xc8, + 0xd6, 0x8f, 0xf8, 0x9a, 0x85, 0x38, 0xf2, 0x19, 0xa1, 0x89, 0x64, 0xb2, 0xf0, 0xd2, 0x8c, 0x4b, + 0x8e, 0x5a, 0x5a, 0x1f, 0x7f, 0x98, 0xd0, 0x9c, 0xab, 0x0a, 0xea, 0x83, 0xb9, 0x98, 0x39, 0xc6, + 0xc8, 0x70, 0x3b, 0x81, 0xb9, 0x98, 0x21, 0x04, 0x8d, 0x04, 0xc7, 0xd4, 0x31, 0x95, 0xa2, 0xd6, + 0xc8, 0x85, 0x16, 0x8e, 0x18, 0x16, 0x54, 0x38, 0xd6, 0xc8, 0x72, 0xbb, 0xb7, 0x7d, 0x4f, 0x3b, + 0x79, 0xd3, 0xbd, 0x1e, 0x1c, 0xca, 0xe8, 0x1e, 0xda, 0x31, 0x95, 0x98, 0x60, 0x89, 0x9d, 0x86, + 0x6a, 0x1d, 0x56, 0xad, 0xe5, 0x0f, 0xbd, 0x17, 0x5d, 0x9f, 0x27, 0x32, 0x2b, 0x82, 0xaa, 0x1d, + 0x0d, 0xa0, 0x4d, 0x98, 0xc0, 0xab, 0x88, 0x12, 0xc7, 0x1e, 0x19, 0x6e, 0x3b, 0xa8, 0xf6, 0xe8, + 0x0a, 0xfe, 0xed, 0x0f, 0x22, 0x52, 0x1c, 0xd2, 0x25, 0x23, 0x4e, 0x53, 0x1d, 0xae, 0x5b, 0x69, + 0x0b, 0x32, 0x78, 0x84, 0xde, 0x91, 0x33, 0xfa, 0x0f, 0xd6, 0x96, 0x16, 0x9a, 0x6c, 0xbf, 0x44, + 0x17, 0x60, 0xef, 0x70, 0x94, 0x1f, 0xd8, 0xca, 0xcd, 0x83, 0x39, 0x31, 0xc6, 0xef, 0x26, 0xd8, + 0x8a, 0x04, 0x0d, 0x01, 0x62, 0x9e, 0x27, 0x72, 0x29, 0x8b, 0x94, 0xea, 0x8f, 0x3b, 0x4a, 0x79, + 0x2d, 0x52, 0x8a, 0xae, 0xa1, 0x5f, 0x96, 0x71, 0x18, 0x52, 0x21, 0x78, 0xa6, 0xbd, 0x7a, 0x4a, + 0x9d, 0x6a, 0xb1, 0x0a, 0xd1, 0xaa, 0x85, 0x38, 0xf9, 0x16, 0xcd, 0xe5, 0x71, 0x8a, 0x67, 0x93, + 0x29, 0xaf, 0xc8, 0xae, 0xae, 0xe8, 0xaf, 0xd3, 0xf8, 0x34, 0xc0, 0x7e, 0xce, 0x78, 0x9e, 0xfe, + 0xe8, 0x71, 0xd4, 0xb9, 0xac, 0x13, 0x2e, 0xe5, 0x72, 0x96, 0xeb, 0x94, 0xa3, 0xf1, 0xbb, 0x1c, + 0x4f, 0xee, 0xdb, 0xcd, 0x9a, 0xc9, 0x4d, 0xbe, 0xf2, 0x42, 0x1e, 0xfb, 0x1b, 0x2c, 0x36, 0x2c, + 0xe4, 0x59, 0xea, 0xef, 0x70, 0x1e, 0x49, 0xbf, 0x36, 0x27, 0xab, 0xa6, 0x9a, 0x8f, 0xbb, 0xaf, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xa8, 0xe2, 0x28, 0xc0, 0x3d, 0x03, 0x00, 0x00, } diff --git a/vendor/github.com/hashicorp/vault/sdk/logical/identity.proto b/vendor/github.com/hashicorp/vault/sdk/logical/identity.proto index 65e27435f08d..75d3f60a2641 100644 --- a/vendor/github.com/hashicorp/vault/sdk/logical/identity.proto +++ b/vendor/github.com/hashicorp/vault/sdk/logical/identity.proto @@ -19,6 +19,10 @@ message Entity { // Disabled is true if the entity is disabled. bool disabled = 5; + + // NamespaceID is the identifier of the namespace to which this entity + // belongs to. + string namespace_id = 6; } message Alias { @@ -34,4 +38,26 @@ message Alias { // Metadata represents the custom data tied to this alias map metadata = 4; + + // ID is the unique identifier for the alias + string ID = 5; + + // NamespaceID is the identifier of the namespace to which this alias + // belongs. + string namespace_id = 6; } + +message Group { + // ID is the unique identifier for the group + string ID = 1; + + // Name is the human-friendly unique identifier for the group + string name = 2; + + // Metadata represents the custom data tied to this group + map metadata = 3; + + // NamespaceID is the identifier of the namespace to which this group + // belongs to. + string namespace_id = 4; +} diff --git a/vendor/github.com/hashicorp/vault/sdk/logical/system_view.go b/vendor/github.com/hashicorp/vault/sdk/logical/system_view.go index ef88a4322949..2c5d9c3bed07 100644 --- a/vendor/github.com/hashicorp/vault/sdk/logical/system_view.go +++ b/vendor/github.com/hashicorp/vault/sdk/logical/system_view.go @@ -62,6 +62,10 @@ type SystemView interface { // for the given entity id EntityInfo(entityID string) (*Entity, error) + // GroupsForEntity returns the group membership information for the provided + // entity id + GroupsForEntity(entityID string) ([]*Group, error) + // PluginEnv returns Vault environment information used by plugins PluginEnv(context.Context) (*PluginEnvironment, error) } @@ -82,6 +86,7 @@ type StaticSystemView struct { LocalMountVal bool ReplicationStateVal consts.ReplicationState EntityVal *Entity + GroupsVal []*Group Features license.Features VaultVersion string PluginEnvironment *PluginEnvironment @@ -149,6 +154,10 @@ func (d StaticSystemView) EntityInfo(entityID string) (*Entity, error) { return d.EntityVal, nil } +func (d StaticSystemView) GroupsForEntity(entityID string) ([]*Group, error) { + return d.GroupsVal, nil +} + func (d StaticSystemView) HasFeature(feature license.Features) bool { return d.Features.HasFeature(feature) } diff --git a/vendor/github.com/hashicorp/vault/sdk/plugin/grpc_system.go b/vendor/github.com/hashicorp/vault/sdk/plugin/grpc_system.go index 9047baff41d3..6e27c9b96360 100644 --- a/vendor/github.com/hashicorp/vault/sdk/plugin/grpc_system.go +++ b/vendor/github.com/hashicorp/vault/sdk/plugin/grpc_system.go @@ -138,6 +138,20 @@ func (s *gRPCSystemViewClient) EntityInfo(entityID string) (*logical.Entity, err return reply.Entity, nil } +func (s *gRPCSystemViewClient) GroupsForEntity(entityID string) ([]*logical.Group, error) { + reply, err := s.client.GroupsForEntity(context.Background(), &pb.EntityInfoArgs{ + EntityID: entityID, + }) + if err != nil { + return nil, err + } + if reply.Err != "" { + return nil, errors.New(reply.Err) + } + + return reply.Groups, nil +} + func (s *gRPCSystemViewClient) PluginEnv(ctx context.Context) (*logical.PluginEnvironment, error) { reply, err := s.client.PluginEnv(ctx, &pb.Empty{}) if err != nil { @@ -237,6 +251,18 @@ func (s *gRPCSystemViewServer) EntityInfo(ctx context.Context, args *pb.EntityIn }, nil } +func (s *gRPCSystemViewServer) GroupsForEntity(ctx context.Context, args *pb.EntityInfoArgs) (*pb.GroupsForEntityReply, error) { + groups, err := s.impl.GroupsForEntity(args.EntityID) + if err != nil { + return &pb.GroupsForEntityReply{ + Err: pb.ErrToString(err), + }, nil + } + return &pb.GroupsForEntityReply{ + Groups: groups, + }, nil +} + func (s *gRPCSystemViewServer) PluginEnv(ctx context.Context, _ *pb.Empty) (*pb.PluginEnvReply, error) { pluginEnv, err := s.impl.PluginEnv(ctx) if err != nil { diff --git a/vendor/github.com/hashicorp/vault/sdk/plugin/pb/backend.pb.go b/vendor/github.com/hashicorp/vault/sdk/plugin/pb/backend.pb.go index 566bf63f433c..8c7f57c1025e 100644 --- a/vendor/github.com/hashicorp/vault/sdk/plugin/pb/backend.pb.go +++ b/vendor/github.com/hashicorp/vault/sdk/plugin/pb/backend.pb.go @@ -2568,6 +2568,53 @@ func (m *EntityInfoReply) GetErr() string { return "" } +type GroupsForEntityReply struct { + Groups []*logical.Group `sentinel:"" protobuf:"bytes,1,rep,name=groups,proto3" json:"groups,omitempty"` + Err string `sentinel:"" protobuf:"bytes,2,opt,name=err,proto3" json:"err,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GroupsForEntityReply) Reset() { *m = GroupsForEntityReply{} } +func (m *GroupsForEntityReply) String() string { return proto.CompactTextString(m) } +func (*GroupsForEntityReply) ProtoMessage() {} +func (*GroupsForEntityReply) Descriptor() ([]byte, []int) { + return fileDescriptor_4dbf1dfe0c11846b, []int{42} +} + +func (m *GroupsForEntityReply) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GroupsForEntityReply.Unmarshal(m, b) +} +func (m *GroupsForEntityReply) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GroupsForEntityReply.Marshal(b, m, deterministic) +} +func (m *GroupsForEntityReply) XXX_Merge(src proto.Message) { + xxx_messageInfo_GroupsForEntityReply.Merge(m, src) +} +func (m *GroupsForEntityReply) XXX_Size() int { + return xxx_messageInfo_GroupsForEntityReply.Size(m) +} +func (m *GroupsForEntityReply) XXX_DiscardUnknown() { + xxx_messageInfo_GroupsForEntityReply.DiscardUnknown(m) +} + +var xxx_messageInfo_GroupsForEntityReply proto.InternalMessageInfo + +func (m *GroupsForEntityReply) GetGroups() []*logical.Group { + if m != nil { + return m.Groups + } + return nil +} + +func (m *GroupsForEntityReply) GetErr() string { + if m != nil { + return m.Err + } + return "" +} + type PluginEnvReply struct { PluginEnvironment *logical.PluginEnvironment `sentinel:"" protobuf:"bytes,1,opt,name=plugin_environment,json=pluginEnvironment,proto3" json:"plugin_environment,omitempty"` Err string `sentinel:"" protobuf:"bytes,2,opt,name=err,proto3" json:"err,omitempty"` @@ -2580,7 +2627,7 @@ func (m *PluginEnvReply) Reset() { *m = PluginEnvReply{} } func (m *PluginEnvReply) String() string { return proto.CompactTextString(m) } func (*PluginEnvReply) ProtoMessage() {} func (*PluginEnvReply) Descriptor() ([]byte, []int) { - return fileDescriptor_4dbf1dfe0c11846b, []int{42} + return fileDescriptor_4dbf1dfe0c11846b, []int{43} } func (m *PluginEnvReply) XXX_Unmarshal(b []byte) error { @@ -2627,7 +2674,7 @@ func (m *Connection) Reset() { *m = Connection{} } func (m *Connection) String() string { return proto.CompactTextString(m) } func (*Connection) ProtoMessage() {} func (*Connection) Descriptor() ([]byte, []int) { - return fileDescriptor_4dbf1dfe0c11846b, []int{43} + return fileDescriptor_4dbf1dfe0c11846b, []int{44} } func (m *Connection) XXX_Unmarshal(b []byte) error { @@ -2703,6 +2750,7 @@ func init() { proto.RegisterType((*LocalMountReply)(nil), "pb.LocalMountReply") proto.RegisterType((*EntityInfoArgs)(nil), "pb.EntityInfoArgs") proto.RegisterType((*EntityInfoReply)(nil), "pb.EntityInfoReply") + proto.RegisterType((*GroupsForEntityReply)(nil), "pb.GroupsForEntityReply") proto.RegisterType((*PluginEnvReply)(nil), "pb.PluginEnvReply") proto.RegisterType((*Connection)(nil), "pb.Connection") } @@ -2710,164 +2758,167 @@ func init() { func init() { proto.RegisterFile("sdk/plugin/pb/backend.proto", fileDescriptor_4dbf1dfe0c11846b) } var fileDescriptor_4dbf1dfe0c11846b = []byte{ - // 2504 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x59, 0xcd, 0x72, 0x1b, 0xc7, - 0x11, 0x2e, 0x00, 0xc4, 0x5f, 0xe3, 0x7f, 0x48, 0x2b, 0x2b, 0x48, 0x8e, 0xe8, 0x75, 0x24, 0xd3, - 0x8c, 0x0d, 0x5a, 0x54, 0x14, 0xcb, 0x49, 0x25, 0x29, 0x9a, 0xa2, 0x65, 0xc6, 0xa4, 0xcd, 0x5a, - 0x42, 0x71, 0xfe, 0xaa, 0xe0, 0xc1, 0xee, 0x10, 0xdc, 0xe2, 0x62, 0x77, 0x33, 0x3b, 0x4b, 0x11, - 0xb9, 0xe4, 0x96, 0x47, 0xc8, 0x1b, 0xe4, 0x9c, 0x6b, 0x6e, 0xb9, 0xba, 0x72, 0xcf, 0x2b, 0xe4, - 0x39, 0x52, 0xd3, 0x33, 0xfb, 0x07, 0x80, 0xb6, 0x5c, 0xe5, 0xdc, 0x76, 0xba, 0x7b, 0x7a, 0x66, - 0x7a, 0xbe, 0xfe, 0xba, 0x07, 0x80, 0x7b, 0x91, 0x73, 0xb5, 0x17, 0x7a, 0xf1, 0xcc, 0xf5, 0xf7, - 0xc2, 0xe9, 0xde, 0x94, 0xda, 0x57, 0xcc, 0x77, 0x46, 0x21, 0x0f, 0x44, 0x40, 0xca, 0xe1, 0x74, - 0xf8, 0x60, 0x16, 0x04, 0x33, 0x8f, 0xed, 0xa1, 0x64, 0x1a, 0x5f, 0xec, 0x09, 0x77, 0xce, 0x22, - 0x41, 0xe7, 0xa1, 0x32, 0x1a, 0x0e, 0xa5, 0x07, 0x2f, 0x98, 0xb9, 0x36, 0xf5, 0xf6, 0x5c, 0x87, - 0xf9, 0xc2, 0x15, 0x0b, 0xad, 0x33, 0xf2, 0x3a, 0xb5, 0x8a, 0xd2, 0x98, 0x75, 0xa8, 0x1e, 0xcd, - 0x43, 0xb1, 0x30, 0xb7, 0xa1, 0xf6, 0x29, 0xa3, 0x0e, 0xe3, 0xe4, 0x0e, 0xd4, 0x2e, 0xf1, 0xcb, - 0x28, 0x6d, 0x57, 0x76, 0x9a, 0x96, 0x1e, 0x99, 0x7f, 0x00, 0x38, 0x93, 0x73, 0x8e, 0x38, 0x0f, - 0x38, 0xb9, 0x0b, 0x0d, 0xc6, 0xf9, 0x44, 0x2c, 0x42, 0x66, 0x94, 0xb6, 0x4b, 0x3b, 0x1d, 0xab, - 0xce, 0x38, 0x1f, 0x2f, 0x42, 0x46, 0x7e, 0x00, 0xf2, 0x73, 0x32, 0x8f, 0x66, 0x46, 0x79, 0xbb, - 0x24, 0x3d, 0x30, 0xce, 0x4f, 0xa3, 0x59, 0x32, 0xc7, 0x0e, 0x1c, 0x66, 0x54, 0xb6, 0x4b, 0x3b, - 0x15, 0x9c, 0x73, 0x18, 0x38, 0xcc, 0xfc, 0x5b, 0x09, 0xaa, 0x67, 0x54, 0x5c, 0x46, 0x84, 0xc0, - 0x06, 0x0f, 0x02, 0xa1, 0x17, 0xc7, 0x6f, 0xb2, 0x03, 0xbd, 0xd8, 0xa7, 0xb1, 0xb8, 0x94, 0xa7, - 0xb2, 0xa9, 0x60, 0x8e, 0x51, 0x46, 0xf5, 0xb2, 0x98, 0xbc, 0x0d, 0x1d, 0x2f, 0xb0, 0xa9, 0x37, - 0x89, 0x44, 0xc0, 0xe9, 0x4c, 0xae, 0x23, 0xed, 0xda, 0x28, 0x3c, 0x57, 0x32, 0xb2, 0x0b, 0x83, - 0x88, 0x51, 0x6f, 0xf2, 0x8a, 0xd3, 0x30, 0x35, 0xdc, 0x50, 0x0e, 0xa5, 0xe2, 0x4b, 0x4e, 0x43, - 0x6d, 0x6b, 0xfe, 0xab, 0x06, 0x75, 0x8b, 0xfd, 0x29, 0x66, 0x91, 0x20, 0x5d, 0x28, 0xbb, 0x0e, - 0x9e, 0xb6, 0x69, 0x95, 0x5d, 0x87, 0x8c, 0x80, 0x58, 0x2c, 0xf4, 0xe4, 0xd2, 0x6e, 0xe0, 0x1f, - 0x7a, 0x71, 0x24, 0x18, 0xd7, 0x67, 0x5e, 0xa3, 0x21, 0xf7, 0xa1, 0x19, 0x84, 0x8c, 0xa3, 0x0c, - 0x03, 0xd0, 0xb4, 0x32, 0x81, 0x3c, 0x78, 0x48, 0xc5, 0xa5, 0xb1, 0x81, 0x0a, 0xfc, 0x96, 0x32, - 0x87, 0x0a, 0x6a, 0x54, 0x95, 0x4c, 0x7e, 0x13, 0x13, 0x6a, 0x11, 0xb3, 0x39, 0x13, 0x46, 0x6d, - 0xbb, 0xb4, 0xd3, 0xda, 0x87, 0x51, 0x38, 0x1d, 0x9d, 0xa3, 0xc4, 0xd2, 0x1a, 0x72, 0x1f, 0x36, - 0x64, 0x5c, 0x8c, 0x3a, 0x5a, 0x34, 0xa4, 0xc5, 0x41, 0x2c, 0x2e, 0x2d, 0x94, 0x92, 0x7d, 0xa8, - 0xab, 0x3b, 0x8d, 0x8c, 0xc6, 0x76, 0x65, 0xa7, 0xb5, 0x6f, 0x48, 0x03, 0x7d, 0xca, 0x91, 0x82, - 0x41, 0x74, 0xe4, 0x0b, 0xbe, 0xb0, 0x12, 0x43, 0xf2, 0x16, 0xb4, 0x6d, 0xcf, 0x65, 0xbe, 0x98, - 0x88, 0xe0, 0x8a, 0xf9, 0x46, 0x13, 0x77, 0xd4, 0x52, 0xb2, 0xb1, 0x14, 0x91, 0x7d, 0x78, 0x23, - 0x6f, 0x32, 0xa1, 0xb6, 0xcd, 0xa2, 0x28, 0xe0, 0x06, 0xa0, 0xed, 0x66, 0xce, 0xf6, 0x40, 0xab, - 0xa4, 0x5b, 0xc7, 0x8d, 0x42, 0x8f, 0x2e, 0x26, 0x3e, 0x9d, 0x33, 0xa3, 0xa5, 0xdc, 0x6a, 0xd9, - 0xe7, 0x74, 0xce, 0xc8, 0x03, 0x68, 0xcd, 0x83, 0xd8, 0x17, 0x93, 0x30, 0x70, 0x7d, 0x61, 0xb4, - 0xd1, 0x02, 0x50, 0x74, 0x26, 0x25, 0xe4, 0x4d, 0x50, 0x23, 0x05, 0xc6, 0x8e, 0x8a, 0x2b, 0x4a, - 0x10, 0x8e, 0x0f, 0xa1, 0xab, 0xd4, 0xe9, 0x7e, 0xba, 0x68, 0xd2, 0x41, 0x69, 0xba, 0x93, 0x0f, - 0xa0, 0x89, 0x78, 0x70, 0xfd, 0x8b, 0xc0, 0xe8, 0x61, 0xdc, 0x36, 0x73, 0x61, 0x91, 0x98, 0x38, - 0xf6, 0x2f, 0x02, 0xab, 0xf1, 0x4a, 0x7f, 0x91, 0x5f, 0xc0, 0xbd, 0xc2, 0x79, 0x39, 0x9b, 0x53, - 0xd7, 0x77, 0xfd, 0xd9, 0x24, 0x8e, 0x58, 0x64, 0xf4, 0x11, 0xe1, 0x46, 0xee, 0xd4, 0x56, 0x62, - 0xf0, 0x32, 0x62, 0x11, 0xb9, 0x07, 0x4d, 0x95, 0xa4, 0x13, 0xd7, 0x31, 0x06, 0xb8, 0xa5, 0x86, - 0x12, 0x1c, 0x3b, 0xe4, 0x1d, 0xe8, 0x85, 0x81, 0xe7, 0xda, 0x8b, 0x49, 0x70, 0xcd, 0x38, 0x77, - 0x1d, 0x66, 0x90, 0xed, 0xd2, 0x4e, 0xc3, 0xea, 0x2a, 0xf1, 0x17, 0x5a, 0xba, 0x2e, 0x35, 0x36, - 0xd1, 0x70, 0x25, 0x35, 0x46, 0x00, 0x76, 0xe0, 0xfb, 0xcc, 0x46, 0xf8, 0x6d, 0xe1, 0x09, 0xbb, - 0xf2, 0x84, 0x87, 0xa9, 0xd4, 0xca, 0x59, 0x0c, 0x3f, 0x81, 0x76, 0x1e, 0x0a, 0xa4, 0x0f, 0x95, - 0x2b, 0xb6, 0xd0, 0xf0, 0x97, 0x9f, 0x64, 0x1b, 0xaa, 0xd7, 0xd4, 0x8b, 0x19, 0x42, 0x5e, 0x03, - 0x51, 0x4d, 0xb1, 0x94, 0xe2, 0x67, 0xe5, 0x67, 0x25, 0xf3, 0xbf, 0x55, 0xd8, 0x90, 0xe0, 0x23, - 0x4f, 0xa1, 0xe3, 0x31, 0x1a, 0xb1, 0x49, 0x10, 0xca, 0x05, 0x22, 0x74, 0xd5, 0xda, 0xef, 0xcb, - 0x69, 0x27, 0x52, 0xf1, 0x85, 0x92, 0x5b, 0x6d, 0x2f, 0x37, 0x92, 0x29, 0xed, 0xfa, 0x82, 0x71, - 0x9f, 0x7a, 0x13, 0x4c, 0x06, 0x95, 0x60, 0xed, 0x44, 0xf8, 0x5c, 0x26, 0xc5, 0x32, 0x8e, 0x2a, - 0xab, 0x38, 0x1a, 0x42, 0x03, 0x63, 0xe7, 0xb2, 0x48, 0x27, 0x7b, 0x3a, 0x26, 0xfb, 0xd0, 0x98, - 0x33, 0x41, 0x75, 0xae, 0xc9, 0x94, 0xb8, 0x93, 0xe4, 0xcc, 0xe8, 0x54, 0x2b, 0x54, 0x42, 0xa4, - 0x76, 0x2b, 0x19, 0x51, 0x5b, 0xcd, 0x88, 0x21, 0x34, 0x52, 0xd0, 0xd5, 0xd5, 0x0d, 0x27, 0x63, - 0x49, 0xb3, 0x21, 0xe3, 0x6e, 0xe0, 0x18, 0x0d, 0x04, 0x8a, 0x1e, 0x49, 0x92, 0xf4, 0xe3, 0xb9, - 0x82, 0x50, 0x53, 0x91, 0xa4, 0x1f, 0xcf, 0x57, 0x11, 0x03, 0x4b, 0x88, 0xf9, 0x11, 0x54, 0xa9, - 0xe7, 0xd2, 0x08, 0x53, 0x48, 0xde, 0xac, 0xe6, 0xfb, 0xd1, 0x81, 0x94, 0x5a, 0x4a, 0x49, 0x9e, - 0x40, 0x67, 0xc6, 0x83, 0x38, 0x9c, 0xe0, 0x90, 0x45, 0x46, 0x1b, 0x4f, 0xbb, 0x6c, 0xdd, 0x46, - 0xa3, 0x03, 0x65, 0x23, 0x33, 0x70, 0x1a, 0xc4, 0xbe, 0x33, 0xb1, 0x5d, 0x87, 0x47, 0x46, 0x07, - 0x83, 0x07, 0x28, 0x3a, 0x94, 0x12, 0x99, 0x62, 0x2a, 0x05, 0xd2, 0x00, 0x77, 0xd1, 0xa6, 0x83, - 0xd2, 0xb3, 0x24, 0xca, 0x3f, 0x86, 0x41, 0x52, 0x98, 0x32, 0xcb, 0x1e, 0x5a, 0xf6, 0x13, 0x45, - 0x6a, 0xbc, 0x03, 0x7d, 0x76, 0x23, 0x29, 0xd4, 0x15, 0x93, 0x39, 0xbd, 0x99, 0x08, 0xe1, 0xe9, - 0x94, 0xea, 0x26, 0xf2, 0x53, 0x7a, 0x33, 0x16, 0x9e, 0xcc, 0x7f, 0xb5, 0x3a, 0xe6, 0xff, 0x00, - 0x8b, 0x51, 0x13, 0x25, 0x98, 0xff, 0xbb, 0x30, 0xf0, 0x83, 0x89, 0xc3, 0x2e, 0x68, 0xec, 0x09, - 0xb5, 0xee, 0x42, 0x27, 0x53, 0xcf, 0x0f, 0x9e, 0x2b, 0x39, 0x2e, 0xbb, 0x18, 0xfe, 0x1c, 0x3a, - 0x85, 0xeb, 0x5e, 0x03, 0xfa, 0xad, 0x3c, 0xe8, 0x9b, 0x79, 0xa0, 0xff, 0x7b, 0x03, 0x00, 0xef, - 0x5d, 0x4d, 0x5d, 0xae, 0x16, 0x79, 0x30, 0x94, 0xd7, 0x80, 0x81, 0x72, 0xe6, 0x0b, 0x0d, 0x5c, - 0x3d, 0xfa, 0x46, 0xcc, 0x26, 0xf5, 0xa2, 0x9a, 0xab, 0x17, 0xef, 0xc1, 0x86, 0xc4, 0xa7, 0x51, - 0xcb, 0x68, 0x3d, 0xdb, 0x11, 0x22, 0x59, 0xa1, 0x18, 0xad, 0x56, 0x92, 0xa6, 0xbe, 0x9a, 0x34, - 0x79, 0x34, 0x36, 0x8a, 0x68, 0x7c, 0x1b, 0x3a, 0x36, 0x67, 0x58, 0xbb, 0x26, 0xb2, 0x19, 0xd1, - 0x68, 0x6d, 0x27, 0xc2, 0xb1, 0x3b, 0x67, 0x32, 0x7e, 0xf2, 0xe2, 0x00, 0x55, 0xf2, 0x73, 0xed, - 0xbd, 0xb6, 0xd6, 0xde, 0x2b, 0x76, 0x02, 0x1e, 0xd3, 0x8c, 0x8f, 0xdf, 0xb9, 0xac, 0xe9, 0x14, - 0xb2, 0xa6, 0x90, 0x1a, 0xdd, 0xa5, 0xd4, 0x58, 0xc2, 0x6f, 0x6f, 0x05, 0xbf, 0x6f, 0x41, 0x5b, - 0x06, 0x20, 0x0a, 0xa9, 0xcd, 0xa4, 0x83, 0xbe, 0x0a, 0x44, 0x2a, 0x3b, 0x76, 0x30, 0xdb, 0xe3, - 0xe9, 0x74, 0x71, 0x19, 0x78, 0x2c, 0x23, 0xec, 0x56, 0x2a, 0x3b, 0x76, 0xe4, 0x7e, 0x11, 0x81, - 0x04, 0x11, 0x88, 0xdf, 0xc3, 0x0f, 0xa1, 0x99, 0x46, 0xfd, 0x3b, 0x81, 0xe9, 0x1f, 0x25, 0x68, - 0xe7, 0x49, 0x51, 0x4e, 0x1e, 0x8f, 0x4f, 0x70, 0x72, 0xc5, 0x92, 0x9f, 0xb2, 0x9d, 0xe0, 0xcc, - 0x67, 0xaf, 0xe8, 0xd4, 0x53, 0x0e, 0x1a, 0x56, 0x26, 0x90, 0x5a, 0xd7, 0xb7, 0x39, 0x9b, 0x27, - 0xa8, 0xaa, 0x58, 0x99, 0x80, 0x7c, 0x04, 0xe0, 0x46, 0x51, 0xcc, 0xd4, 0xcd, 0x6d, 0x20, 0x65, - 0x0c, 0x47, 0xaa, 0xc7, 0x1c, 0x25, 0x3d, 0xe6, 0x68, 0x9c, 0xf4, 0x98, 0x56, 0x13, 0xad, 0xf1, - 0x4a, 0xef, 0x40, 0x4d, 0x5e, 0xd0, 0xf8, 0x04, 0x91, 0x57, 0xb1, 0xf4, 0xc8, 0xfc, 0x0b, 0xd4, - 0x54, 0x17, 0xf2, 0x7f, 0x25, 0xfa, 0xbb, 0xd0, 0x50, 0xbe, 0x5d, 0x47, 0xe7, 0x4a, 0x1d, 0xc7, - 0xc7, 0x8e, 0xf9, 0x75, 0x19, 0x1a, 0x16, 0x8b, 0xc2, 0xc0, 0x8f, 0x58, 0xae, 0x4b, 0x2a, 0x7d, - 0x6b, 0x97, 0x54, 0x5e, 0xdb, 0x25, 0x25, 0xbd, 0x57, 0x25, 0xd7, 0x7b, 0x0d, 0xa1, 0xc1, 0x99, - 0xe3, 0x72, 0x66, 0x0b, 0xdd, 0xa7, 0xa5, 0x63, 0xa9, 0x7b, 0x45, 0xb9, 0x2c, 0xef, 0x11, 0xd6, - 0x90, 0xa6, 0x95, 0x8e, 0xc9, 0xe3, 0x7c, 0x73, 0xa1, 0xda, 0xb6, 0x2d, 0xd5, 0x5c, 0xa8, 0xed, - 0xae, 0xe9, 0x2e, 0x9e, 0x64, 0x4d, 0x5a, 0x1d, 0xb3, 0xf9, 0x6e, 0x7e, 0xc2, 0xfa, 0x2e, 0xed, - 0x7b, 0xab, 0xd9, 0x5f, 0x97, 0xa1, 0xbf, 0xbc, 0xb7, 0x35, 0x08, 0xdc, 0x82, 0xaa, 0xaa, 0x7d, - 0x1a, 0xbe, 0x62, 0xa5, 0xea, 0x55, 0x96, 0x88, 0xee, 0x57, 0xcb, 0xa4, 0xf1, 0xed, 0xd0, 0x2b, - 0x12, 0xca, 0xbb, 0xd0, 0x97, 0x21, 0x0a, 0x99, 0x93, 0xf5, 0x73, 0x8a, 0x01, 0x7b, 0x5a, 0x9e, - 0x76, 0x74, 0xbb, 0x30, 0x48, 0x4c, 0x33, 0x6e, 0xa8, 0x15, 0x6c, 0x8f, 0x12, 0x8a, 0xb8, 0x03, - 0xb5, 0x8b, 0x80, 0xcf, 0xa9, 0xd0, 0x24, 0xa8, 0x47, 0x05, 0x92, 0x43, 0xb6, 0x6d, 0x28, 0x4c, - 0x26, 0x42, 0xf9, 0x66, 0x91, 0xe4, 0x93, 0xbe, 0x27, 0x90, 0x05, 0x1b, 0x56, 0x23, 0x79, 0x47, - 0x98, 0xbf, 0x85, 0xde, 0x52, 0x0b, 0xb9, 0x26, 0x90, 0xd9, 0xf2, 0xe5, 0xc2, 0xf2, 0x05, 0xcf, - 0x95, 0x25, 0xcf, 0xbf, 0x83, 0xc1, 0xa7, 0xd4, 0x77, 0x3c, 0xa6, 0xfd, 0x1f, 0xf0, 0x59, 0x24, - 0x8b, 0xa1, 0x7e, 0xd1, 0x4c, 0x74, 0xf5, 0xe9, 0x58, 0x4d, 0x2d, 0x39, 0x76, 0xc8, 0x43, 0xa8, - 0x73, 0x65, 0xad, 0x01, 0xd0, 0xca, 0xf5, 0xb8, 0x56, 0xa2, 0x33, 0xbf, 0x02, 0x52, 0x70, 0x2d, - 0x1f, 0x33, 0x0b, 0xb2, 0x23, 0xd1, 0xaf, 0x40, 0xa1, 0xb3, 0xaa, 0x9d, 0xc7, 0xa4, 0x95, 0x6a, - 0xc9, 0x36, 0x54, 0x18, 0xe7, 0x7a, 0x09, 0x6c, 0x32, 0xb3, 0xa7, 0xa3, 0x25, 0x55, 0x66, 0x1f, - 0xba, 0xc7, 0xbe, 0x2b, 0x5c, 0xea, 0xb9, 0x7f, 0x66, 0x72, 0xe7, 0xe6, 0x13, 0xe8, 0x65, 0x12, - 0xb5, 0xa0, 0x76, 0x53, 0xba, 0xdd, 0xcd, 0x4f, 0x60, 0x70, 0x1e, 0x32, 0xdb, 0xa5, 0x1e, 0xbe, - 0x1e, 0xd5, 0xb4, 0x07, 0x50, 0x95, 0x77, 0x95, 0xf0, 0x4e, 0x13, 0x27, 0xa2, 0x5a, 0xc9, 0xcd, - 0xaf, 0xc0, 0x50, 0xc7, 0x3b, 0xba, 0x71, 0x23, 0xc1, 0x7c, 0x9b, 0x1d, 0x5e, 0x32, 0xfb, 0xea, - 0x7b, 0x0c, 0xe0, 0x35, 0xdc, 0x5d, 0xb7, 0x42, 0xb2, 0xbf, 0x96, 0x2d, 0x47, 0x93, 0x0b, 0x59, - 0x82, 0x70, 0x8d, 0x86, 0x05, 0x28, 0xfa, 0x44, 0x4a, 0x24, 0x1c, 0x98, 0x9c, 0x17, 0x69, 0x5a, - 0xd7, 0xa3, 0x24, 0x1e, 0x95, 0xdb, 0xe3, 0xf1, 0xcf, 0x12, 0x34, 0xcf, 0x99, 0x88, 0x43, 0x3c, - 0xcb, 0x3d, 0x68, 0x4e, 0x79, 0x70, 0xc5, 0x78, 0x76, 0x94, 0x86, 0x12, 0x1c, 0x3b, 0xe4, 0x31, - 0xd4, 0x0e, 0x03, 0xff, 0xc2, 0x9d, 0xe1, 0x5b, 0x5a, 0xf3, 0x4b, 0x3a, 0x77, 0xa4, 0x74, 0x8a, - 0x5f, 0xb4, 0x21, 0xd9, 0x86, 0x96, 0xfe, 0x65, 0xe2, 0xe5, 0xcb, 0xe3, 0xe7, 0x49, 0x93, 0x9d, - 0x13, 0x0d, 0x3f, 0x82, 0x56, 0x6e, 0xe2, 0x77, 0xaa, 0x78, 0x3f, 0x04, 0xc0, 0xd5, 0x55, 0x8c, - 0xfa, 0xd9, 0xd5, 0x37, 0xd5, 0xd1, 0x1e, 0x40, 0x53, 0xf6, 0x73, 0x4a, 0x9d, 0xd4, 0xda, 0x52, - 0x56, 0x6b, 0xcd, 0x87, 0x30, 0x38, 0xf6, 0xaf, 0xa9, 0xe7, 0x3a, 0x54, 0xb0, 0xcf, 0xd8, 0x02, - 0x43, 0xb0, 0xb2, 0x03, 0xf3, 0x1c, 0xda, 0xfa, 0x71, 0xff, 0x5a, 0x7b, 0x6c, 0xeb, 0x3d, 0x7e, - 0x73, 0x2e, 0xbe, 0x0b, 0x3d, 0xed, 0xf4, 0xc4, 0xd5, 0x99, 0x28, 0x5b, 0x15, 0xce, 0x2e, 0xdc, - 0x1b, 0xed, 0x5a, 0x8f, 0xcc, 0x67, 0xd0, 0xcf, 0x99, 0xa6, 0xc7, 0xb9, 0x62, 0x8b, 0x28, 0xf9, - 0xd1, 0x43, 0x7e, 0x27, 0x11, 0x28, 0x67, 0x11, 0x30, 0xa1, 0xab, 0x67, 0xbe, 0x60, 0xe2, 0x96, - 0xd3, 0x7d, 0x96, 0x6e, 0xe4, 0x05, 0xd3, 0xce, 0x1f, 0x41, 0x95, 0xc9, 0x93, 0xe6, 0xcb, 0x70, - 0x3e, 0x02, 0x96, 0x52, 0xaf, 0x59, 0xf0, 0x59, 0xba, 0xe0, 0x59, 0xac, 0x16, 0x7c, 0x4d, 0x5f, - 0xe6, 0xdb, 0xe9, 0x36, 0xce, 0x62, 0x71, 0xdb, 0x8d, 0x3e, 0x84, 0x81, 0x36, 0x7a, 0xce, 0x3c, - 0x26, 0xd8, 0x2d, 0x47, 0x7a, 0x04, 0xa4, 0x60, 0x76, 0x9b, 0xbb, 0xfb, 0xd0, 0x18, 0x8f, 0x4f, - 0x52, 0x6d, 0x91, 0x62, 0xcd, 0x1d, 0x68, 0x8f, 0xa9, 0x6c, 0x25, 0x1c, 0x65, 0x61, 0x40, 0x5d, - 0xa8, 0xb1, 0x4e, 0xc0, 0x64, 0x68, 0xee, 0xc3, 0xd6, 0x21, 0xb5, 0x2f, 0x5d, 0x7f, 0xf6, 0xdc, - 0x8d, 0x64, 0x2f, 0xa5, 0x67, 0x0c, 0xa1, 0xe1, 0x68, 0x81, 0x9e, 0x92, 0x8e, 0xcd, 0xf7, 0xe1, - 0x8d, 0xdc, 0x0f, 0x3e, 0xe7, 0x82, 0x26, 0xdb, 0xdc, 0x82, 0x6a, 0x24, 0x47, 0x38, 0xa3, 0x6a, - 0xa9, 0x81, 0xf9, 0x39, 0x6c, 0xe5, 0xcb, 0xab, 0xec, 0x6c, 0xf0, 0xf0, 0x49, 0xcf, 0x51, 0xca, - 0xf5, 0x1c, 0xfa, 0x28, 0xe5, 0xac, 0x5a, 0xf4, 0xa1, 0xf2, 0xeb, 0x2f, 0xc7, 0x1a, 0x83, 0xf2, - 0xd3, 0xfc, 0xa3, 0x5c, 0xbe, 0xe8, 0x4f, 0x2d, 0x5f, 0x68, 0x3c, 0x4a, 0xaf, 0xd5, 0x78, 0xac, - 0xc2, 0xe0, 0x7d, 0x18, 0x9c, 0x7a, 0x81, 0x7d, 0x75, 0xe4, 0xe7, 0xa2, 0x61, 0x40, 0x9d, 0xf9, - 0xf9, 0x60, 0x24, 0x43, 0xf3, 0x1d, 0xe8, 0x9d, 0x04, 0x36, 0xf5, 0x4e, 0x83, 0xd8, 0x17, 0x69, - 0x14, 0xf0, 0x17, 0x38, 0x6d, 0xaa, 0x06, 0xe6, 0xfb, 0xd0, 0xd5, 0x05, 0xd8, 0xbf, 0x08, 0x12, - 0xc2, 0xca, 0x4a, 0x75, 0xa9, 0xd8, 0xc6, 0x9b, 0x27, 0xd0, 0xcb, 0xcc, 0x95, 0xdf, 0x77, 0xa0, - 0xa6, 0xd4, 0xfa, 0x6c, 0xbd, 0xf4, 0x1d, 0xab, 0x2c, 0x2d, 0xad, 0x5e, 0x73, 0xa8, 0x39, 0x74, - 0xcf, 0xf0, 0x97, 0xd0, 0x23, 0xff, 0x5a, 0x39, 0x3b, 0x06, 0xa2, 0x7e, 0x1b, 0x9d, 0x30, 0xff, - 0xda, 0xe5, 0x81, 0x8f, 0xad, 0x73, 0x49, 0x37, 0x28, 0x89, 0xe3, 0x74, 0x52, 0x62, 0x61, 0x0d, - 0xc2, 0x65, 0xd1, 0xda, 0x18, 0x42, 0xf6, 0x3b, 0x8b, 0xac, 0x00, 0x9c, 0xcd, 0x03, 0xc1, 0x26, - 0xd4, 0x71, 0x12, 0x10, 0x83, 0x12, 0x1d, 0x38, 0x0e, 0xdf, 0xff, 0x7b, 0x05, 0xea, 0x1f, 0x2b, - 0x5e, 0x25, 0xbf, 0x84, 0x4e, 0xa1, 0x18, 0x93, 0x37, 0xb0, 0x69, 0x5b, 0x2e, 0xfd, 0xc3, 0x3b, - 0x2b, 0x62, 0x75, 0xae, 0x0f, 0xa0, 0x9d, 0xaf, 0x91, 0x04, 0xeb, 0x21, 0xfe, 0xea, 0x3b, 0x44, - 0x4f, 0xab, 0x05, 0xf4, 0x1c, 0xb6, 0xd6, 0x55, 0x2f, 0x72, 0x3f, 0x5b, 0x61, 0xb5, 0x72, 0x0e, - 0xdf, 0xbc, 0x4d, 0x9b, 0x54, 0xbd, 0xfa, 0xa1, 0xc7, 0xa8, 0x1f, 0x87, 0xf9, 0x1d, 0x64, 0x9f, - 0xe4, 0x31, 0x74, 0x0a, 0xfc, 0xad, 0xce, 0xb9, 0x42, 0xe9, 0xf9, 0x29, 0x8f, 0xa0, 0x8a, 0x35, - 0x83, 0x74, 0x0a, 0xc5, 0x6b, 0xd8, 0x4d, 0x87, 0x6a, 0xed, 0xa7, 0x00, 0x59, 0x6f, 0x41, 0x88, - 0xf2, 0x9b, 0xef, 0x3e, 0x86, 0x9b, 0x45, 0x59, 0xd2, 0x7f, 0x6c, 0xe0, 0x4f, 0x08, 0xb9, 0xfd, - 0xe2, 0x42, 0x69, 0x1d, 0xda, 0xff, 0x4f, 0x09, 0xea, 0xc9, 0xcf, 0xca, 0x8f, 0x61, 0x43, 0x32, - 0x3a, 0xd9, 0xcc, 0x91, 0x62, 0x52, 0x0d, 0x86, 0x5b, 0x4b, 0x42, 0xb5, 0xc0, 0x08, 0x2a, 0x2f, - 0x98, 0x50, 0x1b, 0x2a, 0x52, 0xfb, 0x70, 0xb3, 0x28, 0x4b, 0xed, 0xcf, 0xe2, 0xa2, 0xbd, 0x66, - 0xe6, 0x82, 0x7d, 0xca, 0xb9, 0x1f, 0x42, 0x4d, 0x71, 0xa6, 0x8a, 0xe5, 0x0a, 0xdb, 0x2a, 0xcc, - 0xac, 0xb2, 0xeb, 0xfe, 0x5f, 0x37, 0x00, 0xce, 0x17, 0x91, 0x60, 0xf3, 0xdf, 0xb8, 0xec, 0x15, - 0xd9, 0x85, 0x9e, 0xfe, 0xa1, 0x04, 0xdf, 0x6f, 0x92, 0x84, 0x72, 0x31, 0xc1, 0x2e, 0x30, 0xa5, - 0xde, 0x47, 0xd0, 0x3a, 0xa5, 0x37, 0xaf, 0x63, 0x57, 0xd7, 0x84, 0x9c, 0xb7, 0xc1, 0x8a, 0x52, - 0x20, 0xea, 0x9f, 0x42, 0x6f, 0x89, 0x8e, 0xf3, 0xf6, 0xf8, 0x1b, 0xc7, 0x5a, 0xba, 0x7e, 0x26, - 0x9f, 0x30, 0x45, 0x4a, 0xce, 0x4f, 0xd4, 0xcf, 0xa9, 0x75, 0x9c, 0xfd, 0xa2, 0xf8, 0xf8, 0xc1, - 0x77, 0xa7, 0xb1, 0xcc, 0x9a, 0x09, 0x67, 0x0f, 0xef, 0xae, 0xd3, 0xa4, 0x99, 0x97, 0x27, 0xce, - 0x95, 0xcc, 0x5b, 0x65, 0xd5, 0xf7, 0x00, 0x32, 0xee, 0xcc, 0xdb, 0xe3, 0xf5, 0x2e, 0xd3, 0xea, - 0x53, 0x80, 0x8c, 0x11, 0x15, 0x2a, 0x8a, 0x84, 0xaa, 0xa6, 0x2d, 0xb3, 0xe6, 0x2e, 0x34, 0x53, - 0x16, 0xcb, 0xaf, 0x81, 0x0e, 0x8a, 0xa4, 0xf8, 0xf1, 0xee, 0xef, 0x77, 0x66, 0xae, 0xb8, 0x8c, - 0xa7, 0x23, 0x3b, 0x98, 0xef, 0x5d, 0xd2, 0xe8, 0xd2, 0xb5, 0x03, 0x1e, 0xee, 0x5d, 0x4b, 0x30, - 0xec, 0x15, 0xfe, 0xb5, 0x9a, 0xd6, 0xf0, 0xf5, 0xf6, 0xe4, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, - 0x66, 0x13, 0x8f, 0x1a, 0xcd, 0x1a, 0x00, 0x00, + // 2545 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x59, 0xdb, 0x72, 0x1b, 0xc7, + 0xd1, 0x2e, 0x00, 0xc4, 0xa9, 0x71, 0x1e, 0xd2, 0xfa, 0x57, 0x90, 0xfc, 0x8b, 0x5e, 0x47, 0x32, + 0xcd, 0xd8, 0xa0, 0x45, 0xc5, 0xb1, 0x9c, 0x54, 0xe2, 0xa2, 0x29, 0x4a, 0x66, 0x4c, 0xda, 0xac, + 0x25, 0x14, 0xe7, 0x54, 0x05, 0x0f, 0x76, 0x87, 0xe0, 0x16, 0x17, 0xbb, 0x9b, 0xd9, 0x59, 0x8a, + 0xc8, 0x4d, 0xde, 0x22, 0x6f, 0x90, 0xeb, 0xdc, 0xe6, 0x2e, 0x97, 0x71, 0xe5, 0x3e, 0xaf, 0x90, + 0xe7, 0x48, 0x4d, 0xcf, 0xec, 0x09, 0x00, 0x6d, 0xb9, 0xca, 0xb9, 0xdb, 0xe9, 0xee, 0xe9, 0x99, + 0xe9, 0xf9, 0xfa, 0xeb, 0x1e, 0x00, 0xee, 0x45, 0xce, 0xd5, 0x5e, 0xe8, 0xc5, 0x33, 0xd7, 0xdf, + 0x0b, 0xa7, 0x7b, 0x53, 0x6a, 0x5f, 0x31, 0xdf, 0x19, 0x85, 0x3c, 0x10, 0x01, 0x29, 0x87, 0xd3, + 0xe1, 0x83, 0x59, 0x10, 0xcc, 0x3c, 0xb6, 0x87, 0x92, 0x69, 0x7c, 0xb1, 0x27, 0xdc, 0x39, 0x8b, + 0x04, 0x9d, 0x87, 0xca, 0x68, 0x38, 0x94, 0x1e, 0xbc, 0x60, 0xe6, 0xda, 0xd4, 0xdb, 0x73, 0x1d, + 0xe6, 0x0b, 0x57, 0x2c, 0xb4, 0xce, 0xc8, 0xeb, 0xd4, 0x2a, 0x4a, 0x63, 0xd6, 0xa1, 0x7a, 0x34, + 0x0f, 0xc5, 0xc2, 0xdc, 0x86, 0xda, 0x67, 0x8c, 0x3a, 0x8c, 0x93, 0x3b, 0x50, 0xbb, 0xc4, 0x2f, + 0xa3, 0xb4, 0x5d, 0xd9, 0x69, 0x5a, 0x7a, 0x64, 0xfe, 0x1e, 0xe0, 0x4c, 0xce, 0x39, 0xe2, 0x3c, + 0xe0, 0xe4, 0x2e, 0x34, 0x18, 0xe7, 0x13, 0xb1, 0x08, 0x99, 0x51, 0xda, 0x2e, 0xed, 0x74, 0xac, + 0x3a, 0xe3, 0x7c, 0xbc, 0x08, 0x19, 0xf9, 0x3f, 0x90, 0x9f, 0x93, 0x79, 0x34, 0x33, 0xca, 0xdb, + 0x25, 0xe9, 0x81, 0x71, 0x7e, 0x1a, 0xcd, 0x92, 0x39, 0x76, 0xe0, 0x30, 0xa3, 0xb2, 0x5d, 0xda, + 0xa9, 0xe0, 0x9c, 0xc3, 0xc0, 0x61, 0xe6, 0x5f, 0x4a, 0x50, 0x3d, 0xa3, 0xe2, 0x32, 0x22, 0x04, + 0x36, 0x78, 0x10, 0x08, 0xbd, 0x38, 0x7e, 0x93, 0x1d, 0xe8, 0xc5, 0x3e, 0x8d, 0xc5, 0xa5, 0x3c, + 0x95, 0x4d, 0x05, 0x73, 0x8c, 0x32, 0xaa, 0x97, 0xc5, 0xe4, 0x6d, 0xe8, 0x78, 0x81, 0x4d, 0xbd, + 0x49, 0x24, 0x02, 0x4e, 0x67, 0x72, 0x1d, 0x69, 0xd7, 0x46, 0xe1, 0xb9, 0x92, 0x91, 0x5d, 0x18, + 0x44, 0x8c, 0x7a, 0x93, 0x57, 0x9c, 0x86, 0xa9, 0xe1, 0x86, 0x72, 0x28, 0x15, 0x5f, 0x71, 0x1a, + 0x6a, 0x5b, 0xf3, 0x1f, 0x35, 0xa8, 0x5b, 0xec, 0x8f, 0x31, 0x8b, 0x04, 0xe9, 0x42, 0xd9, 0x75, + 0xf0, 0xb4, 0x4d, 0xab, 0xec, 0x3a, 0x64, 0x04, 0xc4, 0x62, 0xa1, 0x27, 0x97, 0x76, 0x03, 0xff, + 0xd0, 0x8b, 0x23, 0xc1, 0xb8, 0x3e, 0xf3, 0x1a, 0x0d, 0xb9, 0x0f, 0xcd, 0x20, 0x64, 0x1c, 0x65, + 0x18, 0x80, 0xa6, 0x95, 0x09, 0xe4, 0xc1, 0x43, 0x2a, 0x2e, 0x8d, 0x0d, 0x54, 0xe0, 0xb7, 0x94, + 0x39, 0x54, 0x50, 0xa3, 0xaa, 0x64, 0xf2, 0x9b, 0x98, 0x50, 0x8b, 0x98, 0xcd, 0x99, 0x30, 0x6a, + 0xdb, 0xa5, 0x9d, 0xd6, 0x3e, 0x8c, 0xc2, 0xe9, 0xe8, 0x1c, 0x25, 0x96, 0xd6, 0x90, 0xfb, 0xb0, + 0x21, 0xe3, 0x62, 0xd4, 0xd1, 0xa2, 0x21, 0x2d, 0x0e, 0x62, 0x71, 0x69, 0xa1, 0x94, 0xec, 0x43, + 0x5d, 0xdd, 0x69, 0x64, 0x34, 0xb6, 0x2b, 0x3b, 0xad, 0x7d, 0x43, 0x1a, 0xe8, 0x53, 0x8e, 0x14, + 0x0c, 0xa2, 0x23, 0x5f, 0xf0, 0x85, 0x95, 0x18, 0x92, 0xb7, 0xa0, 0x6d, 0x7b, 0x2e, 0xf3, 0xc5, + 0x44, 0x04, 0x57, 0xcc, 0x37, 0x9a, 0xb8, 0xa3, 0x96, 0x92, 0x8d, 0xa5, 0x88, 0xec, 0xc3, 0x1b, + 0x79, 0x93, 0x09, 0xb5, 0x6d, 0x16, 0x45, 0x01, 0x37, 0x00, 0x6d, 0x37, 0x73, 0xb6, 0x07, 0x5a, + 0x25, 0xdd, 0x3a, 0x6e, 0x14, 0x7a, 0x74, 0x31, 0xf1, 0xe9, 0x9c, 0x19, 0x2d, 0xe5, 0x56, 0xcb, + 0xbe, 0xa0, 0x73, 0x46, 0x1e, 0x40, 0x6b, 0x1e, 0xc4, 0xbe, 0x98, 0x84, 0x81, 0xeb, 0x0b, 0xa3, + 0x8d, 0x16, 0x80, 0xa2, 0x33, 0x29, 0x21, 0x6f, 0x82, 0x1a, 0x29, 0x30, 0x76, 0x54, 0x5c, 0x51, + 0x82, 0x70, 0x7c, 0x08, 0x5d, 0xa5, 0x4e, 0xf7, 0xd3, 0x45, 0x93, 0x0e, 0x4a, 0xd3, 0x9d, 0x7c, + 0x00, 0x4d, 0xc4, 0x83, 0xeb, 0x5f, 0x04, 0x46, 0x0f, 0xe3, 0xb6, 0x99, 0x0b, 0x8b, 0xc4, 0xc4, + 0xb1, 0x7f, 0x11, 0x58, 0x8d, 0x57, 0xfa, 0x8b, 0xfc, 0x02, 0xee, 0x15, 0xce, 0xcb, 0xd9, 0x9c, + 0xba, 0xbe, 0xeb, 0xcf, 0x26, 0x71, 0xc4, 0x22, 0xa3, 0x8f, 0x08, 0x37, 0x72, 0xa7, 0xb6, 0x12, + 0x83, 0x97, 0x11, 0x8b, 0xc8, 0x3d, 0x68, 0xaa, 0x24, 0x9d, 0xb8, 0x8e, 0x31, 0xc0, 0x2d, 0x35, + 0x94, 0xe0, 0xd8, 0x21, 0xef, 0x40, 0x2f, 0x0c, 0x3c, 0xd7, 0x5e, 0x4c, 0x82, 0x6b, 0xc6, 0xb9, + 0xeb, 0x30, 0x83, 0x6c, 0x97, 0x76, 0x1a, 0x56, 0x57, 0x89, 0xbf, 0xd4, 0xd2, 0x75, 0xa9, 0xb1, + 0x89, 0x86, 0x2b, 0xa9, 0x31, 0x02, 0xb0, 0x03, 0xdf, 0x67, 0x36, 0xc2, 0x6f, 0x0b, 0x4f, 0xd8, + 0x95, 0x27, 0x3c, 0x4c, 0xa5, 0x56, 0xce, 0x62, 0xf8, 0x1c, 0xda, 0x79, 0x28, 0x90, 0x3e, 0x54, + 0xae, 0xd8, 0x42, 0xc3, 0x5f, 0x7e, 0x92, 0x6d, 0xa8, 0x5e, 0x53, 0x2f, 0x66, 0x08, 0x79, 0x0d, + 0x44, 0x35, 0xc5, 0x52, 0x8a, 0x9f, 0x95, 0x9f, 0x96, 0xcc, 0xff, 0x54, 0x61, 0x43, 0x82, 0x8f, + 0x7c, 0x08, 0x1d, 0x8f, 0xd1, 0x88, 0x4d, 0x82, 0x50, 0x2e, 0x10, 0xa1, 0xab, 0xd6, 0x7e, 0x5f, + 0x4e, 0x3b, 0x91, 0x8a, 0x2f, 0x95, 0xdc, 0x6a, 0x7b, 0xb9, 0x91, 0x4c, 0x69, 0xd7, 0x17, 0x8c, + 0xfb, 0xd4, 0x9b, 0x60, 0x32, 0xa8, 0x04, 0x6b, 0x27, 0xc2, 0x67, 0x32, 0x29, 0x96, 0x71, 0x54, + 0x59, 0xc5, 0xd1, 0x10, 0x1a, 0x18, 0x3b, 0x97, 0x45, 0x3a, 0xd9, 0xd3, 0x31, 0xd9, 0x87, 0xc6, + 0x9c, 0x09, 0xaa, 0x73, 0x4d, 0xa6, 0xc4, 0x9d, 0x24, 0x67, 0x46, 0xa7, 0x5a, 0xa1, 0x12, 0x22, + 0xb5, 0x5b, 0xc9, 0x88, 0xda, 0x6a, 0x46, 0x0c, 0xa1, 0x91, 0x82, 0xae, 0xae, 0x6e, 0x38, 0x19, + 0x4b, 0x9a, 0x0d, 0x19, 0x77, 0x03, 0xc7, 0x68, 0x20, 0x50, 0xf4, 0x48, 0x92, 0xa4, 0x1f, 0xcf, + 0x15, 0x84, 0x9a, 0x8a, 0x24, 0xfd, 0x78, 0xbe, 0x8a, 0x18, 0x58, 0x42, 0xcc, 0x8f, 0xa0, 0x4a, + 0x3d, 0x97, 0x46, 0x98, 0x42, 0xf2, 0x66, 0x35, 0xdf, 0x8f, 0x0e, 0xa4, 0xd4, 0x52, 0x4a, 0xf2, + 0x04, 0x3a, 0x33, 0x1e, 0xc4, 0xe1, 0x04, 0x87, 0x2c, 0x32, 0xda, 0x78, 0xda, 0x65, 0xeb, 0x36, + 0x1a, 0x1d, 0x28, 0x1b, 0x99, 0x81, 0xd3, 0x20, 0xf6, 0x9d, 0x89, 0xed, 0x3a, 0x3c, 0x32, 0x3a, + 0x18, 0x3c, 0x40, 0xd1, 0xa1, 0x94, 0xc8, 0x14, 0x53, 0x29, 0x90, 0x06, 0xb8, 0x8b, 0x36, 0x1d, + 0x94, 0x9e, 0x25, 0x51, 0xfe, 0x31, 0x0c, 0x92, 0xc2, 0x94, 0x59, 0xf6, 0xd0, 0xb2, 0x9f, 0x28, + 0x52, 0xe3, 0x1d, 0xe8, 0xb3, 0x1b, 0x49, 0xa1, 0xae, 0x98, 0xcc, 0xe9, 0xcd, 0x44, 0x08, 0x4f, + 0xa7, 0x54, 0x37, 0x91, 0x9f, 0xd2, 0x9b, 0xb1, 0xf0, 0x64, 0xfe, 0xab, 0xd5, 0x31, 0xff, 0x07, + 0x58, 0x8c, 0x9a, 0x28, 0xc1, 0xfc, 0xdf, 0x85, 0x81, 0x1f, 0x4c, 0x1c, 0x76, 0x41, 0x63, 0x4f, + 0xa8, 0x75, 0x17, 0x3a, 0x99, 0x7a, 0x7e, 0xf0, 0x4c, 0xc9, 0x71, 0xd9, 0xc5, 0xf0, 0xe7, 0xd0, + 0x29, 0x5c, 0xf7, 0x1a, 0xd0, 0x6f, 0xe5, 0x41, 0xdf, 0xcc, 0x03, 0xfd, 0x5f, 0x1b, 0x00, 0x78, + 0xef, 0x6a, 0xea, 0x72, 0xb5, 0xc8, 0x83, 0xa1, 0xbc, 0x06, 0x0c, 0x94, 0x33, 0x5f, 0x68, 0xe0, + 0xea, 0xd1, 0xb7, 0x62, 0x36, 0xa9, 0x17, 0xd5, 0x5c, 0xbd, 0x78, 0x0f, 0x36, 0x24, 0x3e, 0x8d, + 0x5a, 0x46, 0xeb, 0xd9, 0x8e, 0x10, 0xc9, 0x0a, 0xc5, 0x68, 0xb5, 0x92, 0x34, 0xf5, 0xd5, 0xa4, + 0xc9, 0xa3, 0xb1, 0x51, 0x44, 0xe3, 0xdb, 0xd0, 0xb1, 0x39, 0xc3, 0xda, 0x35, 0x91, 0xcd, 0x88, + 0x46, 0x6b, 0x3b, 0x11, 0x8e, 0xdd, 0x39, 0x93, 0xf1, 0x93, 0x17, 0x07, 0xa8, 0x92, 0x9f, 0x6b, + 0xef, 0xb5, 0xb5, 0xf6, 0x5e, 0xb1, 0x13, 0xf0, 0x98, 0x66, 0x7c, 0xfc, 0xce, 0x65, 0x4d, 0xa7, + 0x90, 0x35, 0x85, 0xd4, 0xe8, 0x2e, 0xa5, 0xc6, 0x12, 0x7e, 0x7b, 0x2b, 0xf8, 0x7d, 0x0b, 0xda, + 0x32, 0x00, 0x51, 0x48, 0x6d, 0x26, 0x1d, 0xf4, 0x55, 0x20, 0x52, 0xd9, 0xb1, 0x83, 0xd9, 0x1e, + 0x4f, 0xa7, 0x8b, 0xcb, 0xc0, 0x63, 0x19, 0x61, 0xb7, 0x52, 0xd9, 0xb1, 0x23, 0xf7, 0x8b, 0x08, + 0x24, 0x88, 0x40, 0xfc, 0x1e, 0x7e, 0x04, 0xcd, 0x34, 0xea, 0xdf, 0x0b, 0x4c, 0x7f, 0x2b, 0x41, + 0x3b, 0x4f, 0x8a, 0x72, 0xf2, 0x78, 0x7c, 0x82, 0x93, 0x2b, 0x96, 0xfc, 0x94, 0xed, 0x04, 0x67, + 0x3e, 0x7b, 0x45, 0xa7, 0x9e, 0x72, 0xd0, 0xb0, 0x32, 0x81, 0xd4, 0xba, 0xbe, 0xcd, 0xd9, 0x3c, + 0x41, 0x55, 0xc5, 0xca, 0x04, 0xe4, 0x63, 0x00, 0x37, 0x8a, 0x62, 0xa6, 0x6e, 0x6e, 0x03, 0x29, + 0x63, 0x38, 0x52, 0x3d, 0xe6, 0x28, 0xe9, 0x31, 0x47, 0xe3, 0xa4, 0xc7, 0xb4, 0x9a, 0x68, 0x8d, + 0x57, 0x7a, 0x07, 0x6a, 0xf2, 0x82, 0xc6, 0x27, 0x88, 0xbc, 0x8a, 0xa5, 0x47, 0xe6, 0x9f, 0xa1, + 0xa6, 0xba, 0x90, 0xff, 0x29, 0xd1, 0xdf, 0x85, 0x86, 0xf2, 0xed, 0x3a, 0x3a, 0x57, 0xea, 0x38, + 0x3e, 0x76, 0xcc, 0x6f, 0xca, 0xd0, 0xb0, 0x58, 0x14, 0x06, 0x7e, 0xc4, 0x72, 0x5d, 0x52, 0xe9, + 0x3b, 0xbb, 0xa4, 0xf2, 0xda, 0x2e, 0x29, 0xe9, 0xbd, 0x2a, 0xb9, 0xde, 0x6b, 0x08, 0x0d, 0xce, + 0x1c, 0x97, 0x33, 0x5b, 0xe8, 0x3e, 0x2d, 0x1d, 0x4b, 0xdd, 0x2b, 0xca, 0x65, 0x79, 0x8f, 0xb0, + 0x86, 0x34, 0xad, 0x74, 0x4c, 0x1e, 0xe7, 0x9b, 0x0b, 0xd5, 0xb6, 0x6d, 0xa9, 0xe6, 0x42, 0x6d, + 0x77, 0x4d, 0x77, 0xf1, 0x24, 0x6b, 0xd2, 0xea, 0x98, 0xcd, 0x77, 0xf3, 0x13, 0xd6, 0x77, 0x69, + 0x3f, 0x58, 0xcd, 0xfe, 0xa6, 0x0c, 0xfd, 0xe5, 0xbd, 0xad, 0x41, 0xe0, 0x16, 0x54, 0x55, 0xed, + 0xd3, 0xf0, 0x15, 0x2b, 0x55, 0xaf, 0xb2, 0x44, 0x74, 0x9f, 0x2c, 0x93, 0xc6, 0x77, 0x43, 0xaf, + 0x48, 0x28, 0xef, 0x42, 0x5f, 0x86, 0x28, 0x64, 0x4e, 0xd6, 0xcf, 0x29, 0x06, 0xec, 0x69, 0x79, + 0xda, 0xd1, 0xed, 0xc2, 0x20, 0x31, 0xcd, 0xb8, 0xa1, 0x56, 0xb0, 0x3d, 0x4a, 0x28, 0xe2, 0x0e, + 0xd4, 0x2e, 0x02, 0x3e, 0xa7, 0x42, 0x93, 0xa0, 0x1e, 0x15, 0x48, 0x0e, 0xd9, 0xb6, 0xa1, 0x30, + 0x99, 0x08, 0xe5, 0x9b, 0x45, 0x92, 0x4f, 0xfa, 0x9e, 0x40, 0x16, 0x6c, 0x58, 0x8d, 0xe4, 0x1d, + 0x61, 0xfe, 0x06, 0x7a, 0x4b, 0x2d, 0xe4, 0x9a, 0x40, 0x66, 0xcb, 0x97, 0x0b, 0xcb, 0x17, 0x3c, + 0x57, 0x96, 0x3c, 0xff, 0x16, 0x06, 0x9f, 0x51, 0xdf, 0xf1, 0x98, 0xf6, 0x7f, 0xc0, 0x67, 0x91, + 0x2c, 0x86, 0xfa, 0x45, 0x33, 0xd1, 0xd5, 0xa7, 0x63, 0x35, 0xb5, 0xe4, 0xd8, 0x21, 0x0f, 0xa1, + 0xce, 0x95, 0xb5, 0x06, 0x40, 0x2b, 0xd7, 0xe3, 0x5a, 0x89, 0xce, 0xfc, 0x1a, 0x48, 0xc1, 0xb5, + 0x7c, 0xcc, 0x2c, 0xc8, 0x8e, 0x44, 0xbf, 0x02, 0x85, 0xce, 0xaa, 0x76, 0x1e, 0x93, 0x56, 0xaa, + 0x25, 0xdb, 0x50, 0x61, 0x9c, 0xeb, 0x25, 0xb0, 0xc9, 0xcc, 0x9e, 0x8e, 0x96, 0x54, 0x99, 0x7d, + 0xe8, 0x1e, 0xfb, 0xae, 0x70, 0xa9, 0xe7, 0xfe, 0x89, 0xc9, 0x9d, 0x9b, 0x4f, 0xa0, 0x97, 0x49, + 0xd4, 0x82, 0xda, 0x4d, 0xe9, 0x76, 0x37, 0x3f, 0x81, 0xc1, 0x79, 0xc8, 0x6c, 0x97, 0x7a, 0xf8, + 0x7a, 0x54, 0xd3, 0x1e, 0x40, 0x55, 0xde, 0x55, 0xc2, 0x3b, 0x4d, 0x9c, 0x88, 0x6a, 0x25, 0x37, + 0xbf, 0x06, 0x43, 0x1d, 0xef, 0xe8, 0xc6, 0x8d, 0x04, 0xf3, 0x6d, 0x76, 0x78, 0xc9, 0xec, 0xab, + 0x1f, 0x30, 0x80, 0xd7, 0x70, 0x77, 0xdd, 0x0a, 0xc9, 0xfe, 0x5a, 0xb6, 0x1c, 0x4d, 0x2e, 0x64, + 0x09, 0xc2, 0x35, 0x1a, 0x16, 0xa0, 0xe8, 0xb9, 0x94, 0x48, 0x38, 0x30, 0x39, 0x2f, 0xd2, 0xb4, + 0xae, 0x47, 0x49, 0x3c, 0x2a, 0xb7, 0xc7, 0xe3, 0xef, 0x25, 0x68, 0x9e, 0x33, 0x11, 0x87, 0x78, + 0x96, 0x7b, 0xd0, 0x9c, 0xf2, 0xe0, 0x8a, 0xf1, 0xec, 0x28, 0x0d, 0x25, 0x38, 0x76, 0xc8, 0x63, + 0xa8, 0x1d, 0x06, 0xfe, 0x85, 0x3b, 0xc3, 0xb7, 0xb4, 0xe6, 0x97, 0x74, 0xee, 0x48, 0xe9, 0x14, + 0xbf, 0x68, 0x43, 0xb2, 0x0d, 0x2d, 0xfd, 0xcb, 0xc4, 0xcb, 0x97, 0xc7, 0xcf, 0x92, 0x26, 0x3b, + 0x27, 0x1a, 0x7e, 0x0c, 0xad, 0xdc, 0xc4, 0xef, 0x55, 0xf1, 0xfe, 0x1f, 0x00, 0x57, 0x57, 0x31, + 0xea, 0x67, 0x57, 0xdf, 0x54, 0x47, 0x7b, 0x00, 0x4d, 0xd9, 0xcf, 0x29, 0x75, 0x52, 0x6b, 0x4b, + 0x59, 0xad, 0x35, 0x1f, 0xc2, 0xe0, 0xd8, 0xbf, 0xa6, 0x9e, 0xeb, 0x50, 0xc1, 0x3e, 0x67, 0x0b, + 0x0c, 0xc1, 0xca, 0x0e, 0xcc, 0x73, 0x68, 0xeb, 0xc7, 0xfd, 0x6b, 0xed, 0xb1, 0xad, 0xf7, 0xf8, + 0xed, 0xb9, 0xf8, 0x2e, 0xf4, 0xb4, 0xd3, 0x13, 0x57, 0x67, 0xa2, 0x6c, 0x55, 0x38, 0xbb, 0x70, + 0x6f, 0xb4, 0x6b, 0x3d, 0x32, 0x9f, 0x42, 0x3f, 0x67, 0x9a, 0x1e, 0xe7, 0x8a, 0x2d, 0xa2, 0xe4, + 0x47, 0x0f, 0xf9, 0x9d, 0x44, 0xa0, 0x9c, 0x45, 0xc0, 0x84, 0xae, 0x9e, 0xf9, 0x82, 0x89, 0x5b, + 0x4e, 0xf7, 0x79, 0xba, 0x91, 0x17, 0x4c, 0x3b, 0x7f, 0x04, 0x55, 0x26, 0x4f, 0x9a, 0x2f, 0xc3, + 0xf9, 0x08, 0x58, 0x4a, 0xbd, 0x66, 0xc1, 0xa7, 0xe9, 0x82, 0x67, 0xb1, 0x5a, 0xf0, 0x35, 0x7d, + 0x99, 0x6f, 0xa7, 0xdb, 0x38, 0x8b, 0xc5, 0x6d, 0x37, 0xfa, 0x10, 0x06, 0xda, 0xe8, 0x19, 0xf3, + 0x98, 0x60, 0xb7, 0x1c, 0xe9, 0x11, 0x90, 0x82, 0xd9, 0x6d, 0xee, 0xee, 0x43, 0x63, 0x3c, 0x3e, + 0x49, 0xb5, 0x45, 0x8a, 0x35, 0x77, 0xa0, 0x3d, 0xa6, 0xb2, 0x95, 0x70, 0x94, 0x85, 0x01, 0x75, + 0xa1, 0xc6, 0x3a, 0x01, 0x93, 0xa1, 0xb9, 0x0f, 0x5b, 0x87, 0xd4, 0xbe, 0x74, 0xfd, 0xd9, 0x33, + 0x37, 0x92, 0xbd, 0x94, 0x9e, 0x31, 0x84, 0x86, 0xa3, 0x05, 0x7a, 0x4a, 0x3a, 0x36, 0xdf, 0x87, + 0x37, 0x72, 0x3f, 0xf8, 0x9c, 0x0b, 0x9a, 0x6c, 0x73, 0x0b, 0xaa, 0x91, 0x1c, 0xe1, 0x8c, 0xaa, + 0xa5, 0x06, 0xe6, 0x17, 0xb0, 0x95, 0x2f, 0xaf, 0xb2, 0xb3, 0xc1, 0xc3, 0x27, 0x3d, 0x47, 0x29, + 0xd7, 0x73, 0xe8, 0xa3, 0x94, 0xb3, 0x6a, 0xd1, 0x87, 0xca, 0xaf, 0xbe, 0x1a, 0x6b, 0x0c, 0xca, + 0x4f, 0xf3, 0x0f, 0x72, 0xf9, 0xa2, 0x3f, 0xb5, 0x7c, 0xa1, 0xf1, 0x28, 0xbd, 0x56, 0xe3, 0xb1, + 0x0a, 0x83, 0xf7, 0x61, 0x70, 0xea, 0x05, 0xf6, 0xd5, 0x91, 0x9f, 0x8b, 0x86, 0x01, 0x75, 0xe6, + 0xe7, 0x83, 0x91, 0x0c, 0xcd, 0x77, 0xa0, 0x77, 0x12, 0xd8, 0xd4, 0x3b, 0x0d, 0x62, 0x5f, 0xa4, + 0x51, 0xc0, 0x5f, 0xe0, 0xb4, 0xa9, 0x1a, 0x98, 0xef, 0x43, 0x57, 0x17, 0x60, 0xff, 0x22, 0x48, + 0x08, 0x2b, 0x2b, 0xd5, 0xa5, 0x62, 0x1b, 0x6f, 0x9e, 0x40, 0x2f, 0x33, 0x57, 0x7e, 0xdf, 0x81, + 0x9a, 0x52, 0xeb, 0xb3, 0xf5, 0xd2, 0x77, 0xac, 0xb2, 0xb4, 0xb4, 0x7a, 0xcd, 0xa1, 0xce, 0x60, + 0xeb, 0x85, 0x7c, 0xe4, 0x46, 0xcf, 0x03, 0xae, 0x8d, 0x75, 0xb6, 0xd4, 0xf0, 0xf1, 0xab, 0x92, + 0x31, 0xff, 0x34, 0x46, 0x73, 0x4b, 0x6b, 0xd7, 0x78, 0x9c, 0x43, 0xf7, 0x0c, 0x7f, 0x5b, 0x3d, + 0xf2, 0xaf, 0x95, 0xaf, 0x63, 0x20, 0xea, 0xd7, 0xd6, 0x09, 0xf3, 0xaf, 0x5d, 0x1e, 0xf8, 0xd8, + 0x8c, 0x97, 0x74, 0xcb, 0x93, 0xf8, 0x4d, 0x27, 0x25, 0x16, 0xd6, 0x20, 0x5c, 0x16, 0xad, 0xbd, + 0x15, 0xc8, 0x7e, 0xb9, 0x91, 0x35, 0x85, 0xb3, 0x79, 0x20, 0xd8, 0x84, 0x3a, 0x4e, 0x92, 0x16, + 0xa0, 0x44, 0x07, 0x8e, 0xc3, 0xf7, 0xff, 0x5a, 0x81, 0xfa, 0xa7, 0x8a, 0xa9, 0xc9, 0x2f, 0xa1, + 0x53, 0x28, 0xef, 0xe4, 0x0d, 0x6c, 0x03, 0x97, 0x9b, 0x89, 0xe1, 0x9d, 0x15, 0xb1, 0x3a, 0xd7, + 0x07, 0xd0, 0xce, 0x57, 0x5d, 0x82, 0x15, 0x16, 0x7f, 0x47, 0x1e, 0xa2, 0xa7, 0xd5, 0x92, 0x7c, + 0x0e, 0x5b, 0xeb, 0xea, 0x21, 0xb9, 0x9f, 0xad, 0xb0, 0x5a, 0x8b, 0x87, 0x6f, 0xde, 0xa6, 0x4d, + 0xea, 0x68, 0xfd, 0xd0, 0x63, 0xd4, 0x8f, 0xc3, 0xfc, 0x0e, 0xb2, 0x4f, 0xf2, 0x18, 0x3a, 0x85, + 0x8a, 0xa0, 0xce, 0xb9, 0x52, 0x24, 0xf2, 0x53, 0x1e, 0x41, 0x15, 0xab, 0x10, 0xe9, 0x14, 0xca, + 0xe1, 0xb0, 0x9b, 0x0e, 0xd5, 0xda, 0x1f, 0x02, 0x64, 0xdd, 0x0a, 0x21, 0xca, 0x6f, 0xbe, 0x9f, + 0x19, 0x6e, 0x16, 0x65, 0x49, 0x47, 0xb3, 0x81, 0x3f, 0x4a, 0xe4, 0xf6, 0x8b, 0x0b, 0xa5, 0x95, + 0x6d, 0xff, 0xdf, 0x25, 0xa8, 0x27, 0x3f, 0x54, 0x3f, 0x86, 0x0d, 0x59, 0x23, 0xc8, 0x66, 0x8e, + 0x66, 0x93, 0xfa, 0x32, 0xdc, 0x5a, 0x12, 0xaa, 0x05, 0x46, 0x50, 0x79, 0xc1, 0x84, 0xda, 0x50, + 0xb1, 0x58, 0x0c, 0x37, 0x8b, 0xb2, 0xd4, 0xfe, 0x2c, 0x2e, 0xda, 0x6b, 0xae, 0x2f, 0xd8, 0xa7, + 0x2c, 0xfe, 0x11, 0xd4, 0x14, 0x0b, 0xab, 0x58, 0xae, 0xf0, 0xb7, 0xc2, 0xcc, 0x2a, 0x5f, 0xef, + 0xff, 0x73, 0x03, 0xe0, 0x7c, 0x11, 0x09, 0x36, 0xff, 0xb5, 0xcb, 0x5e, 0x91, 0x5d, 0xe8, 0xe9, + 0x9f, 0x5e, 0xf0, 0x45, 0x28, 0x69, 0x2d, 0x17, 0x13, 0xec, 0x2b, 0x53, 0x32, 0x7f, 0x04, 0xad, + 0x53, 0x7a, 0xf3, 0x3a, 0x76, 0x75, 0x4d, 0xf1, 0x79, 0x1b, 0xac, 0x51, 0x05, 0xea, 0xff, 0x29, + 0xf4, 0x96, 0x08, 0x3e, 0x6f, 0x8f, 0xbf, 0x9a, 0xac, 0x2d, 0x00, 0x4f, 0xe5, 0xa3, 0xa8, 0x48, + 0xf2, 0xf9, 0x89, 0xfa, 0x81, 0xb6, 0xae, 0x0a, 0xbc, 0x28, 0x3e, 0xa7, 0xf0, 0x25, 0x6b, 0x2c, + 0xf3, 0x70, 0x52, 0x05, 0x86, 0x77, 0xd7, 0x69, 0xd2, 0xcc, 0xcb, 0x53, 0xf1, 0x4a, 0xe6, 0xad, + 0xf2, 0xf4, 0x7b, 0x00, 0x19, 0x1b, 0xe7, 0xed, 0xf1, 0x7a, 0x97, 0x89, 0xfa, 0x43, 0x80, 0x8c, + 0x63, 0x15, 0x2a, 0x8a, 0x14, 0xad, 0xa6, 0x2d, 0xf3, 0xf0, 0x2e, 0x34, 0x53, 0x16, 0xcb, 0xaf, + 0x81, 0x0e, 0x96, 0x48, 0xf1, 0x13, 0xe8, 0x2d, 0x11, 0xef, 0xda, 0x75, 0x30, 0x3c, 0xeb, 0x18, + 0xfa, 0xd3, 0xdd, 0xdf, 0xed, 0xcc, 0x5c, 0x71, 0x19, 0x4f, 0x47, 0x76, 0x30, 0xdf, 0xbb, 0xa4, + 0xd1, 0xa5, 0x6b, 0x07, 0x3c, 0xdc, 0xbb, 0x96, 0x68, 0xda, 0x2b, 0xfc, 0x91, 0x36, 0xad, 0xe1, + 0x83, 0xf2, 0xc9, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0xe9, 0x9a, 0xc2, 0x92, 0x60, 0x1b, 0x00, + 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -3473,6 +3524,9 @@ type SystemViewClient interface { EntityInfo(ctx context.Context, in *EntityInfoArgs, opts ...grpc.CallOption) (*EntityInfoReply, error) // PluginEnv returns Vault environment information used by plugins PluginEnv(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*PluginEnvReply, error) + // GroupsForEntity returns the group membersship information for the given + // entity id + GroupsForEntity(ctx context.Context, in *EntityInfoArgs, opts ...grpc.CallOption) (*GroupsForEntityReply, error) } type systemViewClient struct { @@ -3573,6 +3627,15 @@ func (c *systemViewClient) PluginEnv(ctx context.Context, in *Empty, opts ...grp return out, nil } +func (c *systemViewClient) GroupsForEntity(ctx context.Context, in *EntityInfoArgs, opts ...grpc.CallOption) (*GroupsForEntityReply, error) { + out := new(GroupsForEntityReply) + err := c.cc.Invoke(ctx, "/pb.SystemView/GroupsForEntity", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // SystemViewServer is the server API for SystemView service. type SystemViewServer interface { // DefaultLeaseTTL returns the default lease TTL set in Vault configuration @@ -3608,6 +3671,9 @@ type SystemViewServer interface { EntityInfo(context.Context, *EntityInfoArgs) (*EntityInfoReply, error) // PluginEnv returns Vault environment information used by plugins PluginEnv(context.Context, *Empty) (*PluginEnvReply, error) + // GroupsForEntity returns the group membersship information for the given + // entity id + GroupsForEntity(context.Context, *EntityInfoArgs) (*GroupsForEntityReply, error) } // UnimplementedSystemViewServer can be embedded to have forward compatible implementations. @@ -3644,6 +3710,9 @@ func (*UnimplementedSystemViewServer) EntityInfo(ctx context.Context, req *Entit func (*UnimplementedSystemViewServer) PluginEnv(ctx context.Context, req *Empty) (*PluginEnvReply, error) { return nil, status.Errorf(codes.Unimplemented, "method PluginEnv not implemented") } +func (*UnimplementedSystemViewServer) GroupsForEntity(ctx context.Context, req *EntityInfoArgs) (*GroupsForEntityReply, error) { + return nil, status.Errorf(codes.Unimplemented, "method GroupsForEntity not implemented") +} func RegisterSystemViewServer(s *grpc.Server, srv SystemViewServer) { s.RegisterService(&_SystemView_serviceDesc, srv) @@ -3829,6 +3898,24 @@ func _SystemView_PluginEnv_Handler(srv interface{}, ctx context.Context, dec fun return interceptor(ctx, in, info, handler) } +func _SystemView_GroupsForEntity_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(EntityInfoArgs) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SystemViewServer).GroupsForEntity(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pb.SystemView/GroupsForEntity", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SystemViewServer).GroupsForEntity(ctx, req.(*EntityInfoArgs)) + } + return interceptor(ctx, in, info, handler) +} + var _SystemView_serviceDesc = grpc.ServiceDesc{ ServiceName: "pb.SystemView", HandlerType: (*SystemViewServer)(nil), @@ -3873,6 +3960,10 @@ var _SystemView_serviceDesc = grpc.ServiceDesc{ MethodName: "PluginEnv", Handler: _SystemView_PluginEnv_Handler, }, + { + MethodName: "GroupsForEntity", + Handler: _SystemView_GroupsForEntity_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "sdk/plugin/pb/backend.proto", diff --git a/vendor/github.com/hashicorp/vault/sdk/plugin/pb/backend.proto b/vendor/github.com/hashicorp/vault/sdk/plugin/pb/backend.proto index 5b23d5e23333..0c5710f69c40 100644 --- a/vendor/github.com/hashicorp/vault/sdk/plugin/pb/backend.proto +++ b/vendor/github.com/hashicorp/vault/sdk/plugin/pb/backend.proto @@ -544,6 +544,11 @@ message EntityInfoReply { string err = 2; } +message GroupsForEntityReply { + repeated logical.Group groups = 1; + string err = 2; +} + message PluginEnvReply { logical.PluginEnvironment plugin_environment = 1; string err = 2; @@ -594,6 +599,10 @@ service SystemView { // PluginEnv returns Vault environment information used by plugins rpc PluginEnv(Empty) returns (PluginEnvReply); + + // GroupsForEntity returns the group membersship information for the given + // entity id + rpc GroupsForEntity(EntityInfoArgs) returns (GroupsForEntityReply); } message Connection { diff --git a/vendor/modules.txt b/vendor/modules.txt index a0b92c8a4c38..3c98ca096ab8 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -457,6 +457,7 @@ github.com/hashicorp/vault/sdk/helper/dbtxn github.com/hashicorp/vault/sdk/helper/entropy github.com/hashicorp/vault/sdk/helper/errutil github.com/hashicorp/vault/sdk/helper/hclutil +github.com/hashicorp/vault/sdk/helper/identity github.com/hashicorp/vault/sdk/helper/jsonutil github.com/hashicorp/vault/sdk/helper/kdf github.com/hashicorp/vault/sdk/helper/keysutil From 8be22ca98f0fd61ab9609c973c8c732cfaf6bb19 Mon Sep 17 00:00:00 2001 From: Brian Kassouf Date: Thu, 2 Jan 2020 17:05:35 -0800 Subject: [PATCH 2/4] Cleanup a bit --- sdk/framework/identity.go | 19 ++++++++++++------- .../{identity => identitytpl}/templating.go | 2 +- .../templating_test.go | 2 +- sdk/logical/identity.proto | 12 ++++++------ sdk/plugin/pb/backend.proto | 4 ++-- vault/identity_store_oidc.go | 2 +- vault/policy.go | 2 +- .../hashicorp/vault/sdk/framework/identity.go | 19 ++++++++++++------- .../{identity => identitytpl}/templating.go | 2 +- .../vault/sdk/logical/identity.proto | 12 ++++++------ .../vault/sdk/plugin/pb/backend.proto | 4 ++-- vendor/modules.txt | 2 +- 12 files changed, 46 insertions(+), 36 deletions(-) rename sdk/helper/{identity => identitytpl}/templating.go (99%) rename sdk/helper/{identity => identitytpl}/templating_test.go (99%) rename vendor/github.com/hashicorp/vault/sdk/helper/{identity => identitytpl}/templating.go (99%) diff --git a/sdk/framework/identity.go b/sdk/framework/identity.go index 0745a082e8e4..ebb2aa4dcc6c 100644 --- a/sdk/framework/identity.go +++ b/sdk/framework/identity.go @@ -4,10 +4,14 @@ import ( "errors" "github.com/hashicorp/errwrap" - "github.com/hashicorp/vault/sdk/helper/identity" + "github.com/hashicorp/vault/sdk/helper/identitytpl" "github.com/hashicorp/vault/sdk/logical" ) +// PopulateIdentityTemplate takes a template string, an entity ID, and an +// instance of system view. It will query system view for information about the +// entity and use the resulting identity information to populate the template +// string. func PopulateIdentityTemplate(tpl string, entityID string, sysView logical.SystemView) (string, error) { entity, err := sysView.EntityInfo(entityID) if err != nil { @@ -22,15 +26,14 @@ func PopulateIdentityTemplate(tpl string, entityID string, sysView logical.Syste return "", err } - // TODO: Namespace bound? - input := identity.PopulateStringInput{ + input := identitytpl.PopulateStringInput{ String: tpl, Entity: entity, Groups: groups, - Mode: identity.ACLTemplating, + Mode: identitytpl.ACLTemplating, } - _, out, err := identity.PopulateString(input) + _, out, err := identitytpl.PopulateString(input) if err != nil { return "", err } @@ -38,9 +41,11 @@ func PopulateIdentityTemplate(tpl string, entityID string, sysView logical.Syste return out, nil } +// ValidateIdentityTemplate takes a template string and returns if the string is +// a valid identity template. func ValidateIdentityTemplate(tpl string) (bool, error) { - hasTemplating, _, err := identity.PopulateString(identity.PopulateStringInput{ - Mode: identity.ACLTemplating, + hasTemplating, _, err := identitytpl.PopulateString(identitytpl.PopulateStringInput{ + Mode: identitytpl.ACLTemplating, ValidityCheckOnly: true, String: tpl, }) diff --git a/sdk/helper/identity/templating.go b/sdk/helper/identitytpl/templating.go similarity index 99% rename from sdk/helper/identity/templating.go rename to sdk/helper/identitytpl/templating.go index acb6b9fb8fda..3b742dc5bdec 100644 --- a/sdk/helper/identity/templating.go +++ b/sdk/helper/identitytpl/templating.go @@ -1,4 +1,4 @@ -package identity +package identitytpl import ( "encoding/json" diff --git a/sdk/helper/identity/templating_test.go b/sdk/helper/identitytpl/templating_test.go similarity index 99% rename from sdk/helper/identity/templating_test.go rename to sdk/helper/identitytpl/templating_test.go index e1ef99e33684..6d188f096eb3 100644 --- a/sdk/helper/identity/templating_test.go +++ b/sdk/helper/identitytpl/templating_test.go @@ -1,4 +1,4 @@ -package identity +package identitytpl import ( "errors" diff --git a/sdk/logical/identity.proto b/sdk/logical/identity.proto index 75d3f60a2641..34af579b4d7a 100644 --- a/sdk/logical/identity.proto +++ b/sdk/logical/identity.proto @@ -16,13 +16,13 @@ message Entity { // Metadata represents the custom data tied to this entity map metadata = 4; - - // Disabled is true if the entity is disabled. - bool disabled = 5; + + // Disabled is true if the entity is disabled. + bool disabled = 5; - // NamespaceID is the identifier of the namespace to which this entity + // NamespaceID is the identifier of the namespace to which this entity // belongs to. - string namespace_id = 6; + string namespace_id = 6; } message Alias { @@ -42,7 +42,7 @@ message Alias { // ID is the unique identifier for the alias string ID = 5; - // NamespaceID is the identifier of the namespace to which this alias + // NamespaceID is the identifier of the namespace to which this alias // belongs. string namespace_id = 6; } diff --git a/sdk/plugin/pb/backend.proto b/sdk/plugin/pb/backend.proto index 0c5710f69c40..9536fde6ca8c 100644 --- a/sdk/plugin/pb/backend.proto +++ b/sdk/plugin/pb/backend.proto @@ -600,8 +600,8 @@ service SystemView { // PluginEnv returns Vault environment information used by plugins rpc PluginEnv(Empty) returns (PluginEnvReply); - // GroupsForEntity returns the group membersship information for the given - // entity id + // GroupsForEntity returns the group membersship information for the given + // entity id rpc GroupsForEntity(EntityInfoArgs) returns (GroupsForEntityReply); } diff --git a/vault/identity_store_oidc.go b/vault/identity_store_oidc.go index 7f5be5934fba..7f0a6e44869f 100644 --- a/vault/identity_store_oidc.go +++ b/vault/identity_store_oidc.go @@ -21,7 +21,7 @@ import ( "github.com/hashicorp/vault/helper/namespace" "github.com/hashicorp/vault/sdk/framework" "github.com/hashicorp/vault/sdk/helper/base62" - identitytpl "github.com/hashicorp/vault/sdk/helper/identity" + "github.com/hashicorp/vault/sdk/helper/identitytpl" "github.com/hashicorp/vault/sdk/helper/strutil" "github.com/hashicorp/vault/sdk/logical" "github.com/patrickmn/go-cache" diff --git a/vault/policy.go b/vault/policy.go index f90605e3dd2f..a6b5b5b3972e 100644 --- a/vault/policy.go +++ b/vault/policy.go @@ -13,7 +13,7 @@ import ( "github.com/hashicorp/vault/helper/identity" "github.com/hashicorp/vault/helper/namespace" "github.com/hashicorp/vault/sdk/helper/hclutil" - identitytpl "github.com/hashicorp/vault/sdk/helper/identity" + "github.com/hashicorp/vault/sdk/helper/identitytpl" "github.com/hashicorp/vault/sdk/helper/parseutil" "github.com/mitchellh/copystructure" ) diff --git a/vendor/github.com/hashicorp/vault/sdk/framework/identity.go b/vendor/github.com/hashicorp/vault/sdk/framework/identity.go index 0745a082e8e4..ebb2aa4dcc6c 100644 --- a/vendor/github.com/hashicorp/vault/sdk/framework/identity.go +++ b/vendor/github.com/hashicorp/vault/sdk/framework/identity.go @@ -4,10 +4,14 @@ import ( "errors" "github.com/hashicorp/errwrap" - "github.com/hashicorp/vault/sdk/helper/identity" + "github.com/hashicorp/vault/sdk/helper/identitytpl" "github.com/hashicorp/vault/sdk/logical" ) +// PopulateIdentityTemplate takes a template string, an entity ID, and an +// instance of system view. It will query system view for information about the +// entity and use the resulting identity information to populate the template +// string. func PopulateIdentityTemplate(tpl string, entityID string, sysView logical.SystemView) (string, error) { entity, err := sysView.EntityInfo(entityID) if err != nil { @@ -22,15 +26,14 @@ func PopulateIdentityTemplate(tpl string, entityID string, sysView logical.Syste return "", err } - // TODO: Namespace bound? - input := identity.PopulateStringInput{ + input := identitytpl.PopulateStringInput{ String: tpl, Entity: entity, Groups: groups, - Mode: identity.ACLTemplating, + Mode: identitytpl.ACLTemplating, } - _, out, err := identity.PopulateString(input) + _, out, err := identitytpl.PopulateString(input) if err != nil { return "", err } @@ -38,9 +41,11 @@ func PopulateIdentityTemplate(tpl string, entityID string, sysView logical.Syste return out, nil } +// ValidateIdentityTemplate takes a template string and returns if the string is +// a valid identity template. func ValidateIdentityTemplate(tpl string) (bool, error) { - hasTemplating, _, err := identity.PopulateString(identity.PopulateStringInput{ - Mode: identity.ACLTemplating, + hasTemplating, _, err := identitytpl.PopulateString(identitytpl.PopulateStringInput{ + Mode: identitytpl.ACLTemplating, ValidityCheckOnly: true, String: tpl, }) diff --git a/vendor/github.com/hashicorp/vault/sdk/helper/identity/templating.go b/vendor/github.com/hashicorp/vault/sdk/helper/identitytpl/templating.go similarity index 99% rename from vendor/github.com/hashicorp/vault/sdk/helper/identity/templating.go rename to vendor/github.com/hashicorp/vault/sdk/helper/identitytpl/templating.go index acb6b9fb8fda..3b742dc5bdec 100644 --- a/vendor/github.com/hashicorp/vault/sdk/helper/identity/templating.go +++ b/vendor/github.com/hashicorp/vault/sdk/helper/identitytpl/templating.go @@ -1,4 +1,4 @@ -package identity +package identitytpl import ( "encoding/json" diff --git a/vendor/github.com/hashicorp/vault/sdk/logical/identity.proto b/vendor/github.com/hashicorp/vault/sdk/logical/identity.proto index 75d3f60a2641..34af579b4d7a 100644 --- a/vendor/github.com/hashicorp/vault/sdk/logical/identity.proto +++ b/vendor/github.com/hashicorp/vault/sdk/logical/identity.proto @@ -16,13 +16,13 @@ message Entity { // Metadata represents the custom data tied to this entity map metadata = 4; - - // Disabled is true if the entity is disabled. - bool disabled = 5; + + // Disabled is true if the entity is disabled. + bool disabled = 5; - // NamespaceID is the identifier of the namespace to which this entity + // NamespaceID is the identifier of the namespace to which this entity // belongs to. - string namespace_id = 6; + string namespace_id = 6; } message Alias { @@ -42,7 +42,7 @@ message Alias { // ID is the unique identifier for the alias string ID = 5; - // NamespaceID is the identifier of the namespace to which this alias + // NamespaceID is the identifier of the namespace to which this alias // belongs. string namespace_id = 6; } diff --git a/vendor/github.com/hashicorp/vault/sdk/plugin/pb/backend.proto b/vendor/github.com/hashicorp/vault/sdk/plugin/pb/backend.proto index 0c5710f69c40..9536fde6ca8c 100644 --- a/vendor/github.com/hashicorp/vault/sdk/plugin/pb/backend.proto +++ b/vendor/github.com/hashicorp/vault/sdk/plugin/pb/backend.proto @@ -600,8 +600,8 @@ service SystemView { // PluginEnv returns Vault environment information used by plugins rpc PluginEnv(Empty) returns (PluginEnvReply); - // GroupsForEntity returns the group membersship information for the given - // entity id + // GroupsForEntity returns the group membersship information for the given + // entity id rpc GroupsForEntity(EntityInfoArgs) returns (GroupsForEntityReply); } diff --git a/vendor/modules.txt b/vendor/modules.txt index 3c98ca096ab8..386d2f0cc04c 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -457,7 +457,7 @@ github.com/hashicorp/vault/sdk/helper/dbtxn github.com/hashicorp/vault/sdk/helper/entropy github.com/hashicorp/vault/sdk/helper/errutil github.com/hashicorp/vault/sdk/helper/hclutil -github.com/hashicorp/vault/sdk/helper/identity +github.com/hashicorp/vault/sdk/helper/identitytpl github.com/hashicorp/vault/sdk/helper/jsonutil github.com/hashicorp/vault/sdk/helper/kdf github.com/hashicorp/vault/sdk/helper/keysutil From 9a11f0d67b3b263a38897bf52f95b2e2bce43334 Mon Sep 17 00:00:00 2001 From: Brian Kassouf Date: Fri, 3 Jan 2020 10:01:21 -0800 Subject: [PATCH 3/4] Fix length issue when groups/aliases are filtered due to ns --- vault/dynamic_system_view.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/vault/dynamic_system_view.go b/vault/dynamic_system_view.go index 5c4d398c8563..652ed6e1c03e 100644 --- a/vault/dynamic_system_view.go +++ b/vault/dynamic_system_view.go @@ -266,8 +266,8 @@ func (d dynamicSystemView) EntityInfo(entityID string) (*logical.Entity, error) } } - aliases := make([]*logical.Alias, len(entity.Aliases)) - for i, a := range entity.Aliases { + aliases := make([]*logical.Alias, 0, len(entity.Aliases)) + for _, a := range entity.Aliases { // Don't return aliases from other namespaces if a.NamespaceID != d.mountEntry.NamespaceID { @@ -281,7 +281,7 @@ func (d dynamicSystemView) EntityInfo(entityID string) (*logical.Entity, error) alias.MountType = mount.MountType } - aliases[i] = alias + aliases = append(aliases, alias) } ret.Aliases = aliases @@ -309,14 +309,14 @@ func (d dynamicSystemView) GroupsForEntity(entityID string) ([]*logical.Group, e groups = append(groups, inheritedGroups...) - logicalGroups := make([]*logical.Group, len(groups)) - for i, g := range groups { + logicalGroups := make([]*logical.Group, 0, len(groups)) + for _, g := range groups { // Don't return groups from other namespaces if g.NamespaceID != d.mountEntry.NamespaceID { continue } - logicalGroups[i] = identity.ToSDKGroup(g) + logicalGroups = append(logicalGroups, identity.ToSDKGroup(g)) } return logicalGroups, nil From a0506cd4b8533b81c26bd2aa824e497b5321f97e Mon Sep 17 00:00:00 2001 From: Brian Kassouf Date: Fri, 3 Jan 2020 11:19:24 -0800 Subject: [PATCH 4/4] review feedback --- sdk/framework/identity_test.go | 14 +++++++------- sdk/plugin/pb/backend.pb.go | 4 ++-- sdk/plugin/pb/backend.proto | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/sdk/framework/identity_test.go b/sdk/framework/identity_test.go index 8459dd35346b..cb71eefdf9d8 100644 --- a/sdk/framework/identity_test.go +++ b/sdk/framework/identity_test.go @@ -18,12 +18,12 @@ func TestIdentityTemplating(t *testing.T) { MountAccessor: "test_mount", MountType: "secret", Metadata: map[string]string{ - "alias-metadata": "metadata-value", + "alias-metadata": "alias-metadata-value", }, }, }, Metadata: map[string]string{ - "entity-metadata": "metadata-value", + "entity-metadata": "entity-metadata-value", }, }, GroupsVal: []*logical.Group{ @@ -31,7 +31,7 @@ func TestIdentityTemplating(t *testing.T) { ID: "group1-id", Name: "group1", Metadata: map[string]string{ - "group-metadata": "metadata-value", + "group-metadata": "group-metadata-value", }, }, }, @@ -51,7 +51,7 @@ func TestIdentityTemplating(t *testing.T) { }, { tpl: "{{identity.entity.metadata.entity-metadata}}", - expected: "metadata-value", + expected: "entity-metadata-value", }, { tpl: "{{identity.entity.aliases.test_mount.id}}", @@ -67,7 +67,7 @@ func TestIdentityTemplating(t *testing.T) { }, { tpl: "{{identity.entity.aliases.test_mount.metadata.alias-metadata}}", - expected: "metadata-value", + expected: "alias-metadata-value", }, { tpl: "{{identity.groups.ids.group1-id.name}}", @@ -79,11 +79,11 @@ func TestIdentityTemplating(t *testing.T) { }, { tpl: "{{identity.groups.names.group1.metadata.group-metadata}}", - expected: "metadata-value", + expected: "group-metadata-value", }, { tpl: "{{identity.groups.ids.group1-id.metadata.group-metadata}}", - expected: "metadata-value", + expected: "group-metadata-value", }, } diff --git a/sdk/plugin/pb/backend.pb.go b/sdk/plugin/pb/backend.pb.go index 8c7f57c1025e..efd386b8eb00 100644 --- a/sdk/plugin/pb/backend.pb.go +++ b/sdk/plugin/pb/backend.pb.go @@ -3524,7 +3524,7 @@ type SystemViewClient interface { EntityInfo(ctx context.Context, in *EntityInfoArgs, opts ...grpc.CallOption) (*EntityInfoReply, error) // PluginEnv returns Vault environment information used by plugins PluginEnv(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*PluginEnvReply, error) - // GroupsForEntity returns the group membersship information for the given + // GroupsForEntity returns the group membership information for the given // entity id GroupsForEntity(ctx context.Context, in *EntityInfoArgs, opts ...grpc.CallOption) (*GroupsForEntityReply, error) } @@ -3671,7 +3671,7 @@ type SystemViewServer interface { EntityInfo(context.Context, *EntityInfoArgs) (*EntityInfoReply, error) // PluginEnv returns Vault environment information used by plugins PluginEnv(context.Context, *Empty) (*PluginEnvReply, error) - // GroupsForEntity returns the group membersship information for the given + // GroupsForEntity returns the group membership information for the given // entity id GroupsForEntity(context.Context, *EntityInfoArgs) (*GroupsForEntityReply, error) } diff --git a/sdk/plugin/pb/backend.proto b/sdk/plugin/pb/backend.proto index 9536fde6ca8c..7b910ea0f0dc 100644 --- a/sdk/plugin/pb/backend.proto +++ b/sdk/plugin/pb/backend.proto @@ -600,7 +600,7 @@ service SystemView { // PluginEnv returns Vault environment information used by plugins rpc PluginEnv(Empty) returns (PluginEnvReply); - // GroupsForEntity returns the group membersship information for the given + // GroupsForEntity returns the group membership information for the given // entity id rpc GroupsForEntity(EntityInfoArgs) returns (GroupsForEntityReply); }