mirror of
https://github.com/hashicorp/vault.git
synced 2026-02-03 20:40:45 -05:00
Sync SCIM related files to CE/main (#11037)
This commit is contained in:
parent
ff96dceedd
commit
bfbd6a9a93
14 changed files with 1041 additions and 351 deletions
|
|
@ -300,6 +300,18 @@ func (c *Logical) addExtraHeaders(r *Request, headers http.Header) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (c *Logical) PatchRaw(path string, data []byte) (*Response, error) {
|
||||
return c.PatchRawWithContext(context.Background(), path, data)
|
||||
}
|
||||
|
||||
func (c *Logical) PatchRawWithContext(ctx context.Context, path string, data []byte) (*Response, error) {
|
||||
r := c.c.NewRequest(http.MethodPatch, "/v1/"+path)
|
||||
r.Headers.Set("Content-Type", "application/scim+json")
|
||||
r.BodyBytes = data
|
||||
|
||||
return c.writeRaw(ctx, r)
|
||||
}
|
||||
|
||||
// Recover recovers the data at the given Vault path from a loaded snapshot.
|
||||
// The snapshotID parameter is the ID of the loaded snapshot
|
||||
func (c *Logical) Recover(ctx context.Context, path string, snapshotID string) (*Secret, error) {
|
||||
|
|
|
|||
|
|
@ -79,7 +79,13 @@ type Group struct {
|
|||
// belongs to. Do not return this value over the API when reading the
|
||||
// group.
|
||||
// @inject_tag: sentinel:"-"
|
||||
NamespaceID string `protobuf:"bytes,13,opt,name=namespace_id,json=namespaceID,proto3" json:"namespace_id,omitempty" sentinel:"-"`
|
||||
NamespaceID string `protobuf:"bytes,13,opt,name=namespace_id,json=namespaceID,proto3" json:"namespace_id,omitempty" sentinel:"-"`
|
||||
// ScimClientID records the unique identifier of the SCIM client that
|
||||
// originally created this Group. This establishes a strict ownership model,
|
||||
// ensuring that authoritative lifecycle operations (like updates and deletes by
|
||||
// an IGA) can only be performed by the client that owns the resource.
|
||||
// @inject_tag: sentinel:"-"
|
||||
ScimClientID string `protobuf:"bytes,14,opt,name=scim_client_id,json=scimClientId,proto3" json:"scim_client_id,omitempty" sentinel:"-"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
|
@ -205,6 +211,13 @@ func (x *Group) GetNamespaceID() string {
|
|||
return ""
|
||||
}
|
||||
|
||||
func (x *Group) GetScimClientID() string {
|
||||
if x != nil {
|
||||
return x.ScimClientID
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// LocalAliases holds the aliases belonging to an entity that are local to the
|
||||
// cluster.
|
||||
type LocalAliases struct {
|
||||
|
|
@ -312,7 +325,20 @@ type Entity struct {
|
|||
// belongs to. Do not return this value over the API when reading the
|
||||
// entity.
|
||||
// @inject_tag: sentinel:"-"
|
||||
NamespaceID string `protobuf:"bytes,12,opt,name=namespace_id,json=namespaceID,proto3" json:"namespace_id,omitempty" sentinel:"-"`
|
||||
NamespaceID string `protobuf:"bytes,12,opt,name=namespace_id,json=namespaceID,proto3" json:"namespace_id,omitempty" sentinel:"-"`
|
||||
// ExternalID stores the `externalId` provided by a SCIM client.
|
||||
// This field serves as the canonical correlation key, linking this Vault Entity
|
||||
// to its representation in the external identity management system. It is
|
||||
// crucial for preventing the creation of duplicate entities when multiple
|
||||
// SCIM clients provision the same user.
|
||||
// @inject_tag: sentinel:"-"
|
||||
ExternalID string `protobuf:"bytes,13,opt,name=external_id,json=externalId,proto3" json:"external_id,omitempty" sentinel:"-"`
|
||||
// ScimClientID records the unique identifier of the SCIM client that
|
||||
// originally created this Entity. This establishes a strict ownership model,
|
||||
// ensuring that authoritative lifecycle operations (like updates and deletes by
|
||||
// an IGA) can only be performed by the client that owns the resource.
|
||||
// @inject_tag: sentinel:"-"
|
||||
ScimClientID string `protobuf:"bytes,14,opt,name=scim_client_id,json=scimClientId,proto3" json:"scim_client_id,omitempty" sentinel:"-"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
|
@ -431,6 +457,20 @@ func (x *Entity) GetNamespaceID() string {
|
|||
return ""
|
||||
}
|
||||
|
||||
func (x *Entity) GetExternalID() string {
|
||||
if x != nil {
|
||||
return x.ExternalID
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Entity) GetScimClientID() string {
|
||||
if x != nil {
|
||||
return x.ScimClientID
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// Alias represents the alias that gets stored inside of the
|
||||
// entity object in storage and also represents in an in-memory index of an
|
||||
// alias object.
|
||||
|
|
@ -495,8 +535,14 @@ type Alias struct {
|
|||
// during invalidation of local aliases in performance standbys.
|
||||
// @inject_tag: sentinel:"-"
|
||||
LocalBucketKey string `protobuf:"bytes,14,opt,name=local_bucket_key,json=localBucketKey,proto3" json:"local_bucket_key,omitempty" sentinel:"-"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
// ScimClientID records the unique identifier of the SCIM client that
|
||||
// originally created this Alias. This establishes a strict ownership model,
|
||||
// ensuring that authoritative lifecycle operations (like updates and deletes by
|
||||
// an IGA) can only be performed by the client that owns the resource.
|
||||
// @inject_tag: sentinel:"-"
|
||||
ScimClientID string `protobuf:"bytes,15,opt,name=scim_client_id,json=scimClientId,proto3" json:"scim_client_id,omitempty" sentinel:"-"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *Alias) Reset() {
|
||||
|
|
@ -627,6 +673,94 @@ func (x *Alias) GetLocalBucketKey() string {
|
|||
return ""
|
||||
}
|
||||
|
||||
func (x *Alias) GetScimClientID() string {
|
||||
if x != nil {
|
||||
return x.ScimClientID
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// ScimConfig defines the stored configuration for a single SCIM client.
|
||||
// This configuration links a client's identity within Vault to its specific
|
||||
// role and capabilities within the SCIM server.
|
||||
type ScimConfig struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
// ClientID is a unique, user-defined identifier for this specific SCIM
|
||||
// client configuration (e.g., 'Okta-Prod', 'SailPoint-Dev').
|
||||
ClientID string `protobuf:"bytes,1,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty"`
|
||||
// ClientRole defines the client's function and authoritative power.
|
||||
// It must be either "IGA" (authoritative) or "IDP" (standard).
|
||||
ClientRole string `protobuf:"bytes,2,opt,name=client_role,json=clientRole,proto3" json:"client_role,omitempty"`
|
||||
// AccessGrantPrincipal is the Vault Entity ID that represents the SCIM
|
||||
// client application itself. This is the principal that will be granted the
|
||||
// necessary permissions to perform SCIM operations.
|
||||
AccessGrantPrincipal string `protobuf:"bytes,3,opt,name=access_grant_principal,json=accessGrantPrincipal,proto3" json:"access_grant_principal,omitempty"`
|
||||
// AliasMountAccessor is an optional field that specifies the mount accessor
|
||||
// of an auth method where login aliases should be created for provisioned users.
|
||||
// This is typically used for clients with the 'IDP' role.
|
||||
AliasMountAccessor string `protobuf:"bytes,4,opt,name=alias_mount_accessor,json=aliasMountAccessor,proto3" json:"alias_mount_accessor,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ScimConfig) Reset() {
|
||||
*x = ScimConfig{}
|
||||
mi := &file_helper_identity_types_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *ScimConfig) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ScimConfig) ProtoMessage() {}
|
||||
|
||||
func (x *ScimConfig) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_helper_identity_types_proto_msgTypes[4]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ScimConfig.ProtoReflect.Descriptor instead.
|
||||
func (*ScimConfig) Descriptor() ([]byte, []int) {
|
||||
return file_helper_identity_types_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
func (x *ScimConfig) GetClientID() string {
|
||||
if x != nil {
|
||||
return x.ClientID
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ScimConfig) GetClientRole() string {
|
||||
if x != nil {
|
||||
return x.ClientRole
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ScimConfig) GetAccessGrantPrincipal() string {
|
||||
if x != nil {
|
||||
return x.AccessGrantPrincipal
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ScimConfig) GetAliasMountAccessor() string {
|
||||
if x != nil {
|
||||
return x.AliasMountAccessor
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// Deprecated. Retained for backwards compatibility.
|
||||
type EntityStorageEntry struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
|
|
@ -646,7 +780,7 @@ type EntityStorageEntry struct {
|
|||
|
||||
func (x *EntityStorageEntry) Reset() {
|
||||
*x = EntityStorageEntry{}
|
||||
mi := &file_helper_identity_types_proto_msgTypes[4]
|
||||
mi := &file_helper_identity_types_proto_msgTypes[5]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
|
@ -658,7 +792,7 @@ func (x *EntityStorageEntry) String() string {
|
|||
func (*EntityStorageEntry) ProtoMessage() {}
|
||||
|
||||
func (x *EntityStorageEntry) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_helper_identity_types_proto_msgTypes[4]
|
||||
mi := &file_helper_identity_types_proto_msgTypes[5]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
|
|
@ -671,7 +805,7 @@ func (x *EntityStorageEntry) ProtoReflect() protoreflect.Message {
|
|||
|
||||
// Deprecated: Use EntityStorageEntry.ProtoReflect.Descriptor instead.
|
||||
func (*EntityStorageEntry) Descriptor() ([]byte, []int) {
|
||||
return file_helper_identity_types_proto_rawDescGZIP(), []int{4}
|
||||
return file_helper_identity_types_proto_rawDescGZIP(), []int{5}
|
||||
}
|
||||
|
||||
func (x *EntityStorageEntry) GetPersonas() []*PersonaIndexEntry {
|
||||
|
|
@ -763,7 +897,7 @@ type PersonaIndexEntry struct {
|
|||
|
||||
func (x *PersonaIndexEntry) Reset() {
|
||||
*x = PersonaIndexEntry{}
|
||||
mi := &file_helper_identity_types_proto_msgTypes[5]
|
||||
mi := &file_helper_identity_types_proto_msgTypes[6]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
|
@ -775,7 +909,7 @@ func (x *PersonaIndexEntry) String() string {
|
|||
func (*PersonaIndexEntry) ProtoMessage() {}
|
||||
|
||||
func (x *PersonaIndexEntry) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_helper_identity_types_proto_msgTypes[5]
|
||||
mi := &file_helper_identity_types_proto_msgTypes[6]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
|
|
@ -788,7 +922,7 @@ func (x *PersonaIndexEntry) ProtoReflect() protoreflect.Message {
|
|||
|
||||
// Deprecated: Use PersonaIndexEntry.ProtoReflect.Descriptor instead.
|
||||
func (*PersonaIndexEntry) Descriptor() ([]byte, []int) {
|
||||
return file_helper_identity_types_proto_rawDescGZIP(), []int{5}
|
||||
return file_helper_identity_types_proto_rawDescGZIP(), []int{6}
|
||||
}
|
||||
|
||||
func (x *PersonaIndexEntry) GetID() string {
|
||||
|
|
@ -870,7 +1004,7 @@ var file_helper_identity_types_proto_rawDesc = string([]byte{
|
|||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61,
|
||||
0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72,
|
||||
0x2f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2f, 0x6d, 0x66, 0x61, 0x2f, 0x74, 0x79,
|
||||
0x70, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xbc, 0x04, 0x0a, 0x05, 0x47, 0x72,
|
||||
0x70, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe2, 0x04, 0x0a, 0x05, 0x47, 0x72,
|
||||
0x6f, 0x75, 0x70, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6f, 0x6c, 0x69, 0x63,
|
||||
|
|
@ -902,178 +1036,198 @@ var file_helper_identity_types_proto_rawDesc = string([]byte{
|
|||
0x6c, 0x69, 0x61, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x0c, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x6e, 0x61, 0x6d, 0x65,
|
||||
0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b,
|
||||
0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64, 0x1a, 0x3b, 0x0a, 0x0d, 0x4d,
|
||||
0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03,
|
||||
0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14,
|
||||
0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76,
|
||||
0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x39, 0x0a, 0x0c, 0x4c, 0x6f, 0x63, 0x61,
|
||||
0x6c, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x12, 0x29, 0x0a, 0x07, 0x61, 0x6c, 0x69, 0x61,
|
||||
0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x69, 0x64, 0x65, 0x6e,
|
||||
0x74, 0x69, 0x74, 0x79, 0x2e, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x07, 0x61, 0x6c, 0x69, 0x61,
|
||||
0x73, 0x65, 0x73, 0x22, 0x8c, 0x05, 0x0a, 0x06, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x29,
|
||||
0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x0e, 0x73,
|
||||
0x63, 0x69, 0x6d, 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x0e, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x0c, 0x73, 0x63, 0x69, 0x6d, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49,
|
||||
0x64, 0x1a, 0x3b, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74,
|
||||
0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x39,
|
||||
0x0a, 0x0c, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x12, 0x29,
|
||||
0x0a, 0x07, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32,
|
||||
0x0f, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2e, 0x41, 0x6c, 0x69, 0x61, 0x73,
|
||||
0x52, 0x07, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d,
|
||||
0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3a, 0x0a,
|
||||
0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32,
|
||||
0x1e, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74,
|
||||
0x79, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52,
|
||||
0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x3f, 0x0a, 0x0d, 0x63, 0x72, 0x65,
|
||||
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b,
|
||||
0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
|
||||
0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x63, 0x72,
|
||||
0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x44, 0x0a, 0x10, 0x6c, 0x61,
|
||||
0x73, 0x74, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x06,
|
||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70,
|
||||
0x52, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65,
|
||||
0x12, 0x2a, 0x0a, 0x11, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x64, 0x5f, 0x65, 0x6e, 0x74, 0x69, 0x74,
|
||||
0x79, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x6d, 0x65, 0x72,
|
||||
0x67, 0x65, 0x64, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x64, 0x73, 0x12, 0x1a, 0x0a, 0x08,
|
||||
0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08,
|
||||
0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x75, 0x63, 0x6b,
|
||||
0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x62, 0x75,
|
||||
0x63, 0x6b, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x41, 0x0a, 0x0b, 0x6d, 0x66, 0x61, 0x5f, 0x73,
|
||||
0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x69,
|
||||
0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2e, 0x4d,
|
||||
0x66, 0x61, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a,
|
||||
0x6d, 0x66, 0x61, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x69,
|
||||
0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x64, 0x69,
|
||||
0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70,
|
||||
0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6e, 0x61,
|
||||
0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64, 0x1a, 0x3b, 0x0a, 0x0d, 0x4d, 0x65, 0x74,
|
||||
0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65,
|
||||
0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05,
|
||||
0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c,
|
||||
0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x4a, 0x0a, 0x0f, 0x4d, 0x66, 0x61, 0x53, 0x65, 0x63,
|
||||
0x72, 0x65, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x21, 0x0a, 0x05, 0x76,
|
||||
0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x6d, 0x66, 0x61,
|
||||
0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02,
|
||||
0x38, 0x01, 0x22, 0xe1, 0x05, 0x0a, 0x05, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x0e, 0x0a, 0x02,
|
||||
0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x21, 0x0a, 0x0c,
|
||||
0x63, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x0b, 0x63, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x49, 0x64, 0x12,
|
||||
0x1d, 0x0a, 0x0a, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x25,
|
||||
0x0a, 0x0e, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72,
|
||||
0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x63, 0x63,
|
||||
0x65, 0x73, 0x73, 0x6f, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x70,
|
||||
0x61, 0x74, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x6f, 0x75, 0x6e, 0x74,
|
||||
0x50, 0x61, 0x74, 0x68, 0x12, 0x39, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
|
||||
0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74,
|
||||
0x79, 0x2e, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
|
||||
0x52, 0x07, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x22, 0xd3, 0x05, 0x0a, 0x06, 0x45, 0x6e,
|
||||
0x74, 0x69, 0x74, 0x79, 0x12, 0x29, 0x0a, 0x07, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x18,
|
||||
0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79,
|
||||
0x2e, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x07, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x12,
|
||||
0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12,
|
||||
0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e,
|
||||
0x61, 0x6d, 0x65, 0x12, 0x3a, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18,
|
||||
0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79,
|
||||
0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
|
||||
0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12,
|
||||
0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e,
|
||||
0x61, 0x6d, 0x65, 0x12, 0x3f, 0x0a, 0x0d, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f,
|
||||
0x74, 0x69, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f,
|
||||
0x3f, 0x0a, 0x0d, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65,
|
||||
0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61,
|
||||
0x6d, 0x70, 0x52, 0x0c, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65,
|
||||
0x12, 0x44, 0x0a, 0x10, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f,
|
||||
0x74, 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f,
|
||||
0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d,
|
||||
0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x54, 0x69, 0x6d, 0x65, 0x12, 0x44, 0x0a, 0x10, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x75, 0x70, 0x64,
|
||||
0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a,
|
||||
0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
|
||||
0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0e, 0x6c, 0x61, 0x73, 0x74,
|
||||
0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x39, 0x0a, 0x19, 0x6d, 0x65,
|
||||
0x72, 0x67, 0x65, 0x64, 0x5f, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x63, 0x61, 0x6e, 0x6f, 0x6e, 0x69,
|
||||
0x63, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x09, 0x52, 0x16, 0x6d,
|
||||
0x65, 0x72, 0x67, 0x65, 0x64, 0x46, 0x72, 0x6f, 0x6d, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63,
|
||||
0x61, 0x6c, 0x49, 0x64, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61,
|
||||
0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6e, 0x61, 0x6d,
|
||||
0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64, 0x12, 0x4c, 0x0a, 0x0f, 0x63, 0x75, 0x73, 0x74,
|
||||
0x6f, 0x6d, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x0c, 0x20, 0x03, 0x28,
|
||||
0x0b, 0x32, 0x23, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2e, 0x41, 0x6c, 0x69,
|
||||
0x61, 0x73, 0x2e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
|
||||
0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x4d, 0x65,
|
||||
0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x18,
|
||||
0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x12, 0x28, 0x0a, 0x10,
|
||||
0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79,
|
||||
0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x42, 0x75, 0x63,
|
||||
0x6b, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x1a, 0x3b, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61,
|
||||
0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x55, 0x70, 0x64, 0x61,
|
||||
0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x2a, 0x0a, 0x11, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x64,
|
||||
0x5f, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28,
|
||||
0x09, 0x52, 0x0f, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x64, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49,
|
||||
0x64, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x18, 0x08,
|
||||
0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x12, 0x1d,
|
||||
0x0a, 0x0a, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x09, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x09, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x41, 0x0a,
|
||||
0x0b, 0x6d, 0x66, 0x61, 0x5f, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x18, 0x0a, 0x20, 0x03,
|
||||
0x28, 0x0b, 0x32, 0x20, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2e, 0x45, 0x6e,
|
||||
0x74, 0x69, 0x74, 0x79, 0x2e, 0x4d, 0x66, 0x61, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x45,
|
||||
0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x6d, 0x66, 0x61, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73,
|
||||
0x12, 0x1a, 0x0a, 0x08, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x0b, 0x20, 0x01,
|
||||
0x28, 0x08, 0x52, 0x08, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x21, 0x0a, 0x0c,
|
||||
0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x0c, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x0b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64, 0x12,
|
||||
0x1f, 0x0a, 0x0b, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x0d,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x64,
|
||||
0x12, 0x24, 0x0a, 0x0e, 0x73, 0x63, 0x69, 0x6d, 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f,
|
||||
0x69, 0x64, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x73, 0x63, 0x69, 0x6d, 0x43, 0x6c,
|
||||
0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x1a, 0x3b, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61,
|
||||
0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c,
|
||||
0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a,
|
||||
0x02, 0x38, 0x01, 0x1a, 0x41, 0x0a, 0x13, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x4d, 0x65, 0x74,
|
||||
0x02, 0x38, 0x01, 0x1a, 0x4a, 0x0a, 0x0f, 0x4d, 0x66, 0x61, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74,
|
||||
0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x21, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75,
|
||||
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x6d, 0x66, 0x61, 0x2e, 0x53, 0x65,
|
||||
0x63, 0x72, 0x65, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22,
|
||||
0x87, 0x06, 0x0a, 0x05, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x61, 0x6e,
|
||||
0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x0b, 0x63, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a,
|
||||
0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x09, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x6d,
|
||||
0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x18, 0x04, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x0d, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73,
|
||||
0x6f, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x70, 0x61, 0x74, 0x68,
|
||||
0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x50, 0x61, 0x74,
|
||||
0x68, 0x12, 0x39, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x06, 0x20,
|
||||
0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2e, 0x41,
|
||||
0x6c, 0x69, 0x61, 0x73, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74,
|
||||
0x72, 0x79, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04,
|
||||
0x6e, 0x61, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65,
|
||||
0x12, 0x3f, 0x0a, 0x0d, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d,
|
||||
0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74,
|
||||
0x61, 0x6d, 0x70, 0x52, 0x0c, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d,
|
||||
0x65, 0x12, 0x44, 0x0a, 0x10, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65,
|
||||
0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f,
|
||||
0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69,
|
||||
0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x55, 0x70, 0x64,
|
||||
0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x39, 0x0a, 0x19, 0x6d, 0x65, 0x72, 0x67, 0x65,
|
||||
0x64, 0x5f, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x63, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c,
|
||||
0x5f, 0x69, 0x64, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x09, 0x52, 0x16, 0x6d, 0x65, 0x72, 0x67,
|
||||
0x65, 0x64, 0x46, 0x72, 0x6f, 0x6d, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x49,
|
||||
0x64, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f,
|
||||
0x69, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70,
|
||||
0x61, 0x63, 0x65, 0x49, 0x64, 0x12, 0x4c, 0x0a, 0x0f, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f,
|
||||
0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23,
|
||||
0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2e, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x2e,
|
||||
0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e,
|
||||
0x74, 0x72, 0x79, 0x52, 0x0e, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x4d, 0x65, 0x74, 0x61, 0x64,
|
||||
0x61, 0x74, 0x61, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x18, 0x0d, 0x20, 0x01,
|
||||
0x28, 0x08, 0x52, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x12, 0x28, 0x0a, 0x10, 0x6c, 0x6f, 0x63,
|
||||
0x61, 0x6c, 0x5f, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x0e, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x0e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74,
|
||||
0x4b, 0x65, 0x79, 0x12, 0x24, 0x0a, 0x0e, 0x73, 0x63, 0x69, 0x6d, 0x5f, 0x63, 0x6c, 0x69, 0x65,
|
||||
0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x73, 0x63, 0x69,
|
||||
0x6d, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x1a, 0x3b, 0x0a, 0x0d, 0x4d, 0x65, 0x74,
|
||||
0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65,
|
||||
0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05,
|
||||
0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c,
|
||||
0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x88, 0x05, 0x0a, 0x12, 0x45, 0x6e, 0x74, 0x69, 0x74,
|
||||
0x79, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x37, 0x0a,
|
||||
0x08, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32,
|
||||
0x1b, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2e, 0x50, 0x65, 0x72, 0x73, 0x6f,
|
||||
0x6e, 0x61, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x70, 0x65,
|
||||
0x72, 0x73, 0x6f, 0x6e, 0x61, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x46, 0x0a, 0x08, 0x6d, 0x65,
|
||||
0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x69,
|
||||
0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x53, 0x74,
|
||||
0x6f, 0x72, 0x61, 0x67, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64,
|
||||
0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61,
|
||||
0x74, 0x61, 0x12, 0x3f, 0x0a, 0x0d, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74,
|
||||
0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
|
||||
0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65,
|
||||
0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54,
|
||||
0x69, 0x6d, 0x65, 0x12, 0x44, 0x0a, 0x10, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x75, 0x70, 0x64, 0x61,
|
||||
0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e,
|
||||
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
|
||||
0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x55,
|
||||
0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x2a, 0x0a, 0x11, 0x6d, 0x65, 0x72,
|
||||
0x67, 0x65, 0x64, 0x5f, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x07,
|
||||
0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x64, 0x45, 0x6e, 0x74, 0x69,
|
||||
0x74, 0x79, 0x49, 0x64, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65,
|
||||
0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65,
|
||||
0x73, 0x12, 0x26, 0x0a, 0x0f, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x5f,
|
||||
0x68, 0x61, 0x73, 0x68, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x62, 0x75, 0x63, 0x6b,
|
||||
0x65, 0x74, 0x4b, 0x65, 0x79, 0x48, 0x61, 0x73, 0x68, 0x12, 0x4d, 0x0a, 0x0b, 0x6d, 0x66, 0x61,
|
||||
0x5f, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c,
|
||||
0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79,
|
||||
0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x4d, 0x66, 0x61,
|
||||
0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x6d, 0x66,
|
||||
0x61, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x1a, 0x3b, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61,
|
||||
0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76,
|
||||
0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75,
|
||||
0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x4a, 0x0a, 0x0f, 0x4d, 0x66, 0x61, 0x53, 0x65, 0x63, 0x72,
|
||||
0x65, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x21, 0x0a, 0x05, 0x76, 0x61,
|
||||
0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x6d, 0x66, 0x61, 0x2e,
|
||||
0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38,
|
||||
0x01, 0x22, 0xf9, 0x03, 0x0a, 0x11, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x49, 0x6e, 0x64,
|
||||
0x65, 0x78, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x65, 0x6e, 0x74, 0x69, 0x74,
|
||||
0x79, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x6e, 0x74, 0x69,
|
||||
0x74, 0x79, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x74, 0x79,
|
||||
0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x54,
|
||||
0x79, 0x70, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x61, 0x63, 0x63,
|
||||
0x65, 0x73, 0x73, 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6d, 0x6f, 0x75,
|
||||
0x6e, 0x74, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x6f,
|
||||
0x75, 0x6e, 0x74, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09,
|
||||
0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x50, 0x61, 0x74, 0x68, 0x12, 0x45, 0x0a, 0x08, 0x6d, 0x65, 0x74,
|
||||
0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x69, 0x64,
|
||||
0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2e, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x49, 0x6e,
|
||||
0x64, 0x65, 0x78, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
|
||||
0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
|
||||
0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
|
||||
0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3f, 0x0a, 0x0d, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f,
|
||||
0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69,
|
||||
0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x44, 0x0a, 0x10, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x75, 0x70,
|
||||
0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32,
|
||||
0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
|
||||
0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0e, 0x6c, 0x61, 0x73,
|
||||
0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x33, 0x0a, 0x16, 0x6d,
|
||||
0x65, 0x72, 0x67, 0x65, 0x64, 0x5f, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x65, 0x6e, 0x74, 0x69, 0x74,
|
||||
0x79, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x09, 0x52, 0x13, 0x6d, 0x65, 0x72,
|
||||
0x67, 0x65, 0x64, 0x46, 0x72, 0x6f, 0x6d, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x64, 0x73,
|
||||
0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x41, 0x0a, 0x13, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d,
|
||||
0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a,
|
||||
0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12,
|
||||
0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05,
|
||||
0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xb2, 0x01, 0x0a, 0x0a, 0x53, 0x63,
|
||||
0x69, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65,
|
||||
0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69,
|
||||
0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f,
|
||||
0x72, 0x6f, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6c, 0x69, 0x65,
|
||||
0x6e, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x34, 0x0a, 0x16, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73,
|
||||
0x5f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c,
|
||||
0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72,
|
||||
0x61, 0x6e, 0x74, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x12, 0x30, 0x0a, 0x14,
|
||||
0x61, 0x6c, 0x69, 0x61, 0x73, 0x5f, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x65,
|
||||
0x73, 0x73, 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x61, 0x6c, 0x69, 0x61,
|
||||
0x73, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x22, 0x88,
|
||||
0x05, 0x0a, 0x12, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65,
|
||||
0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x37, 0x0a, 0x08, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61,
|
||||
0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69,
|
||||
0x74, 0x79, 0x2e, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x45,
|
||||
0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x73, 0x12, 0x0e,
|
||||
0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12,
|
||||
0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61,
|
||||
0x6d, 0x65, 0x12, 0x46, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04,
|
||||
0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2e,
|
||||
0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x45, 0x6e, 0x74,
|
||||
0x72, 0x79, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79,
|
||||
0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x3f, 0x0a, 0x0d, 0x63, 0x72,
|
||||
0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x63,
|
||||
0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x44, 0x0a, 0x10, 0x6c,
|
||||
0x61, 0x73, 0x74, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18,
|
||||
0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d,
|
||||
0x70, 0x52, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d,
|
||||
0x65, 0x12, 0x2a, 0x0a, 0x11, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x64, 0x5f, 0x65, 0x6e, 0x74, 0x69,
|
||||
0x74, 0x79, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x6d, 0x65,
|
||||
0x72, 0x67, 0x65, 0x64, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x64, 0x73, 0x12, 0x1a, 0x0a,
|
||||
0x08, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52,
|
||||
0x08, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x62, 0x75, 0x63,
|
||||
0x6b, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x09, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x0d, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x48, 0x61, 0x73,
|
||||
0x68, 0x12, 0x4d, 0x0a, 0x0b, 0x6d, 0x66, 0x61, 0x5f, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73,
|
||||
0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74,
|
||||
0x79, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x45,
|
||||
0x6e, 0x74, 0x72, 0x79, 0x2e, 0x4d, 0x66, 0x61, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x45,
|
||||
0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x6d, 0x66, 0x61, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73,
|
||||
0x1a, 0x3b, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72,
|
||||
0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03,
|
||||
0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x2c, 0x5a,
|
||||
0x2a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68,
|
||||
0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2f, 0x68, 0x65, 0x6c, 0x70,
|
||||
0x65, 0x72, 0x2f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x62, 0x06, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x33,
|
||||
0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x4a, 0x0a,
|
||||
0x0f, 0x4d, 0x66, 0x61, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79,
|
||||
0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b,
|
||||
0x65, 0x79, 0x12, 0x21, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x0b, 0x2e, 0x6d, 0x66, 0x61, 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, 0x05,
|
||||
0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xf9, 0x03, 0x0a, 0x11, 0x50, 0x65,
|
||||
0x72, 0x73, 0x6f, 0x6e, 0x61, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12,
|
||||
0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12,
|
||||
0x1b, 0x0a, 0x09, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x08, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a,
|
||||
0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x09, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x6d,
|
||||
0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x18, 0x04, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x0d, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73,
|
||||
0x6f, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x70, 0x61, 0x74, 0x68,
|
||||
0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x50, 0x61, 0x74,
|
||||
0x68, 0x12, 0x45, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x06, 0x20,
|
||||
0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2e, 0x50,
|
||||
0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x45, 0x6e, 0x74, 0x72, 0x79,
|
||||
0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08,
|
||||
0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65,
|
||||
0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3f, 0x0a, 0x0d,
|
||||
0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x08, 0x20,
|
||||
0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52,
|
||||
0x0c, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x44, 0x0a,
|
||||
0x10, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d,
|
||||
0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74,
|
||||
0x61, 0x6d, 0x70, 0x52, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54,
|
||||
0x69, 0x6d, 0x65, 0x12, 0x33, 0x0a, 0x16, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x64, 0x5f, 0x66, 0x72,
|
||||
0x6f, 0x6d, 0x5f, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x0a, 0x20,
|
||||
0x03, 0x28, 0x09, 0x52, 0x13, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x64, 0x46, 0x72, 0x6f, 0x6d, 0x45,
|
||||
0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x64, 0x73, 0x1a, 0x3b, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61,
|
||||
0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76,
|
||||
0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75,
|
||||
0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x2c, 0x5a, 0x2a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,
|
||||
0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x76, 0x61,
|
||||
0x75, 0x6c, 0x74, 0x2f, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x2f, 0x69, 0x64, 0x65, 0x6e, 0x74,
|
||||
0x69, 0x74, 0x79, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
})
|
||||
|
||||
var (
|
||||
|
|
@ -1088,50 +1242,51 @@ func file_helper_identity_types_proto_rawDescGZIP() []byte {
|
|||
return file_helper_identity_types_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_helper_identity_types_proto_msgTypes = make([]protoimpl.MessageInfo, 14)
|
||||
var file_helper_identity_types_proto_msgTypes = make([]protoimpl.MessageInfo, 15)
|
||||
var file_helper_identity_types_proto_goTypes = []any{
|
||||
(*Group)(nil), // 0: identity.Group
|
||||
(*LocalAliases)(nil), // 1: identity.LocalAliases
|
||||
(*Entity)(nil), // 2: identity.Entity
|
||||
(*Alias)(nil), // 3: identity.Alias
|
||||
(*EntityStorageEntry)(nil), // 4: identity.EntityStorageEntry
|
||||
(*PersonaIndexEntry)(nil), // 5: identity.PersonaIndexEntry
|
||||
nil, // 6: identity.Group.MetadataEntry
|
||||
nil, // 7: identity.Entity.MetadataEntry
|
||||
nil, // 8: identity.Entity.MFASecretsEntry
|
||||
nil, // 9: identity.Alias.MetadataEntry
|
||||
nil, // 10: identity.Alias.CustomMetadataEntry
|
||||
nil, // 11: identity.EntityStorageEntry.MetadataEntry
|
||||
nil, // 12: identity.EntityStorageEntry.MFASecretsEntry
|
||||
nil, // 13: identity.PersonaIndexEntry.MetadataEntry
|
||||
(*timestamppb.Timestamp)(nil), // 14: google.protobuf.Timestamp
|
||||
(*mfa.Secret)(nil), // 15: mfa.Secret
|
||||
(*ScimConfig)(nil), // 4: identity.ScimConfig
|
||||
(*EntityStorageEntry)(nil), // 5: identity.EntityStorageEntry
|
||||
(*PersonaIndexEntry)(nil), // 6: identity.PersonaIndexEntry
|
||||
nil, // 7: identity.Group.MetadataEntry
|
||||
nil, // 8: identity.Entity.MetadataEntry
|
||||
nil, // 9: identity.Entity.MFASecretsEntry
|
||||
nil, // 10: identity.Alias.MetadataEntry
|
||||
nil, // 11: identity.Alias.CustomMetadataEntry
|
||||
nil, // 12: identity.EntityStorageEntry.MetadataEntry
|
||||
nil, // 13: identity.EntityStorageEntry.MFASecretsEntry
|
||||
nil, // 14: identity.PersonaIndexEntry.MetadataEntry
|
||||
(*timestamppb.Timestamp)(nil), // 15: google.protobuf.Timestamp
|
||||
(*mfa.Secret)(nil), // 16: mfa.Secret
|
||||
}
|
||||
var file_helper_identity_types_proto_depIDxs = []int32{
|
||||
6, // 0: identity.Group.metadata:type_name -> identity.Group.MetadataEntry
|
||||
14, // 1: identity.Group.creation_time:type_name -> google.protobuf.Timestamp
|
||||
14, // 2: identity.Group.last_update_time:type_name -> google.protobuf.Timestamp
|
||||
7, // 0: identity.Group.metadata:type_name -> identity.Group.MetadataEntry
|
||||
15, // 1: identity.Group.creation_time:type_name -> google.protobuf.Timestamp
|
||||
15, // 2: identity.Group.last_update_time:type_name -> google.protobuf.Timestamp
|
||||
3, // 3: identity.Group.alias:type_name -> identity.Alias
|
||||
3, // 4: identity.LocalAliases.aliases:type_name -> identity.Alias
|
||||
3, // 5: identity.Entity.aliases:type_name -> identity.Alias
|
||||
7, // 6: identity.Entity.metadata:type_name -> identity.Entity.MetadataEntry
|
||||
14, // 7: identity.Entity.creation_time:type_name -> google.protobuf.Timestamp
|
||||
14, // 8: identity.Entity.last_update_time:type_name -> google.protobuf.Timestamp
|
||||
8, // 9: identity.Entity.mfa_secrets:type_name -> identity.Entity.MFASecretsEntry
|
||||
9, // 10: identity.Alias.metadata:type_name -> identity.Alias.MetadataEntry
|
||||
14, // 11: identity.Alias.creation_time:type_name -> google.protobuf.Timestamp
|
||||
14, // 12: identity.Alias.last_update_time:type_name -> google.protobuf.Timestamp
|
||||
10, // 13: identity.Alias.custom_metadata:type_name -> identity.Alias.CustomMetadataEntry
|
||||
5, // 14: identity.EntityStorageEntry.personas:type_name -> identity.PersonaIndexEntry
|
||||
11, // 15: identity.EntityStorageEntry.metadata:type_name -> identity.EntityStorageEntry.MetadataEntry
|
||||
14, // 16: identity.EntityStorageEntry.creation_time:type_name -> google.protobuf.Timestamp
|
||||
14, // 17: identity.EntityStorageEntry.last_update_time:type_name -> google.protobuf.Timestamp
|
||||
12, // 18: identity.EntityStorageEntry.mfa_secrets:type_name -> identity.EntityStorageEntry.MFASecretsEntry
|
||||
13, // 19: identity.PersonaIndexEntry.metadata:type_name -> identity.PersonaIndexEntry.MetadataEntry
|
||||
14, // 20: identity.PersonaIndexEntry.creation_time:type_name -> google.protobuf.Timestamp
|
||||
14, // 21: identity.PersonaIndexEntry.last_update_time:type_name -> google.protobuf.Timestamp
|
||||
15, // 22: identity.Entity.MFASecretsEntry.value:type_name -> mfa.Secret
|
||||
15, // 23: identity.EntityStorageEntry.MFASecretsEntry.value:type_name -> mfa.Secret
|
||||
8, // 6: identity.Entity.metadata:type_name -> identity.Entity.MetadataEntry
|
||||
15, // 7: identity.Entity.creation_time:type_name -> google.protobuf.Timestamp
|
||||
15, // 8: identity.Entity.last_update_time:type_name -> google.protobuf.Timestamp
|
||||
9, // 9: identity.Entity.mfa_secrets:type_name -> identity.Entity.MFASecretsEntry
|
||||
10, // 10: identity.Alias.metadata:type_name -> identity.Alias.MetadataEntry
|
||||
15, // 11: identity.Alias.creation_time:type_name -> google.protobuf.Timestamp
|
||||
15, // 12: identity.Alias.last_update_time:type_name -> google.protobuf.Timestamp
|
||||
11, // 13: identity.Alias.custom_metadata:type_name -> identity.Alias.CustomMetadataEntry
|
||||
6, // 14: identity.EntityStorageEntry.personas:type_name -> identity.PersonaIndexEntry
|
||||
12, // 15: identity.EntityStorageEntry.metadata:type_name -> identity.EntityStorageEntry.MetadataEntry
|
||||
15, // 16: identity.EntityStorageEntry.creation_time:type_name -> google.protobuf.Timestamp
|
||||
15, // 17: identity.EntityStorageEntry.last_update_time:type_name -> google.protobuf.Timestamp
|
||||
13, // 18: identity.EntityStorageEntry.mfa_secrets:type_name -> identity.EntityStorageEntry.MFASecretsEntry
|
||||
14, // 19: identity.PersonaIndexEntry.metadata:type_name -> identity.PersonaIndexEntry.MetadataEntry
|
||||
15, // 20: identity.PersonaIndexEntry.creation_time:type_name -> google.protobuf.Timestamp
|
||||
15, // 21: identity.PersonaIndexEntry.last_update_time:type_name -> google.protobuf.Timestamp
|
||||
16, // 22: identity.Entity.MFASecretsEntry.value:type_name -> mfa.Secret
|
||||
16, // 23: identity.EntityStorageEntry.MFASecretsEntry.value:type_name -> mfa.Secret
|
||||
24, // [24:24] is the sub-list for method output_type
|
||||
24, // [24:24] is the sub-list for method input_type
|
||||
24, // [24:24] is the sub-list for extension type_name
|
||||
|
|
@ -1150,7 +1305,7 @@ func file_helper_identity_types_proto_init() {
|
|||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_helper_identity_types_proto_rawDesc), len(file_helper_identity_types_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 14,
|
||||
NumMessages: 15,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -75,6 +75,13 @@ message Group {
|
|||
// group.
|
||||
// @inject_tag: sentinel:"-"
|
||||
string namespace_id = 13;
|
||||
|
||||
// ScimClientId records the unique identifier of the SCIM client that
|
||||
// originally created this Group. This establishes a strict ownership model,
|
||||
// ensuring that authoritative lifecycle operations (like updates and deletes by
|
||||
// an IGA) can only be performed by the client that owns the resource.
|
||||
// @inject_tag: sentinel:"-"
|
||||
string scim_client_id = 14;
|
||||
}
|
||||
|
||||
// LocalAliases holds the aliases belonging to an entity that are local to the
|
||||
|
|
@ -155,6 +162,21 @@ message Entity {
|
|||
// entity.
|
||||
// @inject_tag: sentinel:"-"
|
||||
string namespace_id = 12;
|
||||
|
||||
// ExternalId stores the `externalId` provided by a SCIM client.
|
||||
// This field serves as the canonical correlation key, linking this Vault Entity
|
||||
// to its representation in the external identity management system. It is
|
||||
// crucial for preventing the creation of duplicate entities when multiple
|
||||
// SCIM clients provision the same user.
|
||||
// @inject_tag: sentinel:"-"
|
||||
string external_id = 13;
|
||||
|
||||
// ScimClientId records the unique identifier of the SCIM client that
|
||||
// originally created this Entity. This establishes a strict ownership model,
|
||||
// ensuring that authoritative lifecycle operations (like updates and deletes by
|
||||
// an IGA) can only be performed by the client that owns the resource.
|
||||
// @inject_tag: sentinel:"-"
|
||||
string scim_client_id = 14;
|
||||
}
|
||||
|
||||
// Alias represents the alias that gets stored inside of the
|
||||
|
|
@ -233,6 +255,36 @@ message Alias {
|
|||
// during invalidation of local aliases in performance standbys.
|
||||
// @inject_tag: sentinel:"-"
|
||||
string local_bucket_key = 14;
|
||||
|
||||
// ScimClientId records the unique identifier of the SCIM client that
|
||||
// originally created this Alias. This establishes a strict ownership model,
|
||||
// ensuring that authoritative lifecycle operations (like updates and deletes by
|
||||
// an IGA) can only be performed by the client that owns the resource.
|
||||
// @inject_tag: sentinel:"-"
|
||||
string scim_client_id = 15;
|
||||
}
|
||||
|
||||
// ScimConfig defines the stored configuration for a single SCIM client.
|
||||
// This configuration links a client's identity within Vault to its specific
|
||||
// role and capabilities within the SCIM server.
|
||||
message ScimConfig {
|
||||
// ClientId is a unique, user-defined identifier for this specific SCIM
|
||||
// client configuration (e.g., 'Okta-Prod', 'SailPoint-Dev').
|
||||
string client_id = 1;
|
||||
|
||||
// ClientRole defines the client's function and authoritative power.
|
||||
// It must be either "IGA" (authoritative) or "IdP" (standard).
|
||||
string client_role = 2;
|
||||
|
||||
// AccessGrantPrincipal is the Vault Entity ID that represents the SCIM
|
||||
// client application itself. This is the principal that will be granted the
|
||||
// necessary permissions to perform SCIM operations.
|
||||
string access_grant_principal = 3;
|
||||
|
||||
// AliasMountAccessor is an optional field that specifies the mount accessor
|
||||
// of an auth method where login aliases should be created for provisioned users.
|
||||
// This is typically used for clients with the 'IdP' role.
|
||||
string alias_mount_accessor = 4;
|
||||
}
|
||||
|
||||
// Deprecated. Retained for backwards compatibility.
|
||||
|
|
|
|||
|
|
@ -43,7 +43,10 @@ func (b *bufferedReader) Close() error {
|
|||
return b.rOrig.Close()
|
||||
}
|
||||
|
||||
const MergePatchContentTypeHeader = "application/merge-patch+json"
|
||||
const (
|
||||
MergePatchContentTypeHeader = "application/merge-patch+json"
|
||||
ScimPatchContentTypeHeader = "application/scim+json"
|
||||
)
|
||||
|
||||
func buildLogicalRequestNoAuth(perfStandby bool, ra *vault.RouterAccess, w http.ResponseWriter, r *http.Request) (*logical.Request, io.ReadCloser, int, error) {
|
||||
ns, err := namespace.FromContext(r.Context())
|
||||
|
|
@ -167,7 +170,7 @@ func buildLogicalRequestNoAuth(perfStandby bool, ra *vault.RouterAccess, w http.
|
|||
return nil, nil, status, err
|
||||
}
|
||||
|
||||
if contentType != MergePatchContentTypeHeader {
|
||||
if contentType != MergePatchContentTypeHeader && contentType != ScimPatchContentTypeHeader {
|
||||
return nil, nil, http.StatusUnsupportedMediaType, fmt.Errorf("PATCH requires Content-Type of %s, provided %s", MergePatchContentTypeHeader, contentType)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ import (
|
|||
const (
|
||||
groupBucketsPrefix = "packer/group/buckets/"
|
||||
localAliasesBucketsPrefix = "packer/local-aliases/buckets/"
|
||||
scimBucketsPrefix = "packer/scim/buckets/"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -95,6 +96,8 @@ func NewIdentityStore(ctx context.Context, core *Core, config *logical.BackendCo
|
|||
core.AddLogger(localAliasesPackerLogger)
|
||||
groupsPackerLogger := iStore.logger.Named("storagepacker").Named("groups")
|
||||
core.AddLogger(groupsPackerLogger)
|
||||
scimPackerLogger := iStore.logger.Named("storagepacker").Named("scim")
|
||||
core.AddLogger(scimPackerLogger)
|
||||
|
||||
iStore.entityPacker, err = storagepacker.NewStoragePacker(iStore.view, entitiesPackerLogger, "")
|
||||
if err != nil {
|
||||
|
|
@ -111,6 +114,11 @@ func NewIdentityStore(ctx context.Context, core *Core, config *logical.BackendCo
|
|||
return nil, fmt.Errorf("failed to create group packer: %w", err)
|
||||
}
|
||||
|
||||
iStore.scimConfigPacker, err = storagepacker.NewStoragePacker(iStore.view, scimPackerLogger, scimBucketsPrefix)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create scim packer: %w", err)
|
||||
}
|
||||
|
||||
iStore.Backend = &framework.Backend{
|
||||
BackendType: logical.TypeLogical,
|
||||
Paths: iStore.paths(),
|
||||
|
|
@ -123,7 +131,7 @@ func NewIdentityStore(ctx context.Context, core *Core, config *logical.BackendCo
|
|||
"oidc/+/.well-known/*",
|
||||
"oidc/provider/+/.well-known/*",
|
||||
"oidc/provider/+/token",
|
||||
}, identityStoreLoginMFAEntUnauthedPaths()...),
|
||||
}),
|
||||
LocalStorage: []string{
|
||||
localAliasesBucketsPrefix,
|
||||
},
|
||||
|
|
@ -165,7 +173,6 @@ func (i *IdentityStore) paths() []*framework.Path {
|
|||
mfaDuoPaths(i),
|
||||
mfaPingIDPaths(i),
|
||||
mfaLoginEnforcementPaths(i),
|
||||
mfaLoginEnterprisePaths(i),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -35,34 +35,7 @@ func aliasPaths(i *IdentityStore) []*framework.Path {
|
|||
OperationSuffix: "alias",
|
||||
},
|
||||
|
||||
Fields: map[string]*framework.FieldSchema{
|
||||
"id": {
|
||||
Type: framework.TypeString,
|
||||
Description: "ID of the entity alias. If set, updates the corresponding entity alias.",
|
||||
},
|
||||
// entity_id is deprecated in favor of canonical_id
|
||||
"entity_id": {
|
||||
Type: framework.TypeString,
|
||||
Description: `Entity ID to which this alias belongs.
|
||||
This field is deprecated, use canonical_id.`,
|
||||
},
|
||||
"canonical_id": {
|
||||
Type: framework.TypeString,
|
||||
Description: "Entity ID to which this alias belongs",
|
||||
},
|
||||
"mount_accessor": {
|
||||
Type: framework.TypeString,
|
||||
Description: "Mount accessor to which this alias belongs to; unused for a modify",
|
||||
},
|
||||
"name": {
|
||||
Type: framework.TypeString,
|
||||
Description: "Name of the alias; unused for a modify",
|
||||
},
|
||||
"custom_metadata": {
|
||||
Type: framework.TypeKVPairs,
|
||||
Description: "User provided key-value pairs",
|
||||
},
|
||||
},
|
||||
Fields: aliasFieldSchema(),
|
||||
Callbacks: map[logical.Operation]framework.OperationFunc{
|
||||
logical.UpdateOperation: i.handleAliasCreateUpdate(),
|
||||
},
|
||||
|
|
@ -150,6 +123,37 @@ This field is deprecated, use canonical_id.`,
|
|||
}
|
||||
}
|
||||
|
||||
func aliasFieldSchema() map[string]*framework.FieldSchema {
|
||||
return map[string]*framework.FieldSchema{
|
||||
"id": {
|
||||
Type: framework.TypeString,
|
||||
Description: "ID of the entity alias. If set, updates the corresponding entity alias.",
|
||||
},
|
||||
// entity_id is deprecated in favor of canonical_id
|
||||
"entity_id": {
|
||||
Type: framework.TypeString,
|
||||
Description: `Entity ID to which this alias belongs.
|
||||
This field is deprecated, use canonical_id.`,
|
||||
},
|
||||
"canonical_id": {
|
||||
Type: framework.TypeString,
|
||||
Description: "Entity ID to which this alias belongs",
|
||||
},
|
||||
"mount_accessor": {
|
||||
Type: framework.TypeString,
|
||||
Description: "Mount accessor to which this alias belongs to; unused for a modify",
|
||||
},
|
||||
"name": {
|
||||
Type: framework.TypeString,
|
||||
Description: "Name of the alias; unused for a modify",
|
||||
},
|
||||
"custom_metadata": {
|
||||
Type: framework.TypeKVPairs,
|
||||
Description: "User provided key-value pairs",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// handleAliasCreateUpdate is used to create or update an alias
|
||||
func (i *IdentityStore) handleAliasCreateUpdate() framework.OperationFunc {
|
||||
return func(ctx context.Context, req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
|
||||
|
|
@ -239,7 +243,6 @@ func (i *IdentityStore) handleAliasCreateUpdate() framework.OperationFunc {
|
|||
return logical.ErrorResponse("'id' or 'mount_accessor' and 'name' must be provided"), nil
|
||||
}
|
||||
|
||||
// Look up the alias by factors; if it's found it's an update
|
||||
mountEntry := i.router.MatchingMountByAccessor(mountAccessor)
|
||||
if mountEntry == nil {
|
||||
return logical.ErrorResponse(fmt.Sprintf("invalid mount accessor %q", mountAccessor)), nil
|
||||
|
|
@ -247,22 +250,30 @@ func (i *IdentityStore) handleAliasCreateUpdate() framework.OperationFunc {
|
|||
if mountEntry.NamespaceID != ns.ID {
|
||||
return logical.ErrorResponse("matching mount is in a different namespace than request"), logical.ErrPermissionDenied
|
||||
}
|
||||
alias, err := i.MemDBAliasByFactors(mountAccessor, name, true, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if alias != nil {
|
||||
if alias.NamespaceID != ns.ID {
|
||||
return logical.ErrorResponse("cannot modify aliases across namespaces"), logical.ErrPermissionDenied
|
||||
}
|
||||
return i.handleAliasUpdate(ctx, canonicalID, name, mountAccessor, alias, customMetadata)
|
||||
}
|
||||
// At this point we know it's a new creation request
|
||||
return i.handleAliasCreate(ctx, canonicalID, name, mountAccessor, mountEntry.Local, customMetadata)
|
||||
|
||||
localMount := mountEntry.Local
|
||||
|
||||
// Look up the alias by factors; if it's found it's an update
|
||||
return i.handleAliasCreateUpdateCommon(ctx, ns, mountAccessor, name, canonicalID, customMetadata, localMount, "")
|
||||
}
|
||||
}
|
||||
|
||||
func (i *IdentityStore) handleAliasCreate(ctx context.Context, canonicalID, name, mountAccessor string, local bool, customMetadata map[string]string) (*logical.Response, error) {
|
||||
func (i *IdentityStore) handleAliasCreateUpdateCommon(ctx context.Context, ns *namespace.Namespace, mountAccessor string, name string, canonicalID string, customMetadata map[string]string, localMount bool, scimClientID string) (*logical.Response, error) {
|
||||
alias, err := i.MemDBAliasByFactors(mountAccessor, name, true, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if alias != nil {
|
||||
if alias.NamespaceID != ns.ID {
|
||||
return logical.ErrorResponse("cannot modify aliases across namespaces"), logical.ErrPermissionDenied
|
||||
}
|
||||
return i.handleAliasUpdate(ctx, canonicalID, name, mountAccessor, alias, customMetadata)
|
||||
}
|
||||
// At this point we know it's a new creation request
|
||||
return i.handleAliasCreate(ctx, canonicalID, name, mountAccessor, localMount, customMetadata, scimClientID)
|
||||
}
|
||||
|
||||
func (i *IdentityStore) handleAliasCreate(ctx context.Context, canonicalID, name, mountAccessor string, local bool, customMetadata map[string]string, scimClientID string) (*logical.Response, error) {
|
||||
ns, err := namespace.FromContext(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -326,6 +337,7 @@ func (i *IdentityStore) handleAliasCreate(ctx context.Context, canonicalID, name
|
|||
Name: name,
|
||||
CustomMetadata: customMetadata,
|
||||
CanonicalID: entity.ID,
|
||||
ScimClientID: scimClientID,
|
||||
}
|
||||
err = i.sanitizeAlias(ctx, alias)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -31,6 +31,14 @@ func entityPathFields() map[string]*framework.FieldSchema {
|
|||
Type: framework.TypeString,
|
||||
Description: "Name of the entity",
|
||||
},
|
||||
"external_id": {
|
||||
Type: framework.TypeString,
|
||||
Description: "External ID of the entity",
|
||||
},
|
||||
"scim_client_id": {
|
||||
Type: framework.TypeString,
|
||||
Description: "SCIM Client ID of the entity",
|
||||
},
|
||||
"metadata": {
|
||||
Type: framework.TypeKVPairs,
|
||||
Description: `Metadata to be associated with the entity.
|
||||
|
|
@ -304,106 +312,7 @@ func (i *IdentityStore) handleEntityUpdateCommon() framework.OperationFunc {
|
|||
i.lock.Lock()
|
||||
defer i.lock.Unlock()
|
||||
|
||||
entity := new(identity.Entity)
|
||||
var err error
|
||||
|
||||
entityID := d.Get("id").(string)
|
||||
if entityID != "" {
|
||||
entity, err = i.MemDBEntityByID(entityID, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if entity == nil {
|
||||
return logical.ErrorResponse("entity not found from id"), nil
|
||||
}
|
||||
}
|
||||
|
||||
// Get the name
|
||||
entityName := d.Get("name").(string)
|
||||
if entityName != "" {
|
||||
entityByName, err := i.MemDBEntityByName(ctx, entityName, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch {
|
||||
case entityByName == nil:
|
||||
// Not found, safe to use this name with an existing or new entity
|
||||
case entity.ID == "":
|
||||
// Entity by ID was not found, but and entity for the supplied
|
||||
// name was found. Continue updating the entity.
|
||||
entity = entityByName
|
||||
case entity.ID == entityByName.ID:
|
||||
// Same exact entity, carry on (this is basically a noop then)
|
||||
default:
|
||||
return logical.ErrorResponse("entity name is already in use"), nil
|
||||
}
|
||||
}
|
||||
|
||||
if entityName != "" {
|
||||
entity.Name = entityName
|
||||
}
|
||||
|
||||
// Update the policies if supplied
|
||||
entityPoliciesRaw, ok := d.GetOk("policies")
|
||||
if ok {
|
||||
entity.Policies = strutil.RemoveDuplicates(entityPoliciesRaw.([]string), false)
|
||||
}
|
||||
|
||||
if strutil.StrListContainsCaseInsensitive(entity.Policies, "root") {
|
||||
return logical.ErrorResponse("policies cannot contain root"), nil
|
||||
}
|
||||
|
||||
disabledRaw, ok := d.GetOk("disabled")
|
||||
if ok {
|
||||
entity.Disabled = disabledRaw.(bool)
|
||||
}
|
||||
|
||||
// Get entity metadata
|
||||
metadata, ok, err := d.GetOkErr("metadata")
|
||||
if err != nil {
|
||||
return logical.ErrorResponse(fmt.Sprintf("failed to parse metadata: %v", err)), nil
|
||||
}
|
||||
if ok {
|
||||
entity.Metadata = metadata.(map[string]string)
|
||||
}
|
||||
|
||||
// At this point, if entity.ID is empty, it indicates that a new entity
|
||||
// is being created. Using this to respond data in the response.
|
||||
newEntity := entity.ID == ""
|
||||
|
||||
// ID creation and some validations
|
||||
err = i.sanitizeEntity(ctx, entity)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := i.upsertEntity(ctx, entity, nil, true); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// If this operation was an update to an existing entity, return 204
|
||||
if !newEntity {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Prepare the response
|
||||
respData := map[string]interface{}{
|
||||
"id": entity.ID,
|
||||
"name": entity.Name,
|
||||
}
|
||||
|
||||
var aliasIDs []string
|
||||
for _, alias := range entity.Aliases {
|
||||
aliasIDs = append(aliasIDs, alias.ID)
|
||||
}
|
||||
|
||||
respData["aliases"] = aliasIDs
|
||||
|
||||
// Return ID of the entity that was either created or updated along with
|
||||
// its aliases
|
||||
return &logical.Response{
|
||||
Data: respData,
|
||||
}, nil
|
||||
return i.EntityUpdateCommon(ctx, d)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
249
vault/identity_store_entities_update.go
Normal file
249
vault/identity_store_entities_update.go
Normal file
|
|
@ -0,0 +1,249 @@
|
|||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package vault
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/vault/helper/identity"
|
||||
"github.com/hashicorp/vault/sdk/framework"
|
||||
"github.com/hashicorp/vault/sdk/helper/strutil"
|
||||
"github.com/hashicorp/vault/sdk/logical"
|
||||
)
|
||||
|
||||
// EntityBuilder is used to construct or update an identity.Entity.
|
||||
type EntityBuilder struct {
|
||||
store *IdentityStore
|
||||
entity *identity.Entity
|
||||
isNew bool
|
||||
err error
|
||||
}
|
||||
|
||||
// NewEntityBuilder creates a new builder instance.
|
||||
func NewEntityBuilder(store *IdentityStore) *EntityBuilder {
|
||||
return &EntityBuilder{
|
||||
store: store,
|
||||
entity: new(identity.Entity),
|
||||
isNew: true, // Assume new until an existing entity is loaded
|
||||
}
|
||||
}
|
||||
|
||||
// WithExistingEntity allows you to pass in a preloaded entity.
|
||||
func (b *EntityBuilder) WithExistingEntity(entity *identity.Entity) *EntityBuilder {
|
||||
if b.err != nil || entity == nil {
|
||||
return b
|
||||
}
|
||||
b.entity = entity
|
||||
b.isNew = false
|
||||
return b
|
||||
}
|
||||
|
||||
// WithID attempts to load an entity by its ID.
|
||||
func (b *EntityBuilder) WithID(id string) *EntityBuilder {
|
||||
if b.err != nil || id == "" {
|
||||
return b
|
||||
}
|
||||
|
||||
entity, err := b.store.MemDBEntityByID(id, true)
|
||||
if err != nil {
|
||||
b.err = err
|
||||
return b
|
||||
}
|
||||
if entity == nil {
|
||||
b.err = fmt.Errorf("entity not found from id: %s", id)
|
||||
return b
|
||||
}
|
||||
|
||||
b.entity = entity
|
||||
b.isNew = false
|
||||
return b
|
||||
}
|
||||
|
||||
// WithExternalID handles logic related to the external_id.
|
||||
func (b *EntityBuilder) WithExternalID(ctx context.Context, externalID string) *EntityBuilder {
|
||||
if b.err != nil || externalID == "" {
|
||||
return b
|
||||
}
|
||||
|
||||
entityByExternalID, err := b.store.MemDBEntityByExternalID(ctx, externalID, true)
|
||||
if err != nil {
|
||||
b.err = err
|
||||
return b
|
||||
}
|
||||
|
||||
if entityByExternalID != nil {
|
||||
// An entity with this external ID already exists, so we'll update it.
|
||||
b.entity = entityByExternalID
|
||||
b.isNew = false
|
||||
} else {
|
||||
// No entity found, so we're just setting the external ID on the current one.
|
||||
b.entity.ExternalID = externalID
|
||||
}
|
||||
|
||||
return b
|
||||
}
|
||||
|
||||
// WithName handles the complex logic for finding an entity by name and checking for conflicts.
|
||||
func (b *EntityBuilder) WithName(ctx context.Context, name string) *EntityBuilder {
|
||||
if b.err != nil || name == "" {
|
||||
return b
|
||||
}
|
||||
|
||||
entityByName, err := b.store.MemDBEntityByName(ctx, name, true)
|
||||
if err != nil {
|
||||
b.err = err
|
||||
return b
|
||||
}
|
||||
|
||||
switch {
|
||||
case entityByName == nil:
|
||||
// Not found, safe to use this name.
|
||||
case b.isNew:
|
||||
// We haven't loaded an entity yet, but one with this name exists. Let's update it.
|
||||
b.entity = entityByName
|
||||
b.isNew = false
|
||||
case b.entity.ID == entityByName.ID:
|
||||
// The loaded entity and the one found by name are the same. No-op.
|
||||
default:
|
||||
// A different entity already has this name, which is a conflict.
|
||||
b.err = fmt.Errorf("entity name '%s' is already in use", name)
|
||||
return b
|
||||
}
|
||||
|
||||
b.entity.Name = name
|
||||
return b
|
||||
}
|
||||
|
||||
// WithPolicies sets the policies for the entity.
|
||||
func (b *EntityBuilder) WithPolicies(policies []string) *EntityBuilder {
|
||||
if b.err != nil {
|
||||
return b
|
||||
}
|
||||
if strutil.StrListContainsCaseInsensitive(policies, "root") {
|
||||
b.err = fmt.Errorf("policies cannot contain root")
|
||||
return b
|
||||
}
|
||||
b.entity.Policies = strutil.RemoveDuplicates(policies, false)
|
||||
return b
|
||||
}
|
||||
|
||||
// WithDisabled sets the disabled status of the entity.
|
||||
func (b *EntityBuilder) WithDisabled(disabled bool) *EntityBuilder {
|
||||
if b.err != nil {
|
||||
return b
|
||||
}
|
||||
b.entity.Disabled = disabled
|
||||
return b
|
||||
}
|
||||
|
||||
// WithMetadata sets the metadata for the entity.
|
||||
func (b *EntityBuilder) WithMetadata(metadata map[string]string) *EntityBuilder {
|
||||
if b.err != nil {
|
||||
return b
|
||||
}
|
||||
b.entity.Metadata = metadata
|
||||
return b
|
||||
}
|
||||
|
||||
// WithSCIMClientID sets the SCIM client ID.
|
||||
func (b *EntityBuilder) WithSCIMClientID(scimClientID string) *EntityBuilder {
|
||||
if b.err != nil {
|
||||
return b
|
||||
}
|
||||
b.entity.ScimClientID = scimClientID
|
||||
return b
|
||||
}
|
||||
|
||||
// Build finalizes the entity creation/update process.
|
||||
func (b *EntityBuilder) Build(ctx context.Context) (*logical.Response, error) {
|
||||
// If any previous step set an error, return it immediately.
|
||||
if b.err != nil {
|
||||
return logical.ErrorResponse(b.err.Error()), nil
|
||||
}
|
||||
|
||||
// Sanitize and persist the entity
|
||||
if err := b.store.sanitizeEntity(ctx, b.entity); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := b.store.upsertEntity(ctx, b.entity, nil, true); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// If this was an update to an existing entity, return 204 No Content
|
||||
if !b.isNew {
|
||||
return &logical.Response{}, nil
|
||||
}
|
||||
|
||||
// This was a new entity, so prepare the response data
|
||||
respData := map[string]interface{}{
|
||||
"id": b.entity.ID,
|
||||
"name": b.entity.Name,
|
||||
}
|
||||
var aliasIDs []string
|
||||
for _, alias := range b.entity.Aliases {
|
||||
aliasIDs = append(aliasIDs, alias.ID)
|
||||
}
|
||||
respData["aliases"] = aliasIDs
|
||||
|
||||
return &logical.Response{
|
||||
Data: respData,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// FromFieldData is a convenience method to populate the builder from a FieldData object.
|
||||
func (b *EntityBuilder) FromFieldData(ctx context.Context, d *framework.FieldData) *EntityBuilder {
|
||||
if b.err != nil {
|
||||
return b
|
||||
}
|
||||
|
||||
if id, ok := d.GetOk("id"); ok {
|
||||
b.WithID(id.(string))
|
||||
}
|
||||
if externalID, ok := d.GetOk("external_id"); ok {
|
||||
b.WithExternalID(ctx, externalID.(string))
|
||||
}
|
||||
if name, ok := d.GetOk("name"); ok {
|
||||
b.WithName(ctx, name.(string))
|
||||
}
|
||||
if scimClientID, ok := d.GetOk("scim_client_id"); ok {
|
||||
b.WithSCIMClientID(scimClientID.(string))
|
||||
}
|
||||
if policies, ok := d.GetOk("policies"); ok {
|
||||
b.WithPolicies(policies.([]string))
|
||||
}
|
||||
if disabled, ok := d.GetOk("disabled"); ok {
|
||||
b.WithDisabled(disabled.(bool))
|
||||
}
|
||||
if metadata, ok, err := d.GetOkErr("metadata"); err != nil {
|
||||
b.err = fmt.Errorf("failed to parse metadata: %v", err)
|
||||
} else if ok {
|
||||
b.WithMetadata(metadata.(map[string]string))
|
||||
}
|
||||
|
||||
return b
|
||||
}
|
||||
|
||||
// Upsert finalizes the entity update process by persisting it to storage.
|
||||
func (b *EntityBuilder) Upsert(ctx context.Context) (*identity.Entity, error) {
|
||||
if b.err != nil {
|
||||
return nil, b.err
|
||||
}
|
||||
|
||||
// Sanitize and persist the entity
|
||||
if err := b.store.sanitizeEntity(ctx, b.entity); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := b.store.upsertEntity(ctx, b.entity, nil, true); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return b.entity, nil
|
||||
}
|
||||
|
||||
func (i *IdentityStore) EntityUpdateCommon(ctx context.Context, d *framework.FieldData) (*logical.Response, error) {
|
||||
return NewEntityBuilder(i).
|
||||
FromFieldData(ctx, d).
|
||||
Build(ctx)
|
||||
}
|
||||
|
|
@ -35,6 +35,10 @@ func groupPathFields() map[string]*framework.FieldSchema {
|
|||
Type: framework.TypeString,
|
||||
Description: "Name of the group.",
|
||||
},
|
||||
"scim_client_id": {
|
||||
Type: framework.TypeString,
|
||||
Description: "SCIM Client ID of the entity",
|
||||
},
|
||||
"metadata": {
|
||||
Type: framework.TypeKVPairs,
|
||||
Description: `Metadata to be associated with the group.
|
||||
|
|
@ -309,6 +313,12 @@ func (i *IdentityStore) handleGroupUpdateCommon(ctx context.Context, req *logica
|
|||
group.Name = groupName
|
||||
}
|
||||
|
||||
_, ok = d.Schema["scim_client_id"]
|
||||
if ok {
|
||||
entitSCIMClientID := d.Get("scim_client_id").(string)
|
||||
group.ScimClientID = entitSCIMClientID
|
||||
}
|
||||
|
||||
metadata, ok, err := d.GetOkErr("metadata")
|
||||
if err != nil {
|
||||
return logical.ErrorResponse(fmt.Sprintf("failed to parse metadata: %v", err)), nil
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ func identityStoreSchema(lowerCaseName bool) *memdb.DBSchema {
|
|||
groupsTableSchema,
|
||||
groupAliasesTableSchema,
|
||||
oidcClientsTableSchema,
|
||||
scimConfigSchema,
|
||||
}
|
||||
|
||||
for _, schemaFunc := range schemas {
|
||||
|
|
@ -130,6 +131,33 @@ func entitiesTableSchema(lowerCaseName bool) *memdb.TableSchema {
|
|||
Field: "NamespaceID",
|
||||
},
|
||||
},
|
||||
// SCIM-related indexes
|
||||
"external_id": {
|
||||
Name: "external_id",
|
||||
Unique: true,
|
||||
Indexer: &memdb.CompoundIndex{
|
||||
Indexes: []memdb.Indexer{
|
||||
&memdb.StringFieldIndex{
|
||||
Field: "NamespaceID",
|
||||
},
|
||||
&memdb.StringFieldIndex{
|
||||
Field: "ExternalID",
|
||||
},
|
||||
},
|
||||
},
|
||||
AllowMissing: true,
|
||||
},
|
||||
|
||||
"scim_client_id": {
|
||||
Name: "scim_client_id",
|
||||
AllowMissing: true,
|
||||
Indexer: &memdb.CompoundIndex{
|
||||
Indexes: []memdb.Indexer{
|
||||
&memdb.StringFieldIndex{Field: "NamespaceID"},
|
||||
&memdb.StringFieldIndex{Field: "ScimClientID"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
@ -186,6 +214,13 @@ func groupsTableSchema(lowerCaseName bool) *memdb.TableSchema {
|
|||
Field: "NamespaceID",
|
||||
},
|
||||
},
|
||||
"scim_client_id": {
|
||||
Name: "scim_client_id",
|
||||
Indexer: &memdb.StringFieldIndex{
|
||||
Field: "ScimClientID",
|
||||
},
|
||||
AllowMissing: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
|||
59
vault/identity_store_scim_schema.go
Normal file
59
vault/identity_store_scim_schema.go
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package vault
|
||||
|
||||
import "github.com/hashicorp/go-memdb"
|
||||
|
||||
const (
|
||||
scimConfigTable = "scim_config"
|
||||
)
|
||||
|
||||
func scimConfigSchema(_ bool) *memdb.TableSchema {
|
||||
return &memdb.TableSchema{
|
||||
Name: scimConfigTable,
|
||||
Indexes: map[string]*memdb.IndexSchema{
|
||||
"id": {
|
||||
Name: "id",
|
||||
Unique: true,
|
||||
Indexer: &memdb.StringFieldIndex{
|
||||
Field: "ID",
|
||||
},
|
||||
},
|
||||
"client_id": {
|
||||
Name: "client_id",
|
||||
Unique: true,
|
||||
Indexer: &memdb.StringFieldIndex{
|
||||
Field: "ClientID",
|
||||
},
|
||||
},
|
||||
"client_role": {
|
||||
Name: "client_role",
|
||||
Indexer: &memdb.StringFieldIndex{
|
||||
Field: "ClientRole",
|
||||
},
|
||||
},
|
||||
"access_grant_method": {
|
||||
Name: "access_grant_method",
|
||||
Indexer: &memdb.StringFieldIndex{
|
||||
Field: "AccessGrantMethod",
|
||||
},
|
||||
},
|
||||
"access_grant_principal": {
|
||||
Name: "access_grant_principal",
|
||||
Unique: true,
|
||||
Indexer: &memdb.StringFieldIndex{
|
||||
Field: "AccessGrantPrincipal",
|
||||
},
|
||||
},
|
||||
"alias_mount_accessor": {
|
||||
Name: "alias_mount_accessor",
|
||||
Unique: true,
|
||||
Indexer: &memdb.StringFieldIndex{
|
||||
Field: "AliasMountAccessor",
|
||||
},
|
||||
AllowMissing: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
@ -100,6 +100,10 @@ type IdentityStore struct {
|
|||
// buckets
|
||||
groupPacker *storagepacker.StoragePacker
|
||||
|
||||
// groupPacker is used to pack multiple group storage entries into 256
|
||||
// buckets
|
||||
scimConfigPacker *storagepacker.StoragePacker
|
||||
|
||||
// disableLowerCaseNames indicates whether or not identity artifacts are
|
||||
// operated case insensitively
|
||||
disableLowerCasedNames bool
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
|
|
@ -1467,6 +1468,42 @@ func (i *IdentityStore) MemDBEntityByIDInTxn(txn *memdb.Txn, entityID string, cl
|
|||
return entity, nil
|
||||
}
|
||||
|
||||
func (i *IdentityStore) MemDBEntityByExternalIDInTxn(ctx context.Context, txn *memdb.Txn, externalID string, clone bool) (*identity.Entity, error) {
|
||||
var entity *identity.Entity
|
||||
if externalID == "" {
|
||||
return nil, fmt.Errorf("missing entity id")
|
||||
}
|
||||
|
||||
if txn == nil {
|
||||
return nil, fmt.Errorf("txn is nil")
|
||||
}
|
||||
|
||||
ns, err := namespace.FromContext(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
entityRaw, err := txn.First(entitiesTable, "external_id", ns.ID, externalID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to fetch entity from memdb using entity id: %w", err)
|
||||
}
|
||||
|
||||
if entityRaw == nil {
|
||||
return entity, nil
|
||||
}
|
||||
|
||||
entity, ok := entityRaw.(*identity.Entity)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("failed to declare the type of fetched entity")
|
||||
}
|
||||
|
||||
if clone {
|
||||
return entity.Clone()
|
||||
}
|
||||
|
||||
return entity, nil
|
||||
}
|
||||
|
||||
func (i *IdentityStore) MemDBEntityByID(entityID string, clone bool) (*identity.Entity, error) {
|
||||
if entityID == "" {
|
||||
return nil, fmt.Errorf("missing entity id")
|
||||
|
|
@ -1477,6 +1514,16 @@ func (i *IdentityStore) MemDBEntityByID(entityID string, clone bool) (*identity.
|
|||
return i.MemDBEntityByIDInTxn(txn, entityID, clone)
|
||||
}
|
||||
|
||||
func (i *IdentityStore) MemDBEntityByExternalID(ctx context.Context, externalID string, clone bool) (*identity.Entity, error) {
|
||||
if externalID == "" {
|
||||
return nil, fmt.Errorf("missing entity externalID")
|
||||
}
|
||||
|
||||
txn := i.db.Txn(false)
|
||||
|
||||
return i.MemDBEntityByExternalIDInTxn(ctx, txn, externalID, clone)
|
||||
}
|
||||
|
||||
func (i *IdentityStore) MemDBEntityByName(ctx context.Context, entityName string, clone bool) (*identity.Entity, error) {
|
||||
if entityName == "" {
|
||||
return nil, fmt.Errorf("missing entity name")
|
||||
|
|
@ -1659,6 +1706,98 @@ func (i *IdentityStore) MemDBDeleteEntityByID(entityID string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (i *IdentityStore) MemDBEntitiesByScimClientID(ctx context.Context, scimClientID string, maxResultSet int) ([]*identity.Entity, error) {
|
||||
if scimClientID == "" {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
txn := i.db.Txn(false)
|
||||
defer txn.Abort()
|
||||
|
||||
entities, err := i.MemDBEntitiesByScimClientIDInTxn(ctx, txn, scimClientID, maxResultSet)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return entities, nil
|
||||
}
|
||||
|
||||
// MemDBEntitiesByScimClientIDInTxn retrieves a fully sorted list of all entities
|
||||
// belonging to a specific SCIM client.
|
||||
//
|
||||
// Implementation Pattern: Filter-Then-Sort
|
||||
// This function implements the "filter then sort" pattern, which is the idiomatic
|
||||
// approach for this type of query in go-memdb. The process involves two steps:
|
||||
// 1. Filtering: A simple two-part compound index on `(NamespaceID, ScimClientID)`
|
||||
// is used with `txn.Get()` to efficiently retrieve all entities for the client.
|
||||
// 2. Sorting: The resulting slice of entities is then sorted in-memory by name
|
||||
// using Go's native `sort.Slice`.
|
||||
//
|
||||
// Why This Pattern is Used (memdb Limitations):
|
||||
// It might seem more efficient to perform the sorting at the database level
|
||||
// using a single ordered index, memdb's built-in `CompoundIndex` does not support
|
||||
// using a partial key (e.g., just `NamespaceID` and `ScimClientID`) to get an
|
||||
// ordered iterator over the remaining fields (e.g., `Name`). The indexer's
|
||||
// internal `FromArgs` method requires a value for every field defined in the index.
|
||||
// This makes a single-operation "filter and ordered scan" impossible with the
|
||||
// standard indexers.
|
||||
//
|
||||
// Given that go-memdb is an in-memory database, sorting a pre-filtered slice
|
||||
// is extremely fast and avoids the complexity of creating a custom indexer.
|
||||
// This function returns the entire sorted list; the caller is responsible for
|
||||
// any subsequent pagination.
|
||||
func (i *IdentityStore) MemDBEntitiesByScimClientIDInTxn(ctx context.Context, txn *memdb.Txn, scimClientID string, maxResultSet int) ([]*identity.Entity, error) {
|
||||
if txn == nil {
|
||||
return nil, fmt.Errorf("nil txn")
|
||||
}
|
||||
|
||||
if scimClientID == "" {
|
||||
return nil, fmt.Errorf("empty scim client id key")
|
||||
}
|
||||
|
||||
ns, err := namespace.FromContext(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ws := memdb.NewWatchSet()
|
||||
|
||||
entitiesIter, err := txn.Get(entitiesTable, "scim_client_id", ns.ID, scimClientID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to lookup entities using scim client id: %w", err)
|
||||
}
|
||||
|
||||
ws.Add(entitiesIter.WatchCh())
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil, ctx.Err()
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
var entities []*identity.Entity
|
||||
for item := entitiesIter.Next(); item != nil; item = entitiesIter.Next() {
|
||||
if len(entities) > maxResultSet {
|
||||
return nil, fmt.Errorf("query returned more than the server's limit of %d results. Please use more specific filters", maxResultSet)
|
||||
}
|
||||
|
||||
entity, err := item.(*identity.Entity).Clone()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
entities = append(entities, entity)
|
||||
}
|
||||
|
||||
sort.Slice(entities, func(i, j int) bool {
|
||||
return entities[i].Name < entities[j].Name
|
||||
})
|
||||
|
||||
return entities, nil
|
||||
}
|
||||
}
|
||||
|
||||
// FetchEntityForLocalAliasInTxn fetches the entity associated with the provided
|
||||
// local identity.Alias. MemDB will first be searched for the entity. If it is
|
||||
// not found there, the localAliasPacker storagepacker.StoragePacker will be
|
||||
|
|
@ -2344,6 +2483,43 @@ func (i *IdentityStore) MemDBGroupByID(groupID string, clone bool) (*identity.Gr
|
|||
return i.MemDBGroupByIDInTxn(txn, groupID, clone)
|
||||
}
|
||||
|
||||
func (i *IdentityStore) MemDBGroupsByScimClientIDInTxn(txn *memdb.Txn, scimClientID string) ([]*identity.Group, error) {
|
||||
if scimClientID == "" {
|
||||
return nil, fmt.Errorf("missing scim client ID")
|
||||
}
|
||||
|
||||
if txn == nil {
|
||||
return nil, fmt.Errorf("txn is nil")
|
||||
}
|
||||
|
||||
groupsIter, err := txn.Get(groupsTable, "scim_client_id", scimClientID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to lookup groups using scim client ID: %w", err)
|
||||
}
|
||||
|
||||
var groups []*identity.Group
|
||||
for group := groupsIter.Next(); group != nil; group = groupsIter.Next() {
|
||||
entry := group.(*identity.Group)
|
||||
entry, err = entry.Clone()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
groups = append(groups, entry)
|
||||
}
|
||||
|
||||
return groups, nil
|
||||
}
|
||||
|
||||
func (i *IdentityStore) MemDBGroupsByScimClientID(scimClientID string) ([]*identity.Group, error) {
|
||||
if scimClientID == "" {
|
||||
return nil, fmt.Errorf("missing scim client ID")
|
||||
}
|
||||
|
||||
txn := i.db.Txn(false)
|
||||
|
||||
return i.MemDBGroupsByScimClientIDInTxn(txn, scimClientID)
|
||||
}
|
||||
|
||||
func (i *IdentityStore) MemDBGroupsByParentGroupIDInTxn(txn *memdb.Txn, memberGroupID string, clone bool) ([]*identity.Group, error) {
|
||||
if memberGroupID == "" {
|
||||
return nil, fmt.Errorf("missing member group ID")
|
||||
|
|
|
|||
|
|
@ -18,6 +18,13 @@ func namespaceByID(ctx context.Context, nsID string, c *Core) (*namespace.Namesp
|
|||
return nil, namespace.ErrNoNamespace
|
||||
}
|
||||
|
||||
func namespaceByPath(ctx context.Context, nsPath string, c *Core) (*namespace.Namespace, error) {
|
||||
if nsPath == "" {
|
||||
return namespace.RootNamespace, nil
|
||||
}
|
||||
return nil, namespace.ErrNoNamespace
|
||||
}
|
||||
|
||||
var NamespaceRegister func(context.Context, *namespace.Namespace, *Core) error = namespaceRegister
|
||||
|
||||
func namespaceRegister(ctx context.Context, ns *namespace.Namespace, c *Core) error {
|
||||
|
|
|
|||
Loading…
Reference in a new issue