diff --git a/api/v2/api.pb.go b/api/v2/api.pb.go index 2d08ee858c..3f6e8e99a1 100644 --- a/api/v2/api.pb.go +++ b/api/v2/api.pb.go @@ -1007,6 +1007,478 @@ func (x *ListPasswordResp) GetPasswords() []*Password { return nil } +// Connector is a strategy used by Dex for authenticating a user against another identity provider +type Connector struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"` + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` + Config []byte `protobuf:"bytes,4,opt,name=config,proto3" json:"config,omitempty"` +} + +func (x *Connector) Reset() { + *x = Connector{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_api_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Connector) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Connector) ProtoMessage() {} + +func (x *Connector) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_api_proto_msgTypes[18] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Connector.ProtoReflect.Descriptor instead. +func (*Connector) Descriptor() ([]byte, []int) { + return file_api_v2_api_proto_rawDescGZIP(), []int{18} +} + +func (x *Connector) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Connector) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *Connector) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Connector) GetConfig() []byte { + if x != nil { + return x.Config + } + return nil +} + +// CreateConnectorReq is a request to make a connector. +type CreateConnectorReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Connector *Connector `protobuf:"bytes,1,opt,name=connector,proto3" json:"connector,omitempty"` +} + +func (x *CreateConnectorReq) Reset() { + *x = CreateConnectorReq{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_api_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateConnectorReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateConnectorReq) ProtoMessage() {} + +func (x *CreateConnectorReq) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_api_proto_msgTypes[19] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateConnectorReq.ProtoReflect.Descriptor instead. +func (*CreateConnectorReq) Descriptor() ([]byte, []int) { + return file_api_v2_api_proto_rawDescGZIP(), []int{19} +} + +func (x *CreateConnectorReq) GetConnector() *Connector { + if x != nil { + return x.Connector + } + return nil +} + +// CreateConnectorResp returns the response from creating a connector. +type CreateConnectorResp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AlreadyExists bool `protobuf:"varint,1,opt,name=already_exists,json=alreadyExists,proto3" json:"already_exists,omitempty"` +} + +func (x *CreateConnectorResp) Reset() { + *x = CreateConnectorResp{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_api_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateConnectorResp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateConnectorResp) ProtoMessage() {} + +func (x *CreateConnectorResp) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_api_proto_msgTypes[20] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateConnectorResp.ProtoReflect.Descriptor instead. +func (*CreateConnectorResp) Descriptor() ([]byte, []int) { + return file_api_v2_api_proto_rawDescGZIP(), []int{20} +} + +func (x *CreateConnectorResp) GetAlreadyExists() bool { + if x != nil { + return x.AlreadyExists + } + return false +} + +// UpdateConnectorReq is a request to modify an existing connector. +type UpdateConnectorReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The id used to lookup the connector. This field cannot be modified + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + NewType string `protobuf:"bytes,2,opt,name=new_type,json=newType,proto3" json:"new_type,omitempty"` + NewName string `protobuf:"bytes,3,opt,name=new_name,json=newName,proto3" json:"new_name,omitempty"` + NewConfig []byte `protobuf:"bytes,4,opt,name=new_config,json=newConfig,proto3" json:"new_config,omitempty"` +} + +func (x *UpdateConnectorReq) Reset() { + *x = UpdateConnectorReq{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_api_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateConnectorReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateConnectorReq) ProtoMessage() {} + +func (x *UpdateConnectorReq) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_api_proto_msgTypes[21] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateConnectorReq.ProtoReflect.Descriptor instead. +func (*UpdateConnectorReq) Descriptor() ([]byte, []int) { + return file_api_v2_api_proto_rawDescGZIP(), []int{21} +} + +func (x *UpdateConnectorReq) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *UpdateConnectorReq) GetNewType() string { + if x != nil { + return x.NewType + } + return "" +} + +func (x *UpdateConnectorReq) GetNewName() string { + if x != nil { + return x.NewName + } + return "" +} + +func (x *UpdateConnectorReq) GetNewConfig() []byte { + if x != nil { + return x.NewConfig + } + return nil +} + +// UpdateConnectorResp returns the response from modifying an existing connector. +type UpdateConnectorResp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + NotFound bool `protobuf:"varint,1,opt,name=not_found,json=notFound,proto3" json:"not_found,omitempty"` +} + +func (x *UpdateConnectorResp) Reset() { + *x = UpdateConnectorResp{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_api_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateConnectorResp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateConnectorResp) ProtoMessage() {} + +func (x *UpdateConnectorResp) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_api_proto_msgTypes[22] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateConnectorResp.ProtoReflect.Descriptor instead. +func (*UpdateConnectorResp) Descriptor() ([]byte, []int) { + return file_api_v2_api_proto_rawDescGZIP(), []int{22} +} + +func (x *UpdateConnectorResp) GetNotFound() bool { + if x != nil { + return x.NotFound + } + return false +} + +// DeleteConnectorReq is a request to delete a connector. +type DeleteConnectorReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` +} + +func (x *DeleteConnectorReq) Reset() { + *x = DeleteConnectorReq{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_api_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteConnectorReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteConnectorReq) ProtoMessage() {} + +func (x *DeleteConnectorReq) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_api_proto_msgTypes[23] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteConnectorReq.ProtoReflect.Descriptor instead. +func (*DeleteConnectorReq) Descriptor() ([]byte, []int) { + return file_api_v2_api_proto_rawDescGZIP(), []int{23} +} + +func (x *DeleteConnectorReq) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +// DeleteConnectorResp returns the response from deleting a connector. +type DeleteConnectorResp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + NotFound bool `protobuf:"varint,1,opt,name=not_found,json=notFound,proto3" json:"not_found,omitempty"` +} + +func (x *DeleteConnectorResp) Reset() { + *x = DeleteConnectorResp{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_api_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteConnectorResp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteConnectorResp) ProtoMessage() {} + +func (x *DeleteConnectorResp) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_api_proto_msgTypes[24] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteConnectorResp.ProtoReflect.Descriptor instead. +func (*DeleteConnectorResp) Descriptor() ([]byte, []int) { + return file_api_v2_api_proto_rawDescGZIP(), []int{24} +} + +func (x *DeleteConnectorResp) GetNotFound() bool { + if x != nil { + return x.NotFound + } + return false +} + +// ListConnectorReq is a request to enumerate connectors. +type ListConnectorReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ListConnectorReq) Reset() { + *x = ListConnectorReq{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_api_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListConnectorReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListConnectorReq) ProtoMessage() {} + +func (x *ListConnectorReq) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_api_proto_msgTypes[25] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListConnectorReq.ProtoReflect.Descriptor instead. +func (*ListConnectorReq) Descriptor() ([]byte, []int) { + return file_api_v2_api_proto_rawDescGZIP(), []int{25} +} + +// ListConnectorResp returns a list of connectors. +type ListConnectorResp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Connectors []*Connector `protobuf:"bytes,1,rep,name=connectors,proto3" json:"connectors,omitempty"` +} + +func (x *ListConnectorResp) Reset() { + *x = ListConnectorResp{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_api_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListConnectorResp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListConnectorResp) ProtoMessage() {} + +func (x *ListConnectorResp) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_api_proto_msgTypes[26] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListConnectorResp.ProtoReflect.Descriptor instead. +func (*ListConnectorResp) Descriptor() ([]byte, []int) { + return file_api_v2_api_proto_rawDescGZIP(), []int{26} +} + +func (x *ListConnectorResp) GetConnectors() []*Connector { + if x != nil { + return x.Connectors + } + return nil +} + // VersionReq is a request to fetch version info. type VersionReq struct { state protoimpl.MessageState @@ -1017,7 +1489,7 @@ type VersionReq struct { func (x *VersionReq) Reset() { *x = VersionReq{} if protoimpl.UnsafeEnabled { - mi := &file_api_v2_api_proto_msgTypes[18] + mi := &file_api_v2_api_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1030,7 +1502,7 @@ func (x *VersionReq) String() string { func (*VersionReq) ProtoMessage() {} func (x *VersionReq) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_api_proto_msgTypes[18] + mi := &file_api_v2_api_proto_msgTypes[27] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1043,7 +1515,7 @@ func (x *VersionReq) ProtoReflect() protoreflect.Message { // Deprecated: Use VersionReq.ProtoReflect.Descriptor instead. func (*VersionReq) Descriptor() ([]byte, []int) { - return file_api_v2_api_proto_rawDescGZIP(), []int{18} + return file_api_v2_api_proto_rawDescGZIP(), []int{27} } // VersionResp holds the version info of components. @@ -1062,7 +1534,7 @@ type VersionResp struct { func (x *VersionResp) Reset() { *x = VersionResp{} if protoimpl.UnsafeEnabled { - mi := &file_api_v2_api_proto_msgTypes[19] + mi := &file_api_v2_api_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1075,7 +1547,7 @@ func (x *VersionResp) String() string { func (*VersionResp) ProtoMessage() {} func (x *VersionResp) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_api_proto_msgTypes[19] + mi := &file_api_v2_api_proto_msgTypes[28] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1088,7 +1560,7 @@ func (x *VersionResp) ProtoReflect() protoreflect.Message { // Deprecated: Use VersionResp.ProtoReflect.Descriptor instead. func (*VersionResp) Descriptor() ([]byte, []int) { - return file_api_v2_api_proto_rawDescGZIP(), []int{19} + return file_api_v2_api_proto_rawDescGZIP(), []int{28} } func (x *VersionResp) GetServer() string { @@ -1121,7 +1593,7 @@ type RefreshTokenRef struct { func (x *RefreshTokenRef) Reset() { *x = RefreshTokenRef{} if protoimpl.UnsafeEnabled { - mi := &file_api_v2_api_proto_msgTypes[20] + mi := &file_api_v2_api_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1134,7 +1606,7 @@ func (x *RefreshTokenRef) String() string { func (*RefreshTokenRef) ProtoMessage() {} func (x *RefreshTokenRef) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_api_proto_msgTypes[20] + mi := &file_api_v2_api_proto_msgTypes[29] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1147,7 +1619,7 @@ func (x *RefreshTokenRef) ProtoReflect() protoreflect.Message { // Deprecated: Use RefreshTokenRef.ProtoReflect.Descriptor instead. func (*RefreshTokenRef) Descriptor() ([]byte, []int) { - return file_api_v2_api_proto_rawDescGZIP(), []int{20} + return file_api_v2_api_proto_rawDescGZIP(), []int{29} } func (x *RefreshTokenRef) GetId() string { @@ -1191,7 +1663,7 @@ type ListRefreshReq struct { func (x *ListRefreshReq) Reset() { *x = ListRefreshReq{} if protoimpl.UnsafeEnabled { - mi := &file_api_v2_api_proto_msgTypes[21] + mi := &file_api_v2_api_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1204,7 +1676,7 @@ func (x *ListRefreshReq) String() string { func (*ListRefreshReq) ProtoMessage() {} func (x *ListRefreshReq) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_api_proto_msgTypes[21] + mi := &file_api_v2_api_proto_msgTypes[30] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1217,7 +1689,7 @@ func (x *ListRefreshReq) ProtoReflect() protoreflect.Message { // Deprecated: Use ListRefreshReq.ProtoReflect.Descriptor instead. func (*ListRefreshReq) Descriptor() ([]byte, []int) { - return file_api_v2_api_proto_rawDescGZIP(), []int{21} + return file_api_v2_api_proto_rawDescGZIP(), []int{30} } func (x *ListRefreshReq) GetUserId() string { @@ -1239,7 +1711,7 @@ type ListRefreshResp struct { func (x *ListRefreshResp) Reset() { *x = ListRefreshResp{} if protoimpl.UnsafeEnabled { - mi := &file_api_v2_api_proto_msgTypes[22] + mi := &file_api_v2_api_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1252,7 +1724,7 @@ func (x *ListRefreshResp) String() string { func (*ListRefreshResp) ProtoMessage() {} func (x *ListRefreshResp) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_api_proto_msgTypes[22] + mi := &file_api_v2_api_proto_msgTypes[31] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1265,7 +1737,7 @@ func (x *ListRefreshResp) ProtoReflect() protoreflect.Message { // Deprecated: Use ListRefreshResp.ProtoReflect.Descriptor instead. func (*ListRefreshResp) Descriptor() ([]byte, []int) { - return file_api_v2_api_proto_rawDescGZIP(), []int{22} + return file_api_v2_api_proto_rawDescGZIP(), []int{31} } func (x *ListRefreshResp) GetRefreshTokens() []*RefreshTokenRef { @@ -1289,7 +1761,7 @@ type RevokeRefreshReq struct { func (x *RevokeRefreshReq) Reset() { *x = RevokeRefreshReq{} if protoimpl.UnsafeEnabled { - mi := &file_api_v2_api_proto_msgTypes[23] + mi := &file_api_v2_api_proto_msgTypes[32] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1302,7 +1774,7 @@ func (x *RevokeRefreshReq) String() string { func (*RevokeRefreshReq) ProtoMessage() {} func (x *RevokeRefreshReq) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_api_proto_msgTypes[23] + mi := &file_api_v2_api_proto_msgTypes[32] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1315,7 +1787,7 @@ func (x *RevokeRefreshReq) ProtoReflect() protoreflect.Message { // Deprecated: Use RevokeRefreshReq.ProtoReflect.Descriptor instead. func (*RevokeRefreshReq) Descriptor() ([]byte, []int) { - return file_api_v2_api_proto_rawDescGZIP(), []int{23} + return file_api_v2_api_proto_rawDescGZIP(), []int{32} } func (x *RevokeRefreshReq) GetUserId() string { @@ -1345,7 +1817,7 @@ type RevokeRefreshResp struct { func (x *RevokeRefreshResp) Reset() { *x = RevokeRefreshResp{} if protoimpl.UnsafeEnabled { - mi := &file_api_v2_api_proto_msgTypes[24] + mi := &file_api_v2_api_proto_msgTypes[33] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1358,7 +1830,7 @@ func (x *RevokeRefreshResp) String() string { func (*RevokeRefreshResp) ProtoMessage() {} func (x *RevokeRefreshResp) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_api_proto_msgTypes[24] + mi := &file_api_v2_api_proto_msgTypes[33] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1371,7 +1843,7 @@ func (x *RevokeRefreshResp) ProtoReflect() protoreflect.Message { // Deprecated: Use RevokeRefreshResp.ProtoReflect.Descriptor instead. func (*RevokeRefreshResp) Descriptor() ([]byte, []int) { - return file_api_v2_api_proto_rawDescGZIP(), []int{24} + return file_api_v2_api_proto_rawDescGZIP(), []int{33} } func (x *RevokeRefreshResp) GetNotFound() bool { @@ -1393,7 +1865,7 @@ type VerifyPasswordReq struct { func (x *VerifyPasswordReq) Reset() { *x = VerifyPasswordReq{} if protoimpl.UnsafeEnabled { - mi := &file_api_v2_api_proto_msgTypes[25] + mi := &file_api_v2_api_proto_msgTypes[34] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1406,7 +1878,7 @@ func (x *VerifyPasswordReq) String() string { func (*VerifyPasswordReq) ProtoMessage() {} func (x *VerifyPasswordReq) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_api_proto_msgTypes[25] + mi := &file_api_v2_api_proto_msgTypes[34] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1419,7 +1891,7 @@ func (x *VerifyPasswordReq) ProtoReflect() protoreflect.Message { // Deprecated: Use VerifyPasswordReq.ProtoReflect.Descriptor instead. func (*VerifyPasswordReq) Descriptor() ([]byte, []int) { - return file_api_v2_api_proto_rawDescGZIP(), []int{25} + return file_api_v2_api_proto_rawDescGZIP(), []int{34} } func (x *VerifyPasswordReq) GetEmail() string { @@ -1448,7 +1920,7 @@ type VerifyPasswordResp struct { func (x *VerifyPasswordResp) Reset() { *x = VerifyPasswordResp{} if protoimpl.UnsafeEnabled { - mi := &file_api_v2_api_proto_msgTypes[26] + mi := &file_api_v2_api_proto_msgTypes[35] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1461,7 +1933,7 @@ func (x *VerifyPasswordResp) String() string { func (*VerifyPasswordResp) ProtoMessage() {} func (x *VerifyPasswordResp) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_api_proto_msgTypes[26] + mi := &file_api_v2_api_proto_msgTypes[35] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1474,7 +1946,7 @@ func (x *VerifyPasswordResp) ProtoReflect() protoreflect.Message { // Deprecated: Use VerifyPasswordResp.ProtoReflect.Descriptor instead. func (*VerifyPasswordResp) Descriptor() ([]byte, []int) { - return file_api_v2_api_proto_rawDescGZIP(), []int{26} + return file_api_v2_api_proto_rawDescGZIP(), []int{35} } func (x *VerifyPasswordResp) GetVerified() bool { @@ -1576,96 +2048,149 @@ var file_api_v2_api_proto_rawDesc = []byte{ 0x52, 0x65, 0x73, 0x70, 0x12, 0x2b, 0x0a, 0x09, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x09, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, - 0x73, 0x22, 0x0c, 0x0a, 0x0a, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x22, - 0x37, 0x0a, 0x0b, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x12, 0x16, - 0x0a, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, - 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x70, 0x69, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x05, 0x52, 0x03, 0x61, 0x70, 0x69, 0x22, 0x7a, 0x0a, 0x0f, 0x52, 0x65, 0x66, 0x72, - 0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x66, 0x12, 0x0e, 0x0a, 0x02, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x63, - 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x6c, 0x61, 0x73, 0x74, 0x5f, - 0x75, 0x73, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x6c, 0x61, 0x73, 0x74, - 0x55, 0x73, 0x65, 0x64, 0x22, 0x29, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x66, 0x72, - 0x65, 0x73, 0x68, 0x52, 0x65, 0x71, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x22, - 0x4e, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x52, 0x65, - 0x73, 0x70, 0x12, 0x3b, 0x0a, 0x0e, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x5f, 0x74, 0x6f, - 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x61, 0x70, 0x69, - 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x66, - 0x52, 0x0d, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x22, - 0x48, 0x0a, 0x10, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, - 0x52, 0x65, 0x71, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, + 0x73, 0x22, 0x5b, 0x0a, 0x09, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x0e, + 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, + 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, + 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x42, + 0x0a, 0x12, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x52, 0x65, 0x71, 0x12, 0x2c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0x6f, 0x72, 0x22, 0x3c, 0x0a, 0x13, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x12, 0x25, 0x0a, 0x0e, 0x61, 0x6c, 0x72, + 0x65, 0x61, 0x64, 0x79, 0x5f, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x0d, 0x61, 0x6c, 0x72, 0x65, 0x61, 0x64, 0x79, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, + 0x22, 0x79, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x6e, 0x65, 0x77, 0x5f, 0x74, 0x79, + 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6e, 0x65, 0x77, 0x54, 0x79, 0x70, + 0x65, 0x12, 0x19, 0x0a, 0x08, 0x6e, 0x65, 0x77, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x6e, 0x65, 0x77, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, + 0x6e, 0x65, 0x77, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x09, 0x6e, 0x65, 0x77, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x32, 0x0a, 0x13, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x65, + 0x73, 0x70, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x74, 0x5f, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6e, 0x6f, 0x74, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x22, + 0x24, 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0x6f, 0x72, 0x52, 0x65, 0x71, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x32, 0x0a, 0x13, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, + 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x12, 0x1b, 0x0a, 0x09, + 0x6e, 0x6f, 0x74, 0x5f, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x08, 0x6e, 0x6f, 0x74, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x22, 0x12, 0x0a, 0x10, 0x4c, 0x69, 0x73, + 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x22, 0x43, 0x0a, + 0x11, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x65, + 0x73, 0x70, 0x12, 0x2e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x6f, 0x6e, + 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x73, 0x22, 0x0c, 0x0a, 0x0a, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, + 0x22, 0x37, 0x0a, 0x0b, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x12, + 0x16, 0x0a, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x70, 0x69, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x61, 0x70, 0x69, 0x22, 0x7a, 0x0a, 0x0f, 0x52, 0x65, 0x66, + 0x72, 0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x66, 0x12, 0x0e, 0x0a, 0x02, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x22, 0x30, 0x0a, 0x11, 0x52, 0x65, 0x76, - 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x52, 0x65, 0x73, 0x70, 0x12, 0x1b, - 0x0a, 0x09, 0x6e, 0x6f, 0x74, 0x5f, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x08, 0x6e, 0x6f, 0x74, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x22, 0x45, 0x0a, 0x11, 0x56, - 0x65, 0x72, 0x69, 0x66, 0x79, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, - 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, - 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, - 0x72, 0x64, 0x22, 0x4d, 0x0a, 0x12, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x50, 0x61, 0x73, 0x73, - 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x12, 0x1a, 0x0a, 0x08, 0x76, 0x65, 0x72, 0x69, - 0x66, 0x69, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x76, 0x65, 0x72, 0x69, - 0x66, 0x69, 0x65, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x74, 0x5f, 0x66, 0x6f, 0x75, 0x6e, - 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6e, 0x6f, 0x74, 0x46, 0x6f, 0x75, 0x6e, - 0x64, 0x32, 0xfd, 0x05, 0x0a, 0x03, 0x44, 0x65, 0x78, 0x12, 0x34, 0x0a, 0x09, 0x47, 0x65, 0x74, - 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x11, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, - 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x61, 0x70, 0x69, 0x2e, - 0x47, 0x65, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, - 0x3d, 0x0a, 0x0c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, - 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, - 0x6e, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, + 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x6c, 0x61, 0x73, 0x74, + 0x5f, 0x75, 0x73, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x6c, 0x61, 0x73, + 0x74, 0x55, 0x73, 0x65, 0x64, 0x22, 0x29, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x66, + 0x72, 0x65, 0x73, 0x68, 0x52, 0x65, 0x71, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, + 0x22, 0x4e, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x52, + 0x65, 0x73, 0x70, 0x12, 0x3b, 0x0a, 0x0e, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x5f, 0x74, + 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, + 0x66, 0x52, 0x0d, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, + 0x22, 0x48, 0x0a, 0x10, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, + 0x68, 0x52, 0x65, 0x71, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1b, 0x0a, + 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x22, 0x30, 0x0a, 0x11, 0x52, 0x65, + 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x52, 0x65, 0x73, 0x70, 0x12, + 0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x74, 0x5f, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x08, 0x6e, 0x6f, 0x74, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x22, 0x45, 0x0a, 0x11, + 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, + 0x71, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, + 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, + 0x6f, 0x72, 0x64, 0x22, 0x4d, 0x0a, 0x12, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x50, 0x61, 0x73, + 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x12, 0x1a, 0x0a, 0x08, 0x76, 0x65, 0x72, + 0x69, 0x66, 0x69, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x76, 0x65, 0x72, + 0x69, 0x66, 0x69, 0x65, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x74, 0x5f, 0x66, 0x6f, 0x75, + 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6e, 0x6f, 0x74, 0x46, 0x6f, 0x75, + 0x6e, 0x64, 0x32, 0x98, 0x08, 0x0a, 0x03, 0x44, 0x65, 0x78, 0x12, 0x34, 0x0a, 0x09, 0x47, 0x65, + 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x11, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, + 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, + 0x12, 0x3d, 0x0a, 0x0c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x12, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, + 0x3d, 0x0a, 0x0c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, + 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x3d, - 0x0a, 0x0c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x14, - 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, - 0x74, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x3d, 0x0a, - 0x0c, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x14, 0x2e, - 0x61, 0x70, 0x69, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, - 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x43, 0x0a, 0x0e, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x16, - 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, - 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x22, - 0x00, 0x12, 0x43, 0x0a, 0x0e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, - 0x6f, 0x72, 0x64, 0x12, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e, 0x61, 0x70, - 0x69, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, - 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x43, 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, - 0x1a, 0x17, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x61, 0x73, - 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x3e, 0x0a, 0x0d, 0x4c, - 0x69, 0x73, 0x74, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x12, 0x14, 0x2e, 0x61, - 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, - 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x73, - 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x31, 0x0a, 0x0a, 0x47, - 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x0f, 0x2e, 0x61, 0x70, 0x69, 0x2e, - 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x10, 0x2e, 0x61, 0x70, 0x69, - 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x3a, - 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x12, 0x13, 0x2e, - 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x52, - 0x65, 0x71, 0x1a, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x66, - 0x72, 0x65, 0x73, 0x68, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x40, 0x0a, 0x0d, 0x52, 0x65, - 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x12, 0x15, 0x2e, 0x61, 0x70, - 0x69, 0x2e, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x52, - 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x52, - 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x43, 0x0a, 0x0e, - 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x16, - 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x50, 0x61, 0x73, 0x73, 0x77, - 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x56, 0x65, 0x72, - 0x69, 0x66, 0x79, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x22, - 0x00, 0x42, 0x36, 0x0a, 0x12, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x6f, 0x73, 0x2e, - 0x64, 0x65, 0x78, 0x2e, 0x61, 0x70, 0x69, 0x5a, 0x20, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x64, 0x65, 0x78, 0x69, 0x64, 0x70, 0x2f, 0x64, 0x65, 0x78, 0x2f, 0x61, - 0x70, 0x69, 0x2f, 0x76, 0x32, 0x3b, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x0a, 0x0c, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x14, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x43, 0x0a, + 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, + 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, + 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, + 0x22, 0x00, 0x12, 0x43, 0x0a, 0x0e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, + 0x77, 0x6f, 0x72, 0x64, 0x12, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, + 0x64, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x43, 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, + 0x71, 0x1a, 0x17, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x61, + 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x3e, 0x0a, 0x0d, + 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x12, 0x14, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, + 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, + 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x46, 0x0a, 0x0f, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, + 0x17, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x65, + 0x73, 0x70, 0x22, 0x00, 0x12, 0x46, 0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x17, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, + 0x1a, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, + 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x46, 0x0a, 0x0f, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, + 0x17, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x65, + 0x73, 0x70, 0x22, 0x00, 0x12, 0x41, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x31, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x56, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x0f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x10, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x56, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x3a, 0x0a, 0x0b, 0x4c, 0x69, + 0x73, 0x74, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x12, 0x13, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x52, 0x65, 0x71, 0x1a, 0x14, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, + 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x40, 0x0a, 0x0d, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, + 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x12, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, + 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x52, 0x65, 0x71, 0x1a, 0x16, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x66, 0x72, 0x65, + 0x73, 0x68, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x43, 0x0a, 0x0e, 0x56, 0x65, 0x72, 0x69, + 0x66, 0x79, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x16, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, + 0x65, 0x71, 0x1a, 0x17, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x50, + 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x42, 0x36, 0x0a, + 0x12, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x6f, 0x73, 0x2e, 0x64, 0x65, 0x78, 0x2e, + 0x61, 0x70, 0x69, 0x5a, 0x20, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x64, 0x65, 0x78, 0x69, 0x64, 0x70, 0x2f, 0x64, 0x65, 0x78, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, + 0x32, 0x3b, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1680,35 +2205,44 @@ func file_api_v2_api_proto_rawDescGZIP() []byte { return file_api_v2_api_proto_rawDescData } -var file_api_v2_api_proto_msgTypes = make([]protoimpl.MessageInfo, 27) +var file_api_v2_api_proto_msgTypes = make([]protoimpl.MessageInfo, 36) var file_api_v2_api_proto_goTypes = []interface{}{ - (*Client)(nil), // 0: api.Client - (*GetClientReq)(nil), // 1: api.GetClientReq - (*GetClientResp)(nil), // 2: api.GetClientResp - (*CreateClientReq)(nil), // 3: api.CreateClientReq - (*CreateClientResp)(nil), // 4: api.CreateClientResp - (*DeleteClientReq)(nil), // 5: api.DeleteClientReq - (*DeleteClientResp)(nil), // 6: api.DeleteClientResp - (*UpdateClientReq)(nil), // 7: api.UpdateClientReq - (*UpdateClientResp)(nil), // 8: api.UpdateClientResp - (*Password)(nil), // 9: api.Password - (*CreatePasswordReq)(nil), // 10: api.CreatePasswordReq - (*CreatePasswordResp)(nil), // 11: api.CreatePasswordResp - (*UpdatePasswordReq)(nil), // 12: api.UpdatePasswordReq - (*UpdatePasswordResp)(nil), // 13: api.UpdatePasswordResp - (*DeletePasswordReq)(nil), // 14: api.DeletePasswordReq - (*DeletePasswordResp)(nil), // 15: api.DeletePasswordResp - (*ListPasswordReq)(nil), // 16: api.ListPasswordReq - (*ListPasswordResp)(nil), // 17: api.ListPasswordResp - (*VersionReq)(nil), // 18: api.VersionReq - (*VersionResp)(nil), // 19: api.VersionResp - (*RefreshTokenRef)(nil), // 20: api.RefreshTokenRef - (*ListRefreshReq)(nil), // 21: api.ListRefreshReq - (*ListRefreshResp)(nil), // 22: api.ListRefreshResp - (*RevokeRefreshReq)(nil), // 23: api.RevokeRefreshReq - (*RevokeRefreshResp)(nil), // 24: api.RevokeRefreshResp - (*VerifyPasswordReq)(nil), // 25: api.VerifyPasswordReq - (*VerifyPasswordResp)(nil), // 26: api.VerifyPasswordResp + (*Client)(nil), // 0: api.Client + (*GetClientReq)(nil), // 1: api.GetClientReq + (*GetClientResp)(nil), // 2: api.GetClientResp + (*CreateClientReq)(nil), // 3: api.CreateClientReq + (*CreateClientResp)(nil), // 4: api.CreateClientResp + (*DeleteClientReq)(nil), // 5: api.DeleteClientReq + (*DeleteClientResp)(nil), // 6: api.DeleteClientResp + (*UpdateClientReq)(nil), // 7: api.UpdateClientReq + (*UpdateClientResp)(nil), // 8: api.UpdateClientResp + (*Password)(nil), // 9: api.Password + (*CreatePasswordReq)(nil), // 10: api.CreatePasswordReq + (*CreatePasswordResp)(nil), // 11: api.CreatePasswordResp + (*UpdatePasswordReq)(nil), // 12: api.UpdatePasswordReq + (*UpdatePasswordResp)(nil), // 13: api.UpdatePasswordResp + (*DeletePasswordReq)(nil), // 14: api.DeletePasswordReq + (*DeletePasswordResp)(nil), // 15: api.DeletePasswordResp + (*ListPasswordReq)(nil), // 16: api.ListPasswordReq + (*ListPasswordResp)(nil), // 17: api.ListPasswordResp + (*Connector)(nil), // 18: api.Connector + (*CreateConnectorReq)(nil), // 19: api.CreateConnectorReq + (*CreateConnectorResp)(nil), // 20: api.CreateConnectorResp + (*UpdateConnectorReq)(nil), // 21: api.UpdateConnectorReq + (*UpdateConnectorResp)(nil), // 22: api.UpdateConnectorResp + (*DeleteConnectorReq)(nil), // 23: api.DeleteConnectorReq + (*DeleteConnectorResp)(nil), // 24: api.DeleteConnectorResp + (*ListConnectorReq)(nil), // 25: api.ListConnectorReq + (*ListConnectorResp)(nil), // 26: api.ListConnectorResp + (*VersionReq)(nil), // 27: api.VersionReq + (*VersionResp)(nil), // 28: api.VersionResp + (*RefreshTokenRef)(nil), // 29: api.RefreshTokenRef + (*ListRefreshReq)(nil), // 30: api.ListRefreshReq + (*ListRefreshResp)(nil), // 31: api.ListRefreshResp + (*RevokeRefreshReq)(nil), // 32: api.RevokeRefreshReq + (*RevokeRefreshResp)(nil), // 33: api.RevokeRefreshResp + (*VerifyPasswordReq)(nil), // 34: api.VerifyPasswordReq + (*VerifyPasswordResp)(nil), // 35: api.VerifyPasswordResp } var file_api_v2_api_proto_depIdxs = []int32{ 0, // 0: api.GetClientResp.client:type_name -> api.Client @@ -1716,36 +2250,46 @@ var file_api_v2_api_proto_depIdxs = []int32{ 0, // 2: api.CreateClientResp.client:type_name -> api.Client 9, // 3: api.CreatePasswordReq.password:type_name -> api.Password 9, // 4: api.ListPasswordResp.passwords:type_name -> api.Password - 20, // 5: api.ListRefreshResp.refresh_tokens:type_name -> api.RefreshTokenRef - 1, // 6: api.Dex.GetClient:input_type -> api.GetClientReq - 3, // 7: api.Dex.CreateClient:input_type -> api.CreateClientReq - 7, // 8: api.Dex.UpdateClient:input_type -> api.UpdateClientReq - 5, // 9: api.Dex.DeleteClient:input_type -> api.DeleteClientReq - 10, // 10: api.Dex.CreatePassword:input_type -> api.CreatePasswordReq - 12, // 11: api.Dex.UpdatePassword:input_type -> api.UpdatePasswordReq - 14, // 12: api.Dex.DeletePassword:input_type -> api.DeletePasswordReq - 16, // 13: api.Dex.ListPasswords:input_type -> api.ListPasswordReq - 18, // 14: api.Dex.GetVersion:input_type -> api.VersionReq - 21, // 15: api.Dex.ListRefresh:input_type -> api.ListRefreshReq - 23, // 16: api.Dex.RevokeRefresh:input_type -> api.RevokeRefreshReq - 25, // 17: api.Dex.VerifyPassword:input_type -> api.VerifyPasswordReq - 2, // 18: api.Dex.GetClient:output_type -> api.GetClientResp - 4, // 19: api.Dex.CreateClient:output_type -> api.CreateClientResp - 8, // 20: api.Dex.UpdateClient:output_type -> api.UpdateClientResp - 6, // 21: api.Dex.DeleteClient:output_type -> api.DeleteClientResp - 11, // 22: api.Dex.CreatePassword:output_type -> api.CreatePasswordResp - 13, // 23: api.Dex.UpdatePassword:output_type -> api.UpdatePasswordResp - 15, // 24: api.Dex.DeletePassword:output_type -> api.DeletePasswordResp - 17, // 25: api.Dex.ListPasswords:output_type -> api.ListPasswordResp - 19, // 26: api.Dex.GetVersion:output_type -> api.VersionResp - 22, // 27: api.Dex.ListRefresh:output_type -> api.ListRefreshResp - 24, // 28: api.Dex.RevokeRefresh:output_type -> api.RevokeRefreshResp - 26, // 29: api.Dex.VerifyPassword:output_type -> api.VerifyPasswordResp - 18, // [18:30] is the sub-list for method output_type - 6, // [6:18] is the sub-list for method input_type - 6, // [6:6] is the sub-list for extension type_name - 6, // [6:6] is the sub-list for extension extendee - 0, // [0:6] is the sub-list for field type_name + 18, // 5: api.CreateConnectorReq.connector:type_name -> api.Connector + 18, // 6: api.ListConnectorResp.connectors:type_name -> api.Connector + 29, // 7: api.ListRefreshResp.refresh_tokens:type_name -> api.RefreshTokenRef + 1, // 8: api.Dex.GetClient:input_type -> api.GetClientReq + 3, // 9: api.Dex.CreateClient:input_type -> api.CreateClientReq + 7, // 10: api.Dex.UpdateClient:input_type -> api.UpdateClientReq + 5, // 11: api.Dex.DeleteClient:input_type -> api.DeleteClientReq + 10, // 12: api.Dex.CreatePassword:input_type -> api.CreatePasswordReq + 12, // 13: api.Dex.UpdatePassword:input_type -> api.UpdatePasswordReq + 14, // 14: api.Dex.DeletePassword:input_type -> api.DeletePasswordReq + 16, // 15: api.Dex.ListPasswords:input_type -> api.ListPasswordReq + 19, // 16: api.Dex.CreateConnector:input_type -> api.CreateConnectorReq + 21, // 17: api.Dex.UpdateConnector:input_type -> api.UpdateConnectorReq + 23, // 18: api.Dex.DeleteConnector:input_type -> api.DeleteConnectorReq + 25, // 19: api.Dex.ListConnectors:input_type -> api.ListConnectorReq + 27, // 20: api.Dex.GetVersion:input_type -> api.VersionReq + 30, // 21: api.Dex.ListRefresh:input_type -> api.ListRefreshReq + 32, // 22: api.Dex.RevokeRefresh:input_type -> api.RevokeRefreshReq + 34, // 23: api.Dex.VerifyPassword:input_type -> api.VerifyPasswordReq + 2, // 24: api.Dex.GetClient:output_type -> api.GetClientResp + 4, // 25: api.Dex.CreateClient:output_type -> api.CreateClientResp + 8, // 26: api.Dex.UpdateClient:output_type -> api.UpdateClientResp + 6, // 27: api.Dex.DeleteClient:output_type -> api.DeleteClientResp + 11, // 28: api.Dex.CreatePassword:output_type -> api.CreatePasswordResp + 13, // 29: api.Dex.UpdatePassword:output_type -> api.UpdatePasswordResp + 15, // 30: api.Dex.DeletePassword:output_type -> api.DeletePasswordResp + 17, // 31: api.Dex.ListPasswords:output_type -> api.ListPasswordResp + 20, // 32: api.Dex.CreateConnector:output_type -> api.CreateConnectorResp + 22, // 33: api.Dex.UpdateConnector:output_type -> api.UpdateConnectorResp + 24, // 34: api.Dex.DeleteConnector:output_type -> api.DeleteConnectorResp + 26, // 35: api.Dex.ListConnectors:output_type -> api.ListConnectorResp + 28, // 36: api.Dex.GetVersion:output_type -> api.VersionResp + 31, // 37: api.Dex.ListRefresh:output_type -> api.ListRefreshResp + 33, // 38: api.Dex.RevokeRefresh:output_type -> api.RevokeRefreshResp + 35, // 39: api.Dex.VerifyPassword:output_type -> api.VerifyPasswordResp + 24, // [24:40] is the sub-list for method output_type + 8, // [8:24] is the sub-list for method input_type + 8, // [8:8] is the sub-list for extension type_name + 8, // [8:8] is the sub-list for extension extendee + 0, // [0:8] is the sub-list for field type_name } func init() { file_api_v2_api_proto_init() } @@ -1971,7 +2515,7 @@ func file_api_v2_api_proto_init() { } } file_api_v2_api_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*VersionReq); i { + switch v := v.(*Connector); i { case 0: return &v.state case 1: @@ -1983,7 +2527,7 @@ func file_api_v2_api_proto_init() { } } file_api_v2_api_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*VersionResp); i { + switch v := v.(*CreateConnectorReq); i { case 0: return &v.state case 1: @@ -1995,7 +2539,7 @@ func file_api_v2_api_proto_init() { } } file_api_v2_api_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RefreshTokenRef); i { + switch v := v.(*CreateConnectorResp); i { case 0: return &v.state case 1: @@ -2007,7 +2551,7 @@ func file_api_v2_api_proto_init() { } } file_api_v2_api_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListRefreshReq); i { + switch v := v.(*UpdateConnectorReq); i { case 0: return &v.state case 1: @@ -2019,7 +2563,7 @@ func file_api_v2_api_proto_init() { } } file_api_v2_api_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListRefreshResp); i { + switch v := v.(*UpdateConnectorResp); i { case 0: return &v.state case 1: @@ -2031,7 +2575,7 @@ func file_api_v2_api_proto_init() { } } file_api_v2_api_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RevokeRefreshReq); i { + switch v := v.(*DeleteConnectorReq); i { case 0: return &v.state case 1: @@ -2043,7 +2587,7 @@ func file_api_v2_api_proto_init() { } } file_api_v2_api_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RevokeRefreshResp); i { + switch v := v.(*DeleteConnectorResp); i { case 0: return &v.state case 1: @@ -2055,7 +2599,7 @@ func file_api_v2_api_proto_init() { } } file_api_v2_api_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*VerifyPasswordReq); i { + switch v := v.(*ListConnectorReq); i { case 0: return &v.state case 1: @@ -2067,6 +2611,114 @@ func file_api_v2_api_proto_init() { } } file_api_v2_api_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListConnectorResp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_api_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*VersionReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_api_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*VersionResp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_api_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RefreshTokenRef); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_api_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListRefreshReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_api_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListRefreshResp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_api_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RevokeRefreshReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_api_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RevokeRefreshResp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_api_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*VerifyPasswordReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_api_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*VerifyPasswordResp); i { case 0: return &v.state @@ -2085,7 +2737,7 @@ func file_api_v2_api_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_api_v2_api_proto_rawDesc, NumEnums: 0, - NumMessages: 27, + NumMessages: 36, NumExtensions: 0, NumServices: 1, }, diff --git a/api/v2/api.proto b/api/v2/api.proto index c429fd806a..7f2c80b940 100644 --- a/api/v2/api.proto +++ b/api/v2/api.proto @@ -116,6 +116,56 @@ message ListPasswordResp { repeated Password passwords = 1; } +// Connector is a strategy used by Dex for authenticating a user against another identity provider +message Connector { + string id = 1; + string type = 2; + string name = 3; + bytes config = 4; +} + +// CreateConnectorReq is a request to make a connector. +message CreateConnectorReq { + Connector connector = 1; +} + +// CreateConnectorResp returns the response from creating a connector. +message CreateConnectorResp { + bool already_exists = 1; +} + +// UpdateConnectorReq is a request to modify an existing connector. +message UpdateConnectorReq { + // The id used to lookup the connector. This field cannot be modified + string id = 1; + string new_type = 2; + string new_name = 3; + bytes new_config = 4; +} + +// UpdateConnectorResp returns the response from modifying an existing connector. +message UpdateConnectorResp { + bool not_found = 1; +} + +// DeleteConnectorReq is a request to delete a connector. +message DeleteConnectorReq { + string id = 1; +} + +// DeleteConnectorResp returns the response from deleting a connector. +message DeleteConnectorResp { + bool not_found = 1; +} + +// ListConnectorReq is a request to enumerate connectors. +message ListConnectorReq {} + +// ListConnectorResp returns a list of connectors. +message ListConnectorResp { + repeated Connector connectors = 1; +} + // VersionReq is a request to fetch version info. message VersionReq {} @@ -189,6 +239,14 @@ service Dex { rpc DeletePassword(DeletePasswordReq) returns (DeletePasswordResp) {}; // ListPassword lists all password entries. rpc ListPasswords(ListPasswordReq) returns (ListPasswordResp) {}; + // CreateConnector creates a connector. + rpc CreateConnector(CreateConnectorReq) returns (CreateConnectorResp) {}; + // UpdateConnector modifies existing connector. + rpc UpdateConnector(UpdateConnectorReq) returns (UpdateConnectorResp) {}; + // DeleteConnector deletes the connector. + rpc DeleteConnector(DeleteConnectorReq) returns (DeleteConnectorResp) {}; + // ListConnectors lists all connector entries. + rpc ListConnectors(ListConnectorReq) returns (ListConnectorResp) {}; // GetVersion returns version information of the server. rpc GetVersion(VersionReq) returns (VersionResp) {}; // ListRefresh lists all the refresh token entries for a particular user. diff --git a/api/v2/api_grpc.pb.go b/api/v2/api_grpc.pb.go index fcbb985492..7ffab5aba9 100644 --- a/api/v2/api_grpc.pb.go +++ b/api/v2/api_grpc.pb.go @@ -19,18 +19,22 @@ import ( const _ = grpc.SupportPackageIsVersion7 const ( - Dex_GetClient_FullMethodName = "/api.Dex/GetClient" - Dex_CreateClient_FullMethodName = "/api.Dex/CreateClient" - Dex_UpdateClient_FullMethodName = "/api.Dex/UpdateClient" - Dex_DeleteClient_FullMethodName = "/api.Dex/DeleteClient" - Dex_CreatePassword_FullMethodName = "/api.Dex/CreatePassword" - Dex_UpdatePassword_FullMethodName = "/api.Dex/UpdatePassword" - Dex_DeletePassword_FullMethodName = "/api.Dex/DeletePassword" - Dex_ListPasswords_FullMethodName = "/api.Dex/ListPasswords" - Dex_GetVersion_FullMethodName = "/api.Dex/GetVersion" - Dex_ListRefresh_FullMethodName = "/api.Dex/ListRefresh" - Dex_RevokeRefresh_FullMethodName = "/api.Dex/RevokeRefresh" - Dex_VerifyPassword_FullMethodName = "/api.Dex/VerifyPassword" + Dex_GetClient_FullMethodName = "/api.Dex/GetClient" + Dex_CreateClient_FullMethodName = "/api.Dex/CreateClient" + Dex_UpdateClient_FullMethodName = "/api.Dex/UpdateClient" + Dex_DeleteClient_FullMethodName = "/api.Dex/DeleteClient" + Dex_CreatePassword_FullMethodName = "/api.Dex/CreatePassword" + Dex_UpdatePassword_FullMethodName = "/api.Dex/UpdatePassword" + Dex_DeletePassword_FullMethodName = "/api.Dex/DeletePassword" + Dex_ListPasswords_FullMethodName = "/api.Dex/ListPasswords" + Dex_CreateConnector_FullMethodName = "/api.Dex/CreateConnector" + Dex_UpdateConnector_FullMethodName = "/api.Dex/UpdateConnector" + Dex_DeleteConnector_FullMethodName = "/api.Dex/DeleteConnector" + Dex_ListConnectors_FullMethodName = "/api.Dex/ListConnectors" + Dex_GetVersion_FullMethodName = "/api.Dex/GetVersion" + Dex_ListRefresh_FullMethodName = "/api.Dex/ListRefresh" + Dex_RevokeRefresh_FullMethodName = "/api.Dex/RevokeRefresh" + Dex_VerifyPassword_FullMethodName = "/api.Dex/VerifyPassword" ) // DexClient is the client API for Dex service. @@ -53,6 +57,14 @@ type DexClient interface { DeletePassword(ctx context.Context, in *DeletePasswordReq, opts ...grpc.CallOption) (*DeletePasswordResp, error) // ListPassword lists all password entries. ListPasswords(ctx context.Context, in *ListPasswordReq, opts ...grpc.CallOption) (*ListPasswordResp, error) + // CreateConnector creates a connector. + CreateConnector(ctx context.Context, in *CreateConnectorReq, opts ...grpc.CallOption) (*CreateConnectorResp, error) + // UpdateConnector modifies existing connector. + UpdateConnector(ctx context.Context, in *UpdateConnectorReq, opts ...grpc.CallOption) (*UpdateConnectorResp, error) + // DeleteConnector deletes the connector. + DeleteConnector(ctx context.Context, in *DeleteConnectorReq, opts ...grpc.CallOption) (*DeleteConnectorResp, error) + // ListConnectors lists all connector entries. + ListConnectors(ctx context.Context, in *ListConnectorReq, opts ...grpc.CallOption) (*ListConnectorResp, error) // GetVersion returns version information of the server. GetVersion(ctx context.Context, in *VersionReq, opts ...grpc.CallOption) (*VersionResp, error) // ListRefresh lists all the refresh token entries for a particular user. @@ -145,6 +157,42 @@ func (c *dexClient) ListPasswords(ctx context.Context, in *ListPasswordReq, opts return out, nil } +func (c *dexClient) CreateConnector(ctx context.Context, in *CreateConnectorReq, opts ...grpc.CallOption) (*CreateConnectorResp, error) { + out := new(CreateConnectorResp) + err := c.cc.Invoke(ctx, Dex_CreateConnector_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *dexClient) UpdateConnector(ctx context.Context, in *UpdateConnectorReq, opts ...grpc.CallOption) (*UpdateConnectorResp, error) { + out := new(UpdateConnectorResp) + err := c.cc.Invoke(ctx, Dex_UpdateConnector_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *dexClient) DeleteConnector(ctx context.Context, in *DeleteConnectorReq, opts ...grpc.CallOption) (*DeleteConnectorResp, error) { + out := new(DeleteConnectorResp) + err := c.cc.Invoke(ctx, Dex_DeleteConnector_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *dexClient) ListConnectors(ctx context.Context, in *ListConnectorReq, opts ...grpc.CallOption) (*ListConnectorResp, error) { + out := new(ListConnectorResp) + err := c.cc.Invoke(ctx, Dex_ListConnectors_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *dexClient) GetVersion(ctx context.Context, in *VersionReq, opts ...grpc.CallOption) (*VersionResp, error) { out := new(VersionResp) err := c.cc.Invoke(ctx, Dex_GetVersion_FullMethodName, in, out, opts...) @@ -201,6 +249,14 @@ type DexServer interface { DeletePassword(context.Context, *DeletePasswordReq) (*DeletePasswordResp, error) // ListPassword lists all password entries. ListPasswords(context.Context, *ListPasswordReq) (*ListPasswordResp, error) + // CreateConnector creates a connector. + CreateConnector(context.Context, *CreateConnectorReq) (*CreateConnectorResp, error) + // UpdateConnector modifies existing connector. + UpdateConnector(context.Context, *UpdateConnectorReq) (*UpdateConnectorResp, error) + // DeleteConnector deletes the connector. + DeleteConnector(context.Context, *DeleteConnectorReq) (*DeleteConnectorResp, error) + // ListConnectors lists all connector entries. + ListConnectors(context.Context, *ListConnectorReq) (*ListConnectorResp, error) // GetVersion returns version information of the server. GetVersion(context.Context, *VersionReq) (*VersionResp, error) // ListRefresh lists all the refresh token entries for a particular user. @@ -242,6 +298,18 @@ func (UnimplementedDexServer) DeletePassword(context.Context, *DeletePasswordReq func (UnimplementedDexServer) ListPasswords(context.Context, *ListPasswordReq) (*ListPasswordResp, error) { return nil, status.Errorf(codes.Unimplemented, "method ListPasswords not implemented") } +func (UnimplementedDexServer) CreateConnector(context.Context, *CreateConnectorReq) (*CreateConnectorResp, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateConnector not implemented") +} +func (UnimplementedDexServer) UpdateConnector(context.Context, *UpdateConnectorReq) (*UpdateConnectorResp, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateConnector not implemented") +} +func (UnimplementedDexServer) DeleteConnector(context.Context, *DeleteConnectorReq) (*DeleteConnectorResp, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteConnector not implemented") +} +func (UnimplementedDexServer) ListConnectors(context.Context, *ListConnectorReq) (*ListConnectorResp, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListConnectors not implemented") +} func (UnimplementedDexServer) GetVersion(context.Context, *VersionReq) (*VersionResp, error) { return nil, status.Errorf(codes.Unimplemented, "method GetVersion not implemented") } @@ -411,6 +479,78 @@ func _Dex_ListPasswords_Handler(srv interface{}, ctx context.Context, dec func(i return interceptor(ctx, in, info, handler) } +func _Dex_CreateConnector_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateConnectorReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DexServer).CreateConnector(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Dex_CreateConnector_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DexServer).CreateConnector(ctx, req.(*CreateConnectorReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dex_UpdateConnector_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateConnectorReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DexServer).UpdateConnector(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Dex_UpdateConnector_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DexServer).UpdateConnector(ctx, req.(*UpdateConnectorReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dex_DeleteConnector_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteConnectorReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DexServer).DeleteConnector(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Dex_DeleteConnector_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DexServer).DeleteConnector(ctx, req.(*DeleteConnectorReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _Dex_ListConnectors_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListConnectorReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DexServer).ListConnectors(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Dex_ListConnectors_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DexServer).ListConnectors(ctx, req.(*ListConnectorReq)) + } + return interceptor(ctx, in, info, handler) +} + func _Dex_GetVersion_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(VersionReq) if err := dec(in); err != nil { @@ -522,6 +662,22 @@ var Dex_ServiceDesc = grpc.ServiceDesc{ MethodName: "ListPasswords", Handler: _Dex_ListPasswords_Handler, }, + { + MethodName: "CreateConnector", + Handler: _Dex_CreateConnector_Handler, + }, + { + MethodName: "UpdateConnector", + Handler: _Dex_UpdateConnector_Handler, + }, + { + MethodName: "DeleteConnector", + Handler: _Dex_DeleteConnector_Handler, + }, + { + MethodName: "ListConnectors", + Handler: _Dex_ListConnectors_Handler, + }, { MethodName: "GetVersion", Handler: _Dex_GetVersion_Handler, diff --git a/cmd/dex/config.go b/cmd/dex/config.go index b6d34f37e2..474f28a6e7 100644 --- a/cmd/dex/config.go +++ b/cmd/dex/config.go @@ -7,6 +7,7 @@ import ( "log/slog" "net/http" "os" + "slices" "strings" "golang.org/x/crypto/bcrypt" @@ -50,10 +51,22 @@ type Config struct { // querying the storage. Cannot be specified without enabling a passwords // database. StaticPasswords []password `json:"staticPasswords"` + + // AdditionalFeature allow the extension of Dex functionalities + AdditionalFeatures []server.AdditionalFeature `json:"additionalFeatures"` +} + +// Parse the configuration +func (c *Config) Parse() { + if c.AdditionalFeatures == nil { + c.AdditionalFeatures = []server.AdditionalFeature{} + } } // Validate the configuration func (c Config) Validate() error { + invalidFeatures := c.findInvalidAdditionalFeatures() + // Fast checks. Perform these first for a more responsive CLI. checks := []struct { bad bool @@ -72,6 +85,7 @@ func (c Config) Validate() error { {c.GRPC.TLSKey != "" && c.GRPC.Addr == "", "no address specified for gRPC"}, {(c.GRPC.TLSCert == "") != (c.GRPC.TLSKey == ""), "must specific both a gRPC TLS cert and key"}, {c.GRPC.TLSCert == "" && c.GRPC.TLSClientCA != "", "cannot specify gRPC TLS client CA without a gRPC TLS cert"}, + {len(invalidFeatures) > 0, fmt.Sprintf("invalid additionalFeatures supplied: %v. Valid entries: %s", invalidFeatures, server.ValidAdditionalFeatures)}, {c.GRPC.TLSMinVersion != "" && c.GRPC.TLSMinVersion != "1.2" && c.GRPC.TLSMinVersion != "1.3", "supported TLS versions are: 1.2, 1.3"}, {c.GRPC.TLSMaxVersion != "" && c.GRPC.TLSMaxVersion != "1.2" && c.GRPC.TLSMaxVersion != "1.3", "supported TLS versions are: 1.2, 1.3"}, {c.GRPC.TLSMaxVersion != "" && c.GRPC.TLSMinVersion != "" && c.GRPC.TLSMinVersion > c.GRPC.TLSMaxVersion, "TLSMinVersion greater than TLSMaxVersion"}, @@ -90,6 +104,22 @@ func (c Config) Validate() error { return nil } +// findInvalidAdditionalFeatures returns additional features that are not considered valid +func (c Config) findInvalidAdditionalFeatures() []server.AdditionalFeature { + if c.AdditionalFeatures == nil { + return []server.AdditionalFeature{} + } + + badFeatures := []server.AdditionalFeature{} + for _, feature := range c.AdditionalFeatures { + if !slices.Contains(server.ValidAdditionalFeatures, feature) { + badFeatures = append(badFeatures, feature) + } + } + + return badFeatures +} + type password storage.Password func (p *password) UnmarshalJSON(b []byte) error { diff --git a/cmd/dex/config_test.go b/cmd/dex/config_test.go index 95a79eb27f..8924931d36 100644 --- a/cmd/dex/config_test.go +++ b/cmd/dex/config_test.go @@ -37,7 +37,11 @@ func TestValidConfiguration(t *testing.T) { Config: &mock.CallbackConfig{}, }, }, + AdditionalFeatures: server.ValidAdditionalFeatures, } + + configuration.Parse() + if err := configuration.Validate(); err != nil { t.Fatalf("this configuration should have been valid: %v", err) } @@ -45,6 +49,7 @@ func TestValidConfiguration(t *testing.T) { func TestInvalidConfiguration(t *testing.T) { configuration := Config{} + configuration.Parse() err := configuration.Validate() if err == nil { t.Fatal("this configuration should be invalid") @@ -131,6 +136,10 @@ expiry: logger: level: "debug" format: "json" + +additionalFeatures: [ + "ConnectorsCRUD" +] `) want := Config{ @@ -223,12 +232,16 @@ logger: Level: slog.LevelDebug, Format: "json", }, + AdditionalFeatures: server.ValidAdditionalFeatures, } var c Config if err := yaml.Unmarshal(rawConfig, &c); err != nil { t.Fatalf("failed to decode config: %v", err) } + + c.Parse() + if diff := pretty.Compare(c, want); diff != "" { t.Errorf("got!=want: %s", diff) } @@ -436,7 +449,19 @@ logger: if err := yaml.Unmarshal(rawConfig, &c); err != nil { t.Fatalf("failed to decode config: %v", err) } + + c.Parse() + if diff := pretty.Compare(c, want); diff != "" { t.Errorf("got!=want: %s", diff) } } + +func TestParseConfig(t *testing.T) { + configuration := Config{} + configuration.Parse() + + if configuration.AdditionalFeatures == nil || len(configuration.AdditionalFeatures) != 0 { + t.Fatal("AdditionalFeatures should be an empty slice") + } +} diff --git a/cmd/dex/serve.go b/cmd/dex/serve.go index 19bf2637f8..863f039b30 100644 --- a/cmd/dex/serve.go +++ b/cmd/dex/serve.go @@ -99,6 +99,7 @@ func runServe(options serveOptions) error { return fmt.Errorf("error parse config file %s: %v", configFile, err) } + c.Parse() applyConfigOverrides(options, &c) logger, err := newLogger(c.Logger.Level, c.Logger.Format) @@ -501,7 +502,7 @@ func runServe(options serveOptions) error { } grpcSrv := grpc.NewServer(grpcOptions...) - api.RegisterDexServer(grpcSrv, server.NewAPI(serverConfig.Storage, logger, version)) + api.RegisterDexServer(grpcSrv, server.NewAPI(serverConfig.Storage, logger, version, c.AdditionalFeatures)) grpcMetrics.InitializeMetrics(grpcSrv) if c.GRPC.Reflection { diff --git a/examples/config-dev.yaml b/examples/config-dev.yaml index 8f1018ffcc..8e569949dd 100644 --- a/examples/config-dev.yaml +++ b/examples/config-dev.yaml @@ -162,3 +162,8 @@ staticPasswords: hash: "$2a$10$2b2cU8CPhOTaGrs1HRQuAueS7JTT5ZHsHSzYiFPm1leZck7Mc8T4W" username: "admin" userID: "08a8684b-db88-4b73-90a9-3cd1661f5466" + +# A list of features that extend Dex functionalities +# additionalFeatures: +# # allows CRUD operations on connectors through the gRPC API +# - "ConnectorsCRUD" \ No newline at end of file diff --git a/server/api.go b/server/api.go index 6a0071efb8..090b412cd4 100644 --- a/server/api.go +++ b/server/api.go @@ -2,9 +2,11 @@ package server import ( "context" + "encoding/json" "errors" "fmt" "log/slog" + "slices" "golang.org/x/crypto/bcrypt" @@ -29,11 +31,12 @@ const ( ) // NewAPI returns a server which implements the gRPC API interface. -func NewAPI(s storage.Storage, logger *slog.Logger, version string) api.DexServer { +func NewAPI(s storage.Storage, logger *slog.Logger, version string, additionalFeatures []AdditionalFeature) api.DexServer { return dexAPI{ - s: s, - logger: logger.With("component", "api"), - version: version, + s: s, + logger: logger.With("component", "api"), + version: version, + additionalFeatures: additionalFeatures, } } @@ -43,6 +46,8 @@ type dexAPI struct { s storage.Storage logger *slog.Logger version string + + additionalFeatures []AdditionalFeature } func (d dexAPI) GetClient(ctx context.Context, req *api.GetClientReq) (*api.GetClientResp, error) { @@ -385,3 +390,136 @@ func (d dexAPI) RevokeRefresh(ctx context.Context, req *api.RevokeRefreshReq) (* return &api.RevokeRefreshResp{}, nil } + +func (d dexAPI) CreateConnector(ctx context.Context, req *api.CreateConnectorReq) (*api.CreateConnectorResp, error) { + if !slices.Contains(d.additionalFeatures, ConnectorsCRUD) { + return nil, fmt.Errorf("%v not provided in addtionalFeatures", ConnectorsCRUD) + } + + if req.Connector.Id == "" { + return nil, errors.New("no id supplied") + } + + if req.Connector.Type == "" { + return nil, errors.New("no type supplied") + } + + if req.Connector.Name == "" { + return nil, errors.New("no name supplied") + } + + if len(req.Connector.Config) == 0 { + return nil, errors.New("no config supplied") + } + + if !json.Valid(req.Connector.Config) { + return nil, errors.New("invalid config supplied") + } + + c := storage.Connector{ + ID: req.Connector.Id, + Name: req.Connector.Name, + Type: req.Connector.Type, + Config: req.Connector.Config, + } + if err := d.s.CreateConnector(ctx, c); err != nil { + if err == storage.ErrAlreadyExists { + return &api.CreateConnectorResp{AlreadyExists: true}, nil + } + d.logger.Error("api: failed to create connector", "err", err) + return nil, fmt.Errorf("create connector: %v", err) + } + + return &api.CreateConnectorResp{}, nil +} + +func (d dexAPI) UpdateConnector(ctx context.Context, req *api.UpdateConnectorReq) (*api.UpdateConnectorResp, error) { + if !slices.Contains(d.additionalFeatures, ConnectorsCRUD) { + return nil, fmt.Errorf("%v not provided in addtionalFeatures", ConnectorsCRUD) + } + + if req.Id == "" { + return nil, errors.New("no email supplied") + } + + if len(req.NewConfig) == 0 && req.NewName == "" && req.NewType == "" { + return nil, errors.New("nothing to update") + } + + if !json.Valid(req.NewConfig) { + return nil, errors.New("invalid config supplied") + } + + updater := func(old storage.Connector) (storage.Connector, error) { + if req.NewType != "" { + old.Type = req.NewType + } + + if req.NewName != "" { + old.Name = req.NewName + } + + if len(req.NewConfig) != 0 { + old.Config = req.NewConfig + } + + return old, nil + } + + if err := d.s.UpdateConnector(req.Id, updater); err != nil { + if err == storage.ErrNotFound { + return &api.UpdateConnectorResp{NotFound: true}, nil + } + d.logger.Error("api: failed to update connector", "err", err) + return nil, fmt.Errorf("update connector: %v", err) + } + + return &api.UpdateConnectorResp{}, nil +} + +func (d dexAPI) DeleteConnector(ctx context.Context, req *api.DeleteConnectorReq) (*api.DeleteConnectorResp, error) { + if !slices.Contains(d.additionalFeatures, ConnectorsCRUD) { + return nil, fmt.Errorf("%v not provided in addtionalFeatures", ConnectorsCRUD) + } + + if req.Id == "" { + return nil, errors.New("no id supplied") + } + + err := d.s.DeleteConnector(req.Id) + if err != nil { + if err == storage.ErrNotFound { + return &api.DeleteConnectorResp{NotFound: true}, nil + } + d.logger.Error("api: failed to delete connector", "err", err) + return nil, fmt.Errorf("delete connector: %v", err) + } + return &api.DeleteConnectorResp{}, nil +} + +func (d dexAPI) ListConnectors(ctx context.Context, req *api.ListConnectorReq) (*api.ListConnectorResp, error) { + if !slices.Contains(d.additionalFeatures, ConnectorsCRUD) { + return nil, fmt.Errorf("%v not provided in addtionalFeatures", ConnectorsCRUD) + } + + connectorList, err := d.s.ListConnectors() + if err != nil { + d.logger.Error("api: failed to list connectors", "err", err) + return nil, fmt.Errorf("list connectors: %v", err) + } + + connectors := make([]*api.Connector, 0, len(connectorList)) + for _, connector := range connectorList { + c := api.Connector{ + Id: connector.ID, + Name: connector.Name, + Type: connector.Type, + Config: connector.Config, + } + connectors = append(connectors, &c) + } + + return &api.ListConnectorResp{ + Connectors: connectors, + }, nil +} diff --git a/server/api_test.go b/server/api_test.go index e4150f1f96..88601ec917 100644 --- a/server/api_test.go +++ b/server/api_test.go @@ -5,6 +5,7 @@ import ( "io" "log/slog" "net" + "strings" "testing" "time" @@ -29,14 +30,14 @@ type apiClient struct { } // newAPI constructs a gRCP client connected to a backing server. -func newAPI(s storage.Storage, logger *slog.Logger, t *testing.T) *apiClient { +func newAPI(s storage.Storage, logger *slog.Logger, t *testing.T, addtionalFeatures []AdditionalFeature) *apiClient { l, err := net.Listen("tcp", "127.0.0.1:0") if err != nil { t.Fatal(err) } serv := grpc.NewServer() - api.RegisterDexServer(serv, NewAPI(s, logger, "test")) + api.RegisterDexServer(serv, NewAPI(s, logger, "test", addtionalFeatures)) go serv.Serve(l) // NewClient will retry automatically if the serv.Serve() goroutine @@ -61,7 +62,7 @@ func TestPassword(t *testing.T) { logger := slog.New(slog.NewTextHandler(io.Discard, &slog.HandlerOptions{})) s := memory.New(logger) - client := newAPI(s, logger, t) + client := newAPI(s, logger, t, []AdditionalFeature{}) defer client.Close() ctx := context.Background() @@ -170,7 +171,7 @@ func TestCheckCost(t *testing.T) { logger := slog.New(slog.NewTextHandler(io.Discard, &slog.HandlerOptions{})) s := memory.New(logger) - client := newAPI(s, logger, t) + client := newAPI(s, logger, t, []AdditionalFeature{}) defer client.Close() tests := []struct { @@ -223,7 +224,7 @@ func TestRefreshToken(t *testing.T) { logger := slog.New(slog.NewTextHandler(io.Discard, &slog.HandlerOptions{})) s := memory.New(logger) - client := newAPI(s, logger, t) + client := newAPI(s, logger, t, []AdditionalFeature{}) defer client.Close() ctx := context.Background() @@ -332,7 +333,7 @@ func TestUpdateClient(t *testing.T) { logger := slog.New(slog.NewTextHandler(io.Discard, &slog.HandlerOptions{})) s := memory.New(logger) - client := newAPI(s, logger, t) + client := newAPI(s, logger, t, []AdditionalFeature{}) defer client.Close() ctx := context.Background() @@ -490,3 +491,233 @@ func find(item string, items []string) bool { } return false } + +func TestCreateConnector(t *testing.T) { + logger := slog.New(slog.NewTextHandler(io.Discard, &slog.HandlerOptions{})) + + s := memory.New(logger) + client := newAPI(s, logger, t, []AdditionalFeature{ConnectorsCRUD}) + defer client.Close() + + ctx := context.Background() + connectorID := "connector123" + connectorName := "TestConnector" + connectorType := "TestType" + connectorConfig := []byte(`{"key": "value"}`) + + createReq := api.CreateConnectorReq{ + Connector: &api.Connector{ + Id: connectorID, + Name: connectorName, + Type: connectorType, + Config: connectorConfig, + }, + } + + // Test valid connector creation + if resp, err := client.CreateConnector(ctx, &createReq); err != nil || resp.AlreadyExists { + if err != nil { + t.Fatalf("Unable to create connector: %v", err) + } else if resp.AlreadyExists { + t.Fatalf("Unable to create connector since %s already exists", connectorID) + } + t.Fatalf("Unable to create connector: %v", err) + } + + // Test creating the same connector again (expecting failure) + if resp, _ := client.CreateConnector(ctx, &createReq); !resp.AlreadyExists { + t.Fatalf("Created connector %s twice", connectorID) + } + + createReq.Connector.Config = []byte("invalid_json") + + // Test invalid JSON config + if _, err := client.CreateConnector(ctx, &createReq); err == nil { + t.Fatal("Expected an error for invalid JSON config, but none occurred") + } else if !strings.Contains(err.Error(), "invalid config supplied") { + t.Fatalf("Unexpected error: %v", err) + } +} + +func TestUpdateConnector(t *testing.T) { + logger := slog.New(slog.NewTextHandler(io.Discard, &slog.HandlerOptions{})) + + s := memory.New(logger) + client := newAPI(s, logger, t, []AdditionalFeature{ConnectorsCRUD}) + defer client.Close() + + ctx := context.Background() + connectorID := "connector123" + newConnectorName := "UpdatedConnector" + newConnectorType := "UpdatedType" + newConnectorConfig := []byte(`{"updated_key": "updated_value"}`) + + // Create a connector for testing + createReq := api.CreateConnectorReq{ + Connector: &api.Connector{ + Id: connectorID, + Name: "TestConnector", + Type: "TestType", + Config: []byte(`{"key": "value"}`), + }, + } + client.CreateConnector(ctx, &createReq) + + updateReq := api.UpdateConnectorReq{ + Id: connectorID, + NewName: newConnectorName, + NewType: newConnectorType, + NewConfig: newConnectorConfig, + } + + // Test valid connector update + if _, err := client.UpdateConnector(ctx, &updateReq); err != nil { + t.Fatalf("Unable to update connector: %v", err) + } + + resp, err := client.ListConnectors(ctx, &api.ListConnectorReq{}) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + + for _, connector := range resp.Connectors { + if connector.Id == connectorID { + if connector.Name != newConnectorName { + t.Fatal("connector name should have been updated") + } + if string(connector.Config) != string(newConnectorConfig) { + t.Fatal("connector config should have been updated") + } + if connector.Type != newConnectorType { + t.Fatal("connector type should have been updated") + } + } + } + + updateReq.NewConfig = []byte("invalid_json") + + // Test invalid JSON config in update request + if _, err := client.UpdateConnector(ctx, &updateReq); err == nil { + t.Fatal("Expected an error for invalid JSON config in update, but none occurred") + } else if !strings.Contains(err.Error(), "invalid config supplied") { + t.Fatalf("Unexpected error: %v", err) + } +} + +func TestDeleteConnector(t *testing.T) { + logger := slog.New(slog.NewTextHandler(io.Discard, &slog.HandlerOptions{})) + + s := memory.New(logger) + client := newAPI(s, logger, t, []AdditionalFeature{ConnectorsCRUD}) + defer client.Close() + + ctx := context.Background() + connectorID := "connector123" + + // Create a connector for testing + createReq := api.CreateConnectorReq{ + Connector: &api.Connector{ + Id: connectorID, + Name: "TestConnector", + Type: "TestType", + Config: []byte(`{"key": "value"}`), + }, + } + client.CreateConnector(ctx, &createReq) + + deleteReq := api.DeleteConnectorReq{ + Id: connectorID, + } + + // Test valid connector deletion + if _, err := client.DeleteConnector(ctx, &deleteReq); err != nil { + t.Fatalf("Unable to delete connector: %v", err) + } + + // Test non existent connector deletion + resp, err := client.DeleteConnector(ctx, &deleteReq) + if err != nil { + t.Fatalf("Unable to delete connector: %v", err) + } + + if !resp.NotFound { + t.Fatal("Should return not found") + } +} + +func TestListConnectors(t *testing.T) { + logger := slog.New(slog.NewTextHandler(io.Discard, &slog.HandlerOptions{})) + + s := memory.New(logger) + client := newAPI(s, logger, t, []AdditionalFeature{ConnectorsCRUD}) + defer client.Close() + + ctx := context.Background() + + // Create connectors for testing + createReq1 := api.CreateConnectorReq{ + Connector: &api.Connector{ + Id: "connector1", + Name: "Connector1", + Type: "Type1", + Config: []byte(`{"key": "value1"}`), + }, + } + client.CreateConnector(ctx, &createReq1) + + createReq2 := api.CreateConnectorReq{ + Connector: &api.Connector{ + Id: "connector2", + Name: "Connector2", + Type: "Type2", + Config: []byte(`{"key": "value2"}`), + }, + } + client.CreateConnector(ctx, &createReq2) + + listReq := api.ListConnectorReq{} + + // Test listing connectors + if resp, err := client.ListConnectors(ctx, &listReq); err != nil { + t.Fatalf("Unable to list connectors: %v", err) + } else if len(resp.Connectors) != 2 { // Check the number of connectors in the response + t.Fatalf("Expected 2 connectors, found %d", len(resp.Connectors)) + } +} + +func TestMissingAdditionalFeature(t *testing.T) { + logger := slog.New(slog.NewTextHandler(io.Discard, &slog.HandlerOptions{})) + + s := memory.New(logger) + client := newAPI(s, logger, t, []AdditionalFeature{}) + defer client.Close() + + ctx := context.Background() + + // Create connectors for testing + createReq1 := api.CreateConnectorReq{ + Connector: &api.Connector{ + Id: "connector1", + Name: "Connector1", + Type: "Type1", + Config: []byte(`{"key": "value1"}`), + }, + } + client.CreateConnector(ctx, &createReq1) + + createReq2 := api.CreateConnectorReq{ + Connector: &api.Connector{ + Id: "connector2", + Name: "Connector2", + Type: "Type2", + Config: []byte(`{"key": "value2"}`), + }, + } + client.CreateConnector(ctx, &createReq2) + + listReq := api.ListConnectorReq{} + + if _, err := client.ListConnectors(ctx, &listReq); err == nil { + t.Fatal("ListConnectors should have returned an error") + } +} diff --git a/server/server.go b/server/server.go index 5c1a97b896..68294885b9 100644 --- a/server/server.go +++ b/server/server.go @@ -47,6 +47,16 @@ import ( "github.com/dexidp/dex/web" ) +// AdditionalFeature allows the extension of Dex server functionalities +type AdditionalFeature string + +// ConnectorsCRUD is an additional feature that allows CRUD operations on connectors +var ConnectorsCRUD AdditionalFeature = "ConnectorsCRUD" + +var ValidAdditionalFeatures []AdditionalFeature = []AdditionalFeature{ + ConnectorsCRUD, +} + // LocalConnector is the local passwordDB connector which is an internal // connector maintained by the server. const LocalConnector = "local"