From 5306d6a2c65cfce3eeefdfc051f4538691b9c075 Mon Sep 17 00:00:00 2001 From: Abin Simon Date: Wed, 6 Apr 2022 13:39:36 +0530 Subject: [PATCH 1/3] Send recovery url back after user creation --- .../rpc/role/rolepermission.swagger.json | 7 + .../proto/rpc/scheduler/cluster.swagger.json | 7 + .../proto/rpc/sentry/bootstrap.swagger.json | 18 +++ .../proto/rpc/sentry/kubeconfig.swagger.json | 53 +++++++ .../rpc/sentry/kubectl_cluster.swagger.json | 11 ++ gen/openapi/proto/rpc/user/group.swagger.json | 7 + gen/openapi/proto/rpc/user/user.swagger.json | 34 +++++ pkg/service/user.go | 5 +- proto/rpc/sentry/bootstrap.pb.gw.go | 38 ++--- proto/types/commonpb/v3/common.pb.go | 102 ++++++++------ proto/types/commonpb/v3/common.proto | 3 + proto/types/userpb/v3/user.pb.go | 131 ++++++++++-------- proto/types/userpb/v3/user.proto | 6 + scripts/initialize/main.go | 4 +- 14 files changed, 301 insertions(+), 125 deletions(-) diff --git a/gen/openapi/proto/rpc/role/rolepermission.swagger.json b/gen/openapi/proto/rpc/role/rolepermission.swagger.json index 29dc56d..845c03f 100644 --- a/gen/openapi/proto/rpc/role/rolepermission.swagger.json +++ b/gen/openapi/proto/rpc/role/rolepermission.swagger.json @@ -228,6 +228,13 @@ "in": "query", "required": false, "type": "string" + }, + { + "name": "type", + "description": "generic way to specify a type of resource, mainly for use in users endpoint.", + "in": "query", + "required": false, + "type": "string" } ], "tags": [ diff --git a/gen/openapi/proto/rpc/scheduler/cluster.swagger.json b/gen/openapi/proto/rpc/scheduler/cluster.swagger.json index 42adf0c..8b36af7 100644 --- a/gen/openapi/proto/rpc/scheduler/cluster.swagger.json +++ b/gen/openapi/proto/rpc/scheduler/cluster.swagger.json @@ -1653,6 +1653,13 @@ "in": "query", "required": false, "type": "string" + }, + { + "name": "type", + "description": "generic way to specify a type of resource, mainly for use in users endpoint.", + "in": "query", + "required": false, + "type": "string" } ], "tags": [ diff --git a/gen/openapi/proto/rpc/sentry/bootstrap.swagger.json b/gen/openapi/proto/rpc/sentry/bootstrap.swagger.json index 3744c8f..ea61ad2 100644 --- a/gen/openapi/proto/rpc/sentry/bootstrap.swagger.json +++ b/gen/openapi/proto/rpc/sentry/bootstrap.swagger.json @@ -409,6 +409,13 @@ "in": "query", "required": false, "type": "string" + }, + { + "name": "type", + "description": "generic way to specify a type of resource, mainly for use in users endpoint.", + "in": "query", + "required": false, + "type": "string" } ], "tags": [ @@ -1457,6 +1464,13 @@ "in": "query", "required": false, "type": "string" + }, + { + "name": "opts.type", + "description": "generic way to specify a type of resource, mainly for use in users endpoint.", + "in": "query", + "required": false, + "type": "string" } ], "tags": [ @@ -2083,6 +2097,10 @@ }, "account": { "type": "string" + }, + "type": { + "type": "string", + "title": "generic way to specify a type of resource, mainly for use in users endpoint" } }, "title": "QueryOptions is the options for performing queries on resources" diff --git a/gen/openapi/proto/rpc/sentry/kubeconfig.swagger.json b/gen/openapi/proto/rpc/sentry/kubeconfig.swagger.json index 503263f..a70c515 100644 --- a/gen/openapi/proto/rpc/sentry/kubeconfig.swagger.json +++ b/gen/openapi/proto/rpc/sentry/kubeconfig.swagger.json @@ -229,6 +229,13 @@ "required": false, "type": "string" }, + { + "name": "opts.type", + "description": "generic way to specify a type of resource, mainly for use in users endpoint.", + "in": "query", + "required": false, + "type": "string" + }, { "name": "namespace", "in": "query", @@ -452,6 +459,13 @@ "required": false, "type": "string" }, + { + "name": "opts.type", + "description": "generic way to specify a type of resource, mainly for use in users endpoint.", + "in": "query", + "required": false, + "type": "string" + }, { "name": "namespace", "in": "query", @@ -718,6 +732,13 @@ "required": false, "type": "string" }, + { + "name": "opts.type", + "description": "generic way to specify a type of resource, mainly for use in users endpoint.", + "in": "query", + "required": false, + "type": "string" + }, { "name": "namespace", "in": "query", @@ -935,6 +956,13 @@ "in": "query", "required": false, "type": "string" + }, + { + "name": "opts.type", + "description": "generic way to specify a type of resource, mainly for use in users endpoint.", + "in": "query", + "required": false, + "type": "string" } ], "tags": [ @@ -1196,6 +1224,13 @@ "in": "query", "required": false, "type": "string" + }, + { + "name": "opts.type", + "description": "generic way to specify a type of resource, mainly for use in users endpoint.", + "in": "query", + "required": false, + "type": "string" } ], "tags": [ @@ -1458,6 +1493,13 @@ "required": false, "type": "string" }, + { + "name": "opts.type", + "description": "generic way to specify a type of resource, mainly for use in users endpoint.", + "in": "query", + "required": false, + "type": "string" + }, { "name": "namespace", "in": "query", @@ -1726,6 +1768,13 @@ "in": "query", "required": false, "type": "string" + }, + { + "name": "opts.type", + "description": "generic way to specify a type of resource, mainly for use in users endpoint.", + "in": "query", + "required": false, + "type": "string" } ], "tags": [ @@ -2001,6 +2050,10 @@ }, "account": { "type": "string" + }, + "type": { + "type": "string", + "title": "generic way to specify a type of resource, mainly for use in users endpoint" } }, "title": "QueryOptions is the options for performing queries on resources" diff --git a/gen/openapi/proto/rpc/sentry/kubectl_cluster.swagger.json b/gen/openapi/proto/rpc/sentry/kubectl_cluster.swagger.json index 10bee2b..ff36b80 100644 --- a/gen/openapi/proto/rpc/sentry/kubectl_cluster.swagger.json +++ b/gen/openapi/proto/rpc/sentry/kubectl_cluster.swagger.json @@ -229,6 +229,13 @@ "in": "query", "required": false, "type": "string" + }, + { + "name": "opts.type", + "description": "generic way to specify a type of resource, mainly for use in users endpoint.", + "in": "query", + "required": false, + "type": "string" } ], "tags": [ @@ -452,6 +459,10 @@ }, "account": { "type": "string" + }, + "type": { + "type": "string", + "title": "generic way to specify a type of resource, mainly for use in users endpoint" } }, "title": "QueryOptions is the options for performing queries on resources" diff --git a/gen/openapi/proto/rpc/user/group.swagger.json b/gen/openapi/proto/rpc/user/group.swagger.json index d8e2fc6..3ff0639 100644 --- a/gen/openapi/proto/rpc/user/group.swagger.json +++ b/gen/openapi/proto/rpc/user/group.swagger.json @@ -685,6 +685,13 @@ "in": "query", "required": false, "type": "string" + }, + { + "name": "type", + "description": "generic way to specify a type of resource, mainly for use in users endpoint.", + "in": "query", + "required": false, + "type": "string" } ], "tags": [ diff --git a/gen/openapi/proto/rpc/user/user.swagger.json b/gen/openapi/proto/rpc/user/user.swagger.json index 4212cd6..887c61e 100644 --- a/gen/openapi/proto/rpc/user/user.swagger.json +++ b/gen/openapi/proto/rpc/user/user.swagger.json @@ -216,6 +216,13 @@ "required": false, "type": "boolean" }, + { + "name": "spec.recoveryUrl", + "description": "Recovery Url. Initial signup URL returned after user creation", + "in": "query", + "required": false, + "type": "string" + }, { "name": "status.conditionType", "description": "Condition Type. type of the status condition", @@ -419,6 +426,13 @@ "required": false, "type": "boolean" }, + { + "name": "spec.recoveryUrl", + "description": "Recovery Url. Initial signup URL returned after user creation", + "in": "query", + "required": false, + "type": "string" + }, { "name": "status.conditionType", "description": "Condition Type. type of the status condition", @@ -762,6 +776,13 @@ "required": false, "type": "boolean" }, + { + "name": "spec.recoveryUrl", + "description": "Recovery Url. Initial signup URL returned after user creation", + "in": "query", + "required": false, + "type": "string" + }, { "name": "status.conditionType", "description": "Condition Type. type of the status condition", @@ -1008,6 +1029,13 @@ "in": "query", "required": false, "type": "string" + }, + { + "name": "type", + "description": "generic way to specify a type of resource, mainly for use in users endpoint.", + "in": "query", + "required": false, + "type": "string" } ], "tags": [ @@ -1562,6 +1590,12 @@ "description": "Flag to show if phone number of the user was verified", "title": "PhoneVerified", "readOnly": true + }, + "recoveryUrl": { + "type": "string", + "description": "Initial signup URL returned after user creation", + "title": "Recovery Url", + "readOnly": true } }, "description": "User specification", diff --git a/pkg/service/user.go b/pkg/service/user.go index 8db75a9..c72dd46 100644 --- a/pkg/service/user.go +++ b/pkg/service/user.go @@ -273,7 +273,7 @@ func (s *userService) createGroupAccountRelations(ctx context.Context, db bun.ID } // TODO: revert our db inserts if this fails - // Just FYI, the succcess can be false if we delete the db directly but casbin has it available internally + // Just FYI, the success can be false if we delete the db directly but casbin has it available internally _, err = s.azc.CreateUserGroups(ctx, &authzv1.UserGroups{UserGroups: ugs}) if err != nil { return &userv3.User{}, fmt.Errorf("unable to create mapping in authz; %v", err) @@ -355,10 +355,11 @@ func (s *userService) Create(ctx context.Context, user *userv3.User) (*userv3.Us } rl, err := s.ap.GetRecoveryLink(ctx, id) - fmt.Println("Recovery link:", rl) // TODO: email the recovery link to the user if err != nil { + _log.Warn("unable to generate recovery url", err) return &userv3.User{}, err } + user.Spec.RecoveryUrl = &rl return user, nil } diff --git a/proto/rpc/sentry/bootstrap.pb.gw.go b/proto/rpc/sentry/bootstrap.pb.gw.go index 3a4efe1..fda7e7c 100644 --- a/proto/rpc/sentry/bootstrap.pb.gw.go +++ b/proto/rpc/sentry/bootstrap.pb.gw.go @@ -14,7 +14,7 @@ import ( "net/http" "github.com/RafayLabs/rcloud-base/proto/types/commonpb/v3" - sentry_0 "github.com/RafayLabs/rcloud-base/proto/types/sentry" + "github.com/RafayLabs/rcloud-base/proto/types/sentry" "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" "github.com/grpc-ecosystem/grpc-gateway/v2/utilities" "google.golang.org/grpc" @@ -34,7 +34,7 @@ var _ = utilities.NewDoubleArray var _ = metadata.Join func request_Bootstrap_PatchBootstrapInfra_0(ctx context.Context, marshaler runtime.Marshaler, client BootstrapClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq sentry_0.BootstrapInfra + var protoReq sentry.BootstrapInfra var metadata runtime.ServerMetadata newReader, berr := utilities.IOReaderFactory(req.Body) @@ -68,7 +68,7 @@ func request_Bootstrap_PatchBootstrapInfra_0(ctx context.Context, marshaler runt } func local_request_Bootstrap_PatchBootstrapInfra_0(ctx context.Context, marshaler runtime.Marshaler, server BootstrapServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq sentry_0.BootstrapInfra + var protoReq sentry.BootstrapInfra var metadata runtime.ServerMetadata newReader, berr := utilities.IOReaderFactory(req.Body) @@ -106,7 +106,7 @@ var ( ) func request_Bootstrap_GetBootstrapInfra_0(ctx context.Context, marshaler runtime.Marshaler, client BootstrapClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq sentry_0.BootstrapInfra + var protoReq sentry.BootstrapInfra var metadata runtime.ServerMetadata var ( @@ -139,7 +139,7 @@ func request_Bootstrap_GetBootstrapInfra_0(ctx context.Context, marshaler runtim } func local_request_Bootstrap_GetBootstrapInfra_0(ctx context.Context, marshaler runtime.Marshaler, server BootstrapServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq sentry_0.BootstrapInfra + var protoReq sentry.BootstrapInfra var metadata runtime.ServerMetadata var ( @@ -172,7 +172,7 @@ func local_request_Bootstrap_GetBootstrapInfra_0(ctx context.Context, marshaler } func request_Bootstrap_PatchBootstrapAgentTemplate_0(ctx context.Context, marshaler runtime.Marshaler, client BootstrapClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq sentry_0.BootstrapAgentTemplate + var protoReq sentry.BootstrapAgentTemplate var metadata runtime.ServerMetadata newReader, berr := utilities.IOReaderFactory(req.Body) @@ -206,7 +206,7 @@ func request_Bootstrap_PatchBootstrapAgentTemplate_0(ctx context.Context, marsha } func local_request_Bootstrap_PatchBootstrapAgentTemplate_0(ctx context.Context, marshaler runtime.Marshaler, server BootstrapServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq sentry_0.BootstrapAgentTemplate + var protoReq sentry.BootstrapAgentTemplate var metadata runtime.ServerMetadata newReader, berr := utilities.IOReaderFactory(req.Body) @@ -244,7 +244,7 @@ var ( ) func request_Bootstrap_GetBootstrapAgentTemplate_0(ctx context.Context, marshaler runtime.Marshaler, client BootstrapClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq sentry_0.BootstrapAgentTemplate + var protoReq sentry.BootstrapAgentTemplate var metadata runtime.ServerMetadata var ( @@ -277,7 +277,7 @@ func request_Bootstrap_GetBootstrapAgentTemplate_0(ctx context.Context, marshale } func local_request_Bootstrap_GetBootstrapAgentTemplate_0(ctx context.Context, marshaler runtime.Marshaler, server BootstrapServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq sentry_0.BootstrapAgentTemplate + var protoReq sentry.BootstrapAgentTemplate var metadata runtime.ServerMetadata var ( @@ -418,7 +418,7 @@ var ( ) func request_Bootstrap_GetBootstrapAgentConfig_0(ctx context.Context, marshaler runtime.Marshaler, client BootstrapClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq sentry_0.BootstrapAgent + var protoReq sentry.BootstrapAgent var metadata runtime.ServerMetadata var ( @@ -461,7 +461,7 @@ func request_Bootstrap_GetBootstrapAgentConfig_0(ctx context.Context, marshaler } func local_request_Bootstrap_GetBootstrapAgentConfig_0(ctx context.Context, marshaler runtime.Marshaler, server BootstrapServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq sentry_0.BootstrapAgent + var protoReq sentry.BootstrapAgent var metadata runtime.ServerMetadata var ( @@ -504,7 +504,7 @@ func local_request_Bootstrap_GetBootstrapAgentConfig_0(ctx context.Context, mars } func request_Bootstrap_CreateBootstrapAgent_0(ctx context.Context, marshaler runtime.Marshaler, client BootstrapClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq sentry_0.BootstrapAgent + var protoReq sentry.BootstrapAgent var metadata runtime.ServerMetadata newReader, berr := utilities.IOReaderFactory(req.Body) @@ -538,7 +538,7 @@ func request_Bootstrap_CreateBootstrapAgent_0(ctx context.Context, marshaler run } func local_request_Bootstrap_CreateBootstrapAgent_0(ctx context.Context, marshaler runtime.Marshaler, server BootstrapServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq sentry_0.BootstrapAgent + var protoReq sentry.BootstrapAgent var metadata runtime.ServerMetadata newReader, berr := utilities.IOReaderFactory(req.Body) @@ -576,7 +576,7 @@ var ( ) func request_Bootstrap_GetBootstrapAgent_0(ctx context.Context, marshaler runtime.Marshaler, client BootstrapClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq sentry_0.BootstrapAgent + var protoReq sentry.BootstrapAgent var metadata runtime.ServerMetadata var ( @@ -619,7 +619,7 @@ func request_Bootstrap_GetBootstrapAgent_0(ctx context.Context, marshaler runtim } func local_request_Bootstrap_GetBootstrapAgent_0(ctx context.Context, marshaler runtime.Marshaler, server BootstrapServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq sentry_0.BootstrapAgent + var protoReq sentry.BootstrapAgent var metadata runtime.ServerMetadata var ( @@ -736,7 +736,7 @@ var ( ) func request_Bootstrap_DeleteBootstrapAgent_0(ctx context.Context, marshaler runtime.Marshaler, client BootstrapClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq sentry_0.BootstrapAgent + var protoReq sentry.BootstrapAgent var metadata runtime.ServerMetadata var ( @@ -779,7 +779,7 @@ func request_Bootstrap_DeleteBootstrapAgent_0(ctx context.Context, marshaler run } func local_request_Bootstrap_DeleteBootstrapAgent_0(ctx context.Context, marshaler runtime.Marshaler, server BootstrapServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq sentry_0.BootstrapAgent + var protoReq sentry.BootstrapAgent var metadata runtime.ServerMetadata var ( @@ -822,7 +822,7 @@ func local_request_Bootstrap_DeleteBootstrapAgent_0(ctx context.Context, marshal } func request_Bootstrap_UpdateBootstrapAgent_0(ctx context.Context, marshaler runtime.Marshaler, client BootstrapClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq sentry_0.BootstrapAgent + var protoReq sentry.BootstrapAgent var metadata runtime.ServerMetadata newReader, berr := utilities.IOReaderFactory(req.Body) @@ -866,7 +866,7 @@ func request_Bootstrap_UpdateBootstrapAgent_0(ctx context.Context, marshaler run } func local_request_Bootstrap_UpdateBootstrapAgent_0(ctx context.Context, marshaler runtime.Marshaler, server BootstrapServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq sentry_0.BootstrapAgent + var protoReq sentry.BootstrapAgent var metadata runtime.ServerMetadata newReader, berr := utilities.IOReaderFactory(req.Body) diff --git a/proto/types/commonpb/v3/common.pb.go b/proto/types/commonpb/v3/common.pb.go index 3f43e22..2bda9d7 100644 --- a/proto/types/commonpb/v3/common.pb.go +++ b/proto/types/commonpb/v3/common.pb.go @@ -792,6 +792,8 @@ type QueryOptions struct { ClusterID string `protobuf:"bytes,27,opt,name=clusterID,proto3" json:"clusterID,omitempty"` ID string `protobuf:"bytes,28,opt,name=ID,proto3" json:"ID,omitempty"` Account string `protobuf:"bytes,29,opt,name=account,proto3" json:"account,omitempty"` + // generic way to specify a type of resource, mainly for use in users endpoint + Type string `protobuf:"bytes,30,opt,name=type,proto3" json:"type,omitempty"` } func (x *QueryOptions) Reset() { @@ -1029,6 +1031,13 @@ func (x *QueryOptions) GetAccount() string { return "" } +func (x *QueryOptions) GetType() string { + if x != nil { + return x.Type + } + return "" +} + // HttpBody represents arbitrary HTTP Body. It should only be used for // payload formats that can't be represented as JSON type HttpBody struct { @@ -1303,7 +1312,7 @@ var file_proto_types_commonpb_v3_common_proto_rawDesc = []byte{ 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x3a, 0x25, 0x92, 0x41, 0x22, 0x0a, 0x20, 0x2a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x32, 0x14, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x20, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x40, 0x01, 0x22, - 0x96, 0x08, 0x0a, 0x0c, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0xaa, 0x08, 0x0a, 0x0c, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x0c, 0x0a, 0x01, 0x71, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x01, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x03, @@ -1360,52 +1369,53 @@ var file_proto_types_commonpb_v3_common_proto_rawDesc = []byte{ 0x49, 0x44, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x1d, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x1a, 0x39, 0x0a, - 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 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, 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, 0x3e, 0x0a, 0x10, 0x41, 0x6e, 0x6e, 0x6f, - 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 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, 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, 0x41, 0x0a, 0x08, 0x48, 0x74, 0x74, 0x70, - 0x42, 0x6f, 0x64, 0x79, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x5f, - 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, - 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x2a, 0x58, 0x0a, 0x0f, 0x43, - 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x10, - 0x0a, 0x0c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x4e, 0x6f, 0x74, 0x53, 0x65, 0x74, 0x10, 0x00, - 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, - 0x74, 0x65, 0x64, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x4f, - 0x4b, 0x10, 0x02, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x46, 0x61, 0x69, - 0x6c, 0x65, 0x64, 0x10, 0x03, 0x2a, 0xa7, 0x01, 0x0a, 0x14, 0x52, 0x61, 0x66, 0x61, 0x79, 0x43, - 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0a, - 0x0a, 0x06, 0x4e, 0x6f, 0x74, 0x53, 0x65, 0x74, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x50, 0x65, - 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x49, 0x6e, 0x50, 0x72, 0x6f, - 0x67, 0x72, 0x65, 0x73, 0x73, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x75, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x10, 0x03, 0x12, 0x0a, 0x0a, 0x06, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x10, 0x04, - 0x12, 0x09, 0x0a, 0x05, 0x52, 0x65, 0x74, 0x72, 0x79, 0x10, 0x05, 0x12, 0x0b, 0x0a, 0x07, 0x53, - 0x6b, 0x69, 0x70, 0x70, 0x65, 0x64, 0x10, 0x06, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x74, 0x6f, 0x70, - 0x70, 0x65, 0x64, 0x10, 0x07, 0x12, 0x0b, 0x0a, 0x07, 0x45, 0x78, 0x70, 0x69, 0x72, 0x65, 0x64, - 0x10, 0x08, 0x12, 0x0c, 0x0a, 0x08, 0x53, 0x74, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x10, 0x09, - 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x10, 0x0a, 0x42, - 0xf8, 0x01, 0x0a, 0x1d, 0x63, 0x6f, 0x6d, 0x2e, 0x72, 0x61, 0x66, 0x61, 0x79, 0x2e, 0x64, 0x65, - 0x76, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, - 0x33, 0x42, 0x0b, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, - 0x5a, 0x41, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x52, 0x61, 0x66, - 0x61, 0x79, 0x4c, 0x61, 0x62, 0x73, 0x2f, 0x72, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2d, 0x62, 0x61, - 0x73, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x63, - 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2f, 0x76, 0x33, 0x3b, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, - 0x6e, 0x76, 0x33, 0xa2, 0x02, 0x04, 0x52, 0x44, 0x54, 0x43, 0xaa, 0x02, 0x19, 0x52, 0x61, 0x66, - 0x61, 0x79, 0x2e, 0x44, 0x65, 0x76, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x43, 0x6f, 0x6d, - 0x6d, 0x6f, 0x6e, 0x2e, 0x56, 0x33, 0xca, 0x02, 0x19, 0x52, 0x61, 0x66, 0x61, 0x79, 0x5c, 0x44, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x12, 0x0a, + 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, + 0x65, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 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, 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, 0x3e, 0x0a, 0x10, + 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 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, 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, 0x41, 0x0a, 0x08, + 0x48, 0x74, 0x74, 0x70, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, + 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, + 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, + 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x2a, + 0x58, 0x0a, 0x0f, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x4e, 0x6f, 0x74, 0x53, + 0x65, 0x74, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x53, 0x75, + 0x62, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x4f, 0x4b, 0x10, 0x02, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x10, 0x03, 0x2a, 0xa7, 0x01, 0x0a, 0x14, 0x52, 0x61, + 0x66, 0x61, 0x79, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x12, 0x0a, 0x0a, 0x06, 0x4e, 0x6f, 0x74, 0x53, 0x65, 0x74, 0x10, 0x00, 0x12, 0x0b, + 0x0a, 0x07, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x49, + 0x6e, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x53, + 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x10, 0x03, 0x12, 0x0a, 0x0a, 0x06, 0x46, 0x61, 0x69, 0x6c, + 0x65, 0x64, 0x10, 0x04, 0x12, 0x09, 0x0a, 0x05, 0x52, 0x65, 0x74, 0x72, 0x79, 0x10, 0x05, 0x12, + 0x0b, 0x0a, 0x07, 0x53, 0x6b, 0x69, 0x70, 0x70, 0x65, 0x64, 0x10, 0x06, 0x12, 0x0b, 0x0a, 0x07, + 0x53, 0x74, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x10, 0x07, 0x12, 0x0b, 0x0a, 0x07, 0x45, 0x78, 0x70, + 0x69, 0x72, 0x65, 0x64, 0x10, 0x08, 0x12, 0x0c, 0x0a, 0x08, 0x53, 0x74, 0x6f, 0x70, 0x70, 0x69, + 0x6e, 0x67, 0x10, 0x09, 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x74, 0x65, + 0x64, 0x10, 0x0a, 0x42, 0xf8, 0x01, 0x0a, 0x1d, 0x63, 0x6f, 0x6d, 0x2e, 0x72, 0x61, 0x66, 0x61, + 0x79, 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x2e, 0x76, 0x33, 0x42, 0x0b, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x50, 0x72, 0x6f, + 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x41, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x52, 0x61, 0x66, 0x61, 0x79, 0x4c, 0x61, 0x62, 0x73, 0x2f, 0x72, 0x63, 0x6c, 0x6f, 0x75, + 0x64, 0x2d, 0x62, 0x61, 0x73, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x74, 0x79, 0x70, + 0x65, 0x73, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2f, 0x76, 0x33, 0x3b, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x76, 0x33, 0xa2, 0x02, 0x04, 0x52, 0x44, 0x54, 0x43, 0xaa, 0x02, + 0x19, 0x52, 0x61, 0x66, 0x61, 0x79, 0x2e, 0x44, 0x65, 0x76, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x73, + 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x56, 0x33, 0xca, 0x02, 0x19, 0x52, 0x61, 0x66, + 0x61, 0x79, 0x5c, 0x44, 0x65, 0x76, 0x5c, 0x54, 0x79, 0x70, 0x65, 0x73, 0x5c, 0x43, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x5c, 0x56, 0x33, 0xe2, 0x02, 0x25, 0x52, 0x61, 0x66, 0x61, 0x79, 0x5c, 0x44, 0x65, 0x76, 0x5c, 0x54, 0x79, 0x70, 0x65, 0x73, 0x5c, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5c, - 0x56, 0x33, 0xe2, 0x02, 0x25, 0x52, 0x61, 0x66, 0x61, 0x79, 0x5c, 0x44, 0x65, 0x76, 0x5c, 0x54, - 0x79, 0x70, 0x65, 0x73, 0x5c, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5c, 0x56, 0x33, 0x5c, 0x47, - 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x1d, 0x52, 0x61, 0x66, - 0x61, 0x79, 0x3a, 0x3a, 0x44, 0x65, 0x76, 0x3a, 0x3a, 0x54, 0x79, 0x70, 0x65, 0x73, 0x3a, 0x3a, - 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x3a, 0x3a, 0x56, 0x33, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x56, 0x33, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, + 0x1d, 0x52, 0x61, 0x66, 0x61, 0x79, 0x3a, 0x3a, 0x44, 0x65, 0x76, 0x3a, 0x3a, 0x54, 0x79, 0x70, + 0x65, 0x73, 0x3a, 0x3a, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x3a, 0x3a, 0x56, 0x33, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/proto/types/commonpb/v3/common.proto b/proto/types/commonpb/v3/common.proto index b214dcb..9ad36a3 100644 --- a/proto/types/commonpb/v3/common.proto +++ b/proto/types/commonpb/v3/common.proto @@ -280,6 +280,9 @@ message QueryOptions { string clusterID = 27; string ID = 28; string account = 29; + + // generic way to specify a type of resource, mainly for use in users endpoint + string type = 30; } // RafayConditionStatus is the status of the status condition diff --git a/proto/types/userpb/v3/user.pb.go b/proto/types/userpb/v3/user.pb.go index 41ca155..4d7aa9b 100644 --- a/proto/types/userpb/v3/user.pb.go +++ b/proto/types/userpb/v3/user.pb.go @@ -289,6 +289,7 @@ type UserSpec struct { ProjectNamespaceRoles []*ProjectNamespaceRole `protobuf:"bytes,7,rep,name=projectNamespaceRoles,proto3" json:"projectNamespaceRoles,omitempty"` EmailVerified bool `protobuf:"varint,8,opt,name=emailVerified,proto3" json:"emailVerified,omitempty"` PhoneVerified bool `protobuf:"varint,9,opt,name=phoneVerified,proto3" json:"phoneVerified,omitempty"` + RecoveryUrl *string `protobuf:"bytes,10,opt,name=recoveryUrl,proto3,oneof" json:"recoveryUrl,omitempty"` } func (x *UserSpec) Reset() { @@ -379,6 +380,13 @@ func (x *UserSpec) GetPhoneVerified() bool { return false } +func (x *UserSpec) GetRecoveryUrl() string { + if x != nil && x.RecoveryUrl != nil { + return *x.RecoveryUrl + } + return "" +} + type UserList struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -634,7 +642,7 @@ var file_proto_types_userpb_v3_user_proto_rawDesc = []byte{ 0x74, 0x75, 0x73, 0x3a, 0x37, 0x92, 0x41, 0x34, 0x0a, 0x32, 0x2a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x32, 0x04, 0x55, 0x73, 0x65, 0x72, 0xd2, 0x01, 0x0a, 0x61, 0x70, 0x69, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0xd2, 0x01, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0xd2, 0x01, 0x08, 0x6d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0xd2, 0x01, 0x04, 0x73, 0x70, 0x65, 0x63, 0x22, 0x95, 0x06, 0x0a, + 0x61, 0x64, 0x61, 0x74, 0x61, 0xd2, 0x01, 0x04, 0x73, 0x70, 0x65, 0x63, 0x22, 0x92, 0x07, 0x0a, 0x08, 0x55, 0x73, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x12, 0x44, 0x0a, 0x09, 0x66, 0x69, 0x72, 0x73, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x26, 0x92, 0x41, 0x23, 0x2a, 0x09, 0x46, 0x69, 0x72, 0x73, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x32, 0x16, 0x46, 0x69, @@ -681,62 +689,70 @@ var file_proto_types_userpb_v3_user_proto_rawDesc = []byte{ 0x68, 0x6f, 0x6e, 0x65, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x77, 0x61, 0x73, 0x20, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x40, 0x01, 0x52, 0x0d, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x56, 0x65, 0x72, - 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a, 0x2d, 0x92, 0x41, 0x2a, 0x0a, 0x28, 0x2a, 0x12, 0x55, 0x73, - 0x65, 0x72, 0x20, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x32, 0x12, 0x55, 0x73, 0x65, 0x72, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xbf, 0x03, 0x0a, 0x08, 0x55, 0x73, 0x65, 0x72, 0x4c, 0x69, 0x73, - 0x74, 0x12, 0x71, 0x0a, 0x0a, 0x61, 0x70, 0x69, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x51, 0x92, 0x41, 0x4e, 0x2a, 0x0b, 0x41, 0x50, 0x49, 0x20, - 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x32, 0x25, 0x41, 0x50, 0x49, 0x20, 0x56, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x75, 0x73, 0x65, 0x72, - 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x3a, 0x16, - 0x75, 0x73, 0x65, 0x72, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x6b, 0x38, 0x73, 0x6d, 0x67, 0x6d, 0x74, - 0x2e, 0x69, 0x6f, 0x2f, 0x76, 0x33, 0x40, 0x01, 0x52, 0x0a, 0x61, 0x70, 0x69, 0x56, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x49, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x42, 0x35, 0x92, 0x41, 0x32, 0x2a, 0x04, 0x4b, 0x69, 0x6e, 0x64, 0x32, 0x1e, 0x4b, - 0x69, 0x6e, 0x64, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, - 0x6c, 0x69, 0x73, 0x74, 0x20, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x3a, 0x08, 0x55, - 0x73, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x40, 0x01, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, - 0x78, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x27, 0x2e, 0x72, 0x61, 0x66, 0x61, 0x79, 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x74, 0x79, - 0x70, 0x65, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x69, - 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x42, 0x33, 0x92, 0x41, 0x30, 0x2a, - 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x32, 0x22, 0x4d, 0x65, 0x74, 0x61, 0x64, - 0x61, 0x74, 0x61, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, - 0x6c, 0x69, 0x73, 0x74, 0x20, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x40, 0x01, 0x52, - 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x5d, 0x0a, 0x05, 0x69, 0x74, 0x65, - 0x6d, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x72, 0x61, 0x66, 0x61, 0x79, - 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, - 0x76, 0x33, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x42, 0x28, 0x92, 0x41, 0x25, 0x2a, 0x05, 0x49, 0x74, - 0x65, 0x6d, 0x73, 0x32, 0x1a, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, - 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x40, - 0x01, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x3a, 0x1c, 0x92, 0x41, 0x19, 0x0a, 0x17, 0x2a, - 0x08, 0x55, 0x73, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x32, 0x09, 0x55, 0x73, 0x65, 0x72, 0x20, - 0x6c, 0x69, 0x73, 0x74, 0x40, 0x01, 0x22, 0x88, 0x01, 0x0a, 0x08, 0x55, 0x73, 0x65, 0x72, 0x52, - 0x6f, 0x6c, 0x65, 0x12, 0x23, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x42, 0x0f, 0x92, 0x41, 0x0c, 0x2a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x32, 0x04, 0x55, 0x73, - 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x23, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0f, 0x92, 0x41, 0x0c, 0x2a, 0x04, 0x52, 0x6f, 0x6c, - 0x65, 0x32, 0x04, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x3a, 0x32, 0x92, - 0x41, 0x2f, 0x0a, 0x2d, 0x2a, 0x08, 0x55, 0x73, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x32, 0x21, - 0x55, 0x73, 0x65, 0x72, 0x2c, 0x20, 0x72, 0x6f, 0x6c, 0x65, 0x20, 0x70, 0x61, 0x69, 0x72, 0x69, - 0x6e, 0x67, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x42, 0xe8, 0x01, 0x0a, 0x1b, 0x63, 0x6f, 0x6d, 0x2e, 0x72, 0x61, 0x66, 0x61, 0x79, 0x2e, - 0x64, 0x65, 0x76, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, - 0x33, 0x42, 0x09, 0x55, 0x73, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3d, - 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x52, 0x61, 0x66, 0x61, 0x79, - 0x4c, 0x61, 0x62, 0x73, 0x2f, 0x72, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2d, 0x62, 0x61, 0x73, 0x65, - 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x75, 0x73, 0x65, - 0x72, 0x70, 0x62, 0x2f, 0x76, 0x33, 0x3b, 0x75, 0x73, 0x65, 0x72, 0x76, 0x33, 0xa2, 0x02, 0x04, - 0x52, 0x44, 0x54, 0x55, 0xaa, 0x02, 0x17, 0x52, 0x61, 0x66, 0x61, 0x79, 0x2e, 0x44, 0x65, 0x76, - 0x2e, 0x54, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x2e, 0x56, 0x33, 0xca, 0x02, - 0x17, 0x52, 0x61, 0x66, 0x61, 0x79, 0x5c, 0x44, 0x65, 0x76, 0x5c, 0x54, 0x79, 0x70, 0x65, 0x73, - 0x5c, 0x55, 0x73, 0x65, 0x72, 0x5c, 0x56, 0x33, 0xe2, 0x02, 0x23, 0x52, 0x61, 0x66, 0x61, 0x79, - 0x5c, 0x44, 0x65, 0x76, 0x5c, 0x54, 0x79, 0x70, 0x65, 0x73, 0x5c, 0x55, 0x73, 0x65, 0x72, 0x5c, - 0x56, 0x33, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, - 0x1b, 0x52, 0x61, 0x66, 0x61, 0x79, 0x3a, 0x3a, 0x44, 0x65, 0x76, 0x3a, 0x3a, 0x54, 0x79, 0x70, - 0x65, 0x73, 0x3a, 0x3a, 0x55, 0x73, 0x65, 0x72, 0x3a, 0x3a, 0x56, 0x33, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x69, 0x66, 0x69, 0x65, 0x64, 0x12, 0x6b, 0x0a, 0x0b, 0x72, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, + 0x79, 0x55, 0x72, 0x6c, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x42, 0x44, 0x92, 0x41, 0x41, 0x2a, + 0x0c, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x20, 0x55, 0x72, 0x6c, 0x32, 0x2f, 0x49, + 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x75, 0x70, 0x20, 0x55, 0x52, + 0x4c, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x20, 0x61, 0x66, 0x74, 0x65, 0x72, + 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x40, 0x01, + 0x48, 0x00, 0x52, 0x0b, 0x72, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x55, 0x72, 0x6c, 0x88, + 0x01, 0x01, 0x3a, 0x2d, 0x92, 0x41, 0x2a, 0x0a, 0x28, 0x2a, 0x12, 0x55, 0x73, 0x65, 0x72, 0x20, + 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x32, 0x12, 0x55, + 0x73, 0x65, 0x72, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x72, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x55, 0x72, + 0x6c, 0x22, 0xbf, 0x03, 0x0a, 0x08, 0x55, 0x73, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x71, + 0x0a, 0x0a, 0x61, 0x70, 0x69, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x42, 0x51, 0x92, 0x41, 0x4e, 0x2a, 0x0b, 0x41, 0x50, 0x49, 0x20, 0x56, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x32, 0x25, 0x41, 0x50, 0x49, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x6c, 0x69, + 0x73, 0x74, 0x20, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x3a, 0x16, 0x75, 0x73, 0x65, + 0x72, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x6b, 0x38, 0x73, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x69, 0x6f, + 0x2f, 0x76, 0x33, 0x40, 0x01, 0x52, 0x0a, 0x61, 0x70, 0x69, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x12, 0x49, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x35, 0x92, 0x41, 0x32, 0x2a, 0x04, 0x4b, 0x69, 0x6e, 0x64, 0x32, 0x1e, 0x4b, 0x69, 0x6e, 0x64, + 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x6c, 0x69, 0x73, + 0x74, 0x20, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x3a, 0x08, 0x55, 0x73, 0x65, 0x72, + 0x4c, 0x69, 0x73, 0x74, 0x40, 0x01, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x78, 0x0a, 0x08, + 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, + 0x2e, 0x72, 0x61, 0x66, 0x61, 0x79, 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, + 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x42, 0x33, 0x92, 0x41, 0x30, 0x2a, 0x08, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x32, 0x22, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x6c, 0x69, 0x73, + 0x74, 0x20, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x40, 0x01, 0x52, 0x08, 0x6d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x5d, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, + 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x72, 0x61, 0x66, 0x61, 0x79, 0x2e, 0x64, 0x65, + 0x76, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x33, 0x2e, + 0x55, 0x73, 0x65, 0x72, 0x42, 0x28, 0x92, 0x41, 0x25, 0x2a, 0x05, 0x49, 0x74, 0x65, 0x6d, 0x73, + 0x32, 0x1a, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x75, 0x73, + 0x65, 0x72, 0x20, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x40, 0x01, 0x52, 0x05, + 0x69, 0x74, 0x65, 0x6d, 0x73, 0x3a, 0x1c, 0x92, 0x41, 0x19, 0x0a, 0x17, 0x2a, 0x08, 0x55, 0x73, + 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x32, 0x09, 0x55, 0x73, 0x65, 0x72, 0x20, 0x6c, 0x69, 0x73, + 0x74, 0x40, 0x01, 0x22, 0x88, 0x01, 0x0a, 0x08, 0x55, 0x73, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, + 0x12, 0x23, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0f, + 0x92, 0x41, 0x0c, 0x2a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x32, 0x04, 0x55, 0x73, 0x65, 0x72, 0x52, + 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x23, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x42, 0x0f, 0x92, 0x41, 0x0c, 0x2a, 0x04, 0x52, 0x6f, 0x6c, 0x65, 0x32, 0x04, + 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x3a, 0x32, 0x92, 0x41, 0x2f, 0x0a, + 0x2d, 0x2a, 0x08, 0x55, 0x73, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x32, 0x21, 0x55, 0x73, 0x65, + 0x72, 0x2c, 0x20, 0x72, 0x6f, 0x6c, 0x65, 0x20, 0x70, 0x61, 0x69, 0x72, 0x69, 0x6e, 0x67, 0x20, + 0x66, 0x6f, 0x72, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0xe8, + 0x01, 0x0a, 0x1b, 0x63, 0x6f, 0x6d, 0x2e, 0x72, 0x61, 0x66, 0x61, 0x79, 0x2e, 0x64, 0x65, 0x76, + 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x33, 0x42, 0x09, + 0x55, 0x73, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3d, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x52, 0x61, 0x66, 0x61, 0x79, 0x4c, 0x61, 0x62, + 0x73, 0x2f, 0x72, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2d, 0x62, 0x61, 0x73, 0x65, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x70, 0x62, + 0x2f, 0x76, 0x33, 0x3b, 0x75, 0x73, 0x65, 0x72, 0x76, 0x33, 0xa2, 0x02, 0x04, 0x52, 0x44, 0x54, + 0x55, 0xaa, 0x02, 0x17, 0x52, 0x61, 0x66, 0x61, 0x79, 0x2e, 0x44, 0x65, 0x76, 0x2e, 0x54, 0x79, + 0x70, 0x65, 0x73, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x2e, 0x56, 0x33, 0xca, 0x02, 0x17, 0x52, 0x61, + 0x66, 0x61, 0x79, 0x5c, 0x44, 0x65, 0x76, 0x5c, 0x54, 0x79, 0x70, 0x65, 0x73, 0x5c, 0x55, 0x73, + 0x65, 0x72, 0x5c, 0x56, 0x33, 0xe2, 0x02, 0x23, 0x52, 0x61, 0x66, 0x61, 0x79, 0x5c, 0x44, 0x65, + 0x76, 0x5c, 0x54, 0x79, 0x70, 0x65, 0x73, 0x5c, 0x55, 0x73, 0x65, 0x72, 0x5c, 0x56, 0x33, 0x5c, + 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x1b, 0x52, 0x61, + 0x66, 0x61, 0x79, 0x3a, 0x3a, 0x44, 0x65, 0x76, 0x3a, 0x3a, 0x54, 0x79, 0x70, 0x65, 0x73, 0x3a, + 0x3a, 0x55, 0x73, 0x65, 0x72, 0x3a, 0x3a, 0x56, 0x33, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, } var ( @@ -863,6 +879,7 @@ func file_proto_types_userpb_v3_user_proto_init() { } } } + file_proto_types_userpb_v3_user_proto_msgTypes[3].OneofWrappers = []interface{}{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ diff --git a/proto/types/userpb/v3/user.proto b/proto/types/userpb/v3/user.proto index 0a5da1a..fee2498 100644 --- a/proto/types/userpb/v3/user.proto +++ b/proto/types/userpb/v3/user.proto @@ -184,6 +184,12 @@ message UserSpec { description : "Flag to show if phone number of the user was verified" read_only : true } ]; + optional string recoveryUrl = 10 + [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + title : "Recovery Url", + description : "Initial signup URL returned after user creation" + read_only : true + } ]; } message UserList { diff --git a/scripts/initialize/main.go b/scripts/initialize/main.go index dbc3f17..9b87b1a 100644 --- a/scripts/initialize/main.go +++ b/scripts/initialize/main.go @@ -264,7 +264,7 @@ func main() { } // should we directly interact with kratos and create a user with a password? - _, err = us.Create(context.Background(), &userv3.User{ + orgA, err := us.Create(context.Background(), &userv3.User{ Metadata: &commonv3.Metadata{Name: *oae, Partner: *partner, Organization: *org, Description: "..."}, Spec: &userv3.UserSpec{ FirstName: *oafn, @@ -290,4 +290,6 @@ func main() { Default: true, }, }) + + fmt.Println("Org Admin signup URL: ", orgA.Spec.RecoveryUrl) } From 66c7cc7f10d563a81a6c94a417671d05309cc1e9 Mon Sep 17 00:00:00 2001 From: Abin Simon Date: Wed, 6 Apr 2022 13:58:05 +0530 Subject: [PATCH 2/3] Filter from all users list if we have don't have filters --- internal/dao/user.go | 6 ++++-- pkg/service/user.go | 33 ++++++++++++++++++++++++--------- pkg/service/user_test.go | 10 +++++----- 3 files changed, 33 insertions(+), 16 deletions(-) diff --git a/internal/dao/user.go b/internal/dao/user.go index 4e6ad8e..c0b7833 100644 --- a/internal/dao/user.go +++ b/internal/dao/user.go @@ -71,7 +71,6 @@ type userProjectnamesaceRole struct { Project *string `bun:"project,type:string"` } -// TODO: find a better name for the function func GetQueryFilteredUsers(ctx context.Context, db bun.IDB, partner, org, group, role uuid.UUID, projects []uuid.UUID) ([]uuid.UUID, error) { p := []models.AccountPermission{} q := db.NewSelect().Model(&p).ColumnExpr("DISTINCT account_id") @@ -100,7 +99,10 @@ func GetQueryFilteredUsers(ctx context.Context, db bun.IDB, partner, org, group, // ListFilteredUsers will return the list of users fileterd by query func ListFilteredUsers(ctx context.Context, db bun.IDB, users *[]models.KratosIdentities, fusers []uuid.UUID, query string, orderBy string, order string, limit int, offset int) (*[]models.KratosIdentities, error) { q := db.NewSelect().Model(users) - q.Where("id IN (?)", bun.In(fusers)) + if len(fusers) > 0 { + // filter with precomputed users if we have any + q.Where("id IN (?)", bun.In(fusers)) + } if query != "" { q.Where("traits ->> 'email' ILIKE ?", "%"+query+"%") // XXX: ILIKE is not-standard q.WhereOr("traits ->> 'first_name' ILIKE ?", "%"+query+"%") diff --git a/pkg/service/user.go b/pkg/service/user.go index c72dd46..f584151 100644 --- a/pkg/service/user.go +++ b/pkg/service/user.go @@ -707,21 +707,36 @@ func (s *userService) List(ctx context.Context, opts ...query.Option) (*userv3.U } } - uids, err := dao.GetQueryFilteredUsers(ctx, s.db, partnerId, orgId, groupId, roleId, projectIds) - if err != nil { - return &userv3.UserList{}, err - } + var usrs *[]models.KratosIdentities + var accs []models.KratosIdentities + if len(projectIds) != 0 || groupId != uuid.Nil || roleId != uuid.Nil { + uids, err := dao.GetQueryFilteredUsers(ctx, s.db, partnerId, orgId, groupId, roleId, projectIds) + if err != nil { + return &userv3.UserList{}, err + } - if len(uids) != 0 { - var accs []models.KratosIdentities - // TODO: maybe merge this with the previous one into single sql - usrs, err := dao.ListFilteredUsers(ctx, s.db, &accs, - uids, queryOptions.Q, + if len(uids) != 0 { + // TODO: maybe merge this with the previous one into single sql + usrs, err = dao.ListFilteredUsers(ctx, s.db, &accs, + uids, queryOptions.Q, + queryOptions.OrderBy, queryOptions.Order, + int(queryOptions.Limit), int(queryOptions.Offset)) + if err != nil { + return userList, err + } + } + } else { + // If no filters are available we have to list just using identities table + usrs, err = dao.ListFilteredUsers(ctx, s.db, &accs, + []uuid.UUID{}, queryOptions.Q, queryOptions.OrderBy, queryOptions.Order, int(queryOptions.Limit), int(queryOptions.Offset)) if err != nil { return userList, err } + } + + if usrs != nil { for _, usr := range *usrs { user := &userv3.User{} user, err := s.identitiesModelToUser(ctx, s.db, user, &usr) diff --git a/pkg/service/user_test.go b/pkg/service/user_test.go index 5262c0d..5bc4b4c 100644 --- a/pkg/service/user_test.go +++ b/pkg/service/user_test.go @@ -429,9 +429,7 @@ func TestUserList(t *testing.T) { WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(puuid)) mock.ExpectQuery(`SELECT "organization"."id" FROM "authsrv_organization" AS "organization"`). WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(ouuid)) - mock.ExpectQuery(`SELECT DISTINCT account_id FROM "sentry_account_permission" AS "sap" WHERE .partner_id = '` + puuid + `'. AND .organization_id = '` + ouuid + `'`). - WithArgs().WillReturnRows(sqlmock.NewRows([]string{"account_id"}).AddRow(uuuid1).AddRow(uuuid2)) - mock.ExpectQuery(`SELECT "identities"."id", .*WHERE .id IN .'` + uuuid1 + `', '` + uuuid2 + `'.. LIMIT 10`). + mock.ExpectQuery(`SELECT "identities"."id", .*FROM "identities" LIMIT 10`). WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id", "traits"}). AddRow(uuuid1, []byte(`{"email":"johndoe@provider.com", "first_name": "John", "last_name": "Doe", "organization_id": "`+ouuid+`", "partner_id": "`+puuid+`", "description": "My awesome user"}`)). AddRow(uuuid2, []byte(`{"email":"johndoe@provider.com", "first_name": "John", "last_name": "Doe", "organization_id": "`+ouuid+`", "partner_id": "`+puuid+`", "description": "My awesome user"}`))) @@ -492,7 +490,7 @@ func TestUserList(t *testing.T) { performBasicAuthProviderChecks(t, *ap, 0, 0, 0, 0) } -func TestUserFiletered(t *testing.T) { +func TestUserFiltered(t *testing.T) { db, mock := getDB(t) defer db.Close() @@ -512,6 +510,8 @@ func TestUserFiletered(t *testing.T) { WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(puuid)) mock.ExpectQuery(`SELECT "organization"."id" FROM "authsrv_organization" AS "organization"`). WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(ouuid)) + mock.ExpectQuery(`SELECT "group"."id" FROM "authsrv_group" AS "group" WHERE .name = 'group-name'. AND .trash = FALSE.`). + WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(guuid)) mock.ExpectQuery(`SELECT DISTINCT account_id FROM "sentry_account_permission" AS "sap" WHERE .partner_id = '` + puuid + `'. AND .organization_id = '` + ouuid + `'`). WithArgs().WillReturnRows(sqlmock.NewRows([]string{"account_id"}).AddRow(uuuid1).AddRow(uuuid2)) mock.ExpectQuery(`SELECT "identities"."id", .*WHERE .id IN .'` + uuuid1 + `', '` + uuuid2 + `'.. AND .traits ->> 'email' ILIKE '%filter-query%'. OR .traits ->> 'first_name' ILIKE '%filter-query%'. OR .traits ->> 'last_name' ILIKE '%filter-query%'. ORDER BY "traits ->> 'email' asc" LIMIT 50 OFFSET 20`). @@ -563,7 +563,7 @@ func TestUserFiletered(t *testing.T) { mock.ExpectQuery(`SELECT authsrv_resourcerole.name as role, authsrv_project.name as project, namespace_id as namespace FROM "authsrv_projectaccountnamespacerole" JOIN authsrv_resourcerole ON authsrv_resourcerole.id=authsrv_projectaccountnamespacerole.role_id JOIN authsrv_project ON authsrv_project.id=authsrv_projectaccountnamespacerole.project_id WHERE .authsrv_projectaccountnamespacerole.account_id = '` + uuuid2 + `'`). WithArgs().WillReturnRows(sqlmock.NewRows([]string{"role", "project", "namespace"}).AddRow("role-"+ruuid, "project-"+pruuid, 9)) - qo := &commonv3.QueryOptions{Q: "filter-query", Limit: 50, Offset: 20, OrderBy: "email", Order: "asc", Organization: ouuid, Partner: puuid} + qo := &commonv3.QueryOptions{Q: "filter-query", Limit: 50, Offset: 20, OrderBy: "email", Order: "asc", Organization: ouuid, Partner: puuid, Group: "group-name"} userlist, err := us.List(context.Background(), query.WithOptions(qo)) if err != nil { t.Fatal("could not list users:", err) From df72864d096a7b10d0a4f69eff00a24d9b29916b Mon Sep 17 00:00:00 2001 From: Abin Simon Date: Wed, 6 Apr 2022 14:51:12 +0530 Subject: [PATCH 3/3] Add option to filter by user auth mode Pass in type=password or type=oidc to pick the mode --- internal/dao/user.go | 10 +++- internal/models/kratosidentities.go | 33 +++++++++--- master.rest | 2 +- pkg/service/user.go | 4 +- pkg/service/user_test.go | 84 +++++++++++++++++++++++++++++ 5 files changed, 121 insertions(+), 12 deletions(-) diff --git a/internal/dao/user.go b/internal/dao/user.go index c0b7833..b2861e3 100644 --- a/internal/dao/user.go +++ b/internal/dao/user.go @@ -97,8 +97,16 @@ func GetQueryFilteredUsers(ctx context.Context, db bun.IDB, partner, org, group, } // ListFilteredUsers will return the list of users fileterd by query -func ListFilteredUsers(ctx context.Context, db bun.IDB, users *[]models.KratosIdentities, fusers []uuid.UUID, query string, orderBy string, order string, limit int, offset int) (*[]models.KratosIdentities, error) { +func ListFilteredUsers(ctx context.Context, db bun.IDB, users *[]models.KratosIdentities, fusers []uuid.UUID, query string, utype string, orderBy string, order string, limit int, offset int) (*[]models.KratosIdentities, error) { q := db.NewSelect().Model(users) + + if utype != "" { + q.Relation("IdentityCredential"). + Relation("IdentityCredential.IdentityCredentialType", func(q *bun.SelectQuery) *bun.SelectQuery { + return q.Where("name = ?", utype) + }) + } + if len(fusers) > 0 { // filter with precomputed users if we have any q.Where("id IN (?)", bun.In(fusers)) diff --git a/internal/models/kratosidentities.go b/internal/models/kratosidentities.go index db23845..5aee37e 100644 --- a/internal/models/kratosidentities.go +++ b/internal/models/kratosidentities.go @@ -7,15 +7,32 @@ import ( "github.com/uptrace/bun" ) +type KratosIdentityCredentialTypes struct { + bun.BaseModel `bun:"table:identity_credential_types,alias:ict"` + + ID uuid.UUID `bun:"id,type:uuid,pk"` + Name string `bun:"name,type:string"` +} + +type KratosIdentityCredentials struct { + bun.BaseModel `bun:"table:identity_credentials,alias:ic"` + + ID uuid.UUID `bun:"id,type:uuid,pk"` + IdentityID uuid.UUID `bun:"identity_id,type:uuid"` + IdentityCredentialTypeID uuid.UUID `bun:"identity_credential_type_id,type:uuid"` + IdentityCredentialType KratosIdentityCredentialTypes `bun:"rel:has-one,join:identity_credential_type_id=id"` +} + type KratosIdentities struct { bun.BaseModel `bun:"table:identities,alias:identities"` - ID uuid.UUID `bun:"id,type:uuid,pk"` - SchemaId string `bun:"schema_id,notnull"` - Traits map[string]interface{} `bun:"traits,type:jsonb"` - CreatedAt time.Time `bun:"created_at,notnull,default:current_timestamp"` - UpdatedAt time.Time `bun:"updated_at,notnull,default:current_timestamp"` - State string `bun:"state,notnull"` - StateChangedAt time.Time `bun:"state_changed_at,notnull,default:current_timestamp"` - NId uuid.UUID `bun:"nid,type:uuid,pk"` + ID uuid.UUID `bun:"id,type:uuid,pk"` + SchemaId string `bun:"schema_id,notnull"` + Traits map[string]interface{} `bun:"traits,type:jsonb"` + CreatedAt time.Time `bun:"created_at,notnull,default:current_timestamp"` + UpdatedAt time.Time `bun:"updated_at,notnull,default:current_timestamp"` + State string `bun:"state,notnull"` + StateChangedAt time.Time `bun:"state_changed_at,notnull,default:current_timestamp"` + NId uuid.UUID `bun:"nid,type:uuid,pk"` + IdentityCredential KratosIdentityCredentials `bun:"rel:has-one,join:id=identity_id"` } diff --git a/master.rest b/master.rest index 1da1ad5..31f36cd 100644 --- a/master.rest +++ b/master.rest @@ -276,7 +276,7 @@ spec: project: :project # Get all users -GET :host/auth/v3/users +GET :host/auth/v3/users?partner=:partner&organization=:org&type=password Content-Type: application/yaml X-Session-Token: :token diff --git a/pkg/service/user.go b/pkg/service/user.go index f584151..dc1e7ce 100644 --- a/pkg/service/user.go +++ b/pkg/service/user.go @@ -718,7 +718,7 @@ func (s *userService) List(ctx context.Context, opts ...query.Option) (*userv3.U if len(uids) != 0 { // TODO: maybe merge this with the previous one into single sql usrs, err = dao.ListFilteredUsers(ctx, s.db, &accs, - uids, queryOptions.Q, + uids, queryOptions.Q, queryOptions.Type, queryOptions.OrderBy, queryOptions.Order, int(queryOptions.Limit), int(queryOptions.Offset)) if err != nil { @@ -728,7 +728,7 @@ func (s *userService) List(ctx context.Context, opts ...query.Option) (*userv3.U } else { // If no filters are available we have to list just using identities table usrs, err = dao.ListFilteredUsers(ctx, s.db, &accs, - []uuid.UUID{}, queryOptions.Q, + []uuid.UUID{}, queryOptions.Q, queryOptions.Type, queryOptions.OrderBy, queryOptions.Order, int(queryOptions.Limit), int(queryOptions.Offset)) if err != nil { diff --git a/pkg/service/user_test.go b/pkg/service/user_test.go index 5bc4b4c..8fea08c 100644 --- a/pkg/service/user_test.go +++ b/pkg/service/user_test.go @@ -490,6 +490,90 @@ func TestUserList(t *testing.T) { performBasicAuthProviderChecks(t, *ap, 0, 0, 0, 0) } + +func TestUserListWithType(t *testing.T) { + // TODO: merge these tests + db, mock := getDB(t) + defer db.Close() + + ap := &mockAuthProvider{} + mazc := mockAuthzClient{} + us := NewUserService(ap, db, &mazc, nil, common.CliConfigDownloadData{}) + + uuuid1 := uuid.New().String() + uuuid2 := uuid.New().String() + puuid := uuid.New().String() + ouuid := uuid.New().String() + guuid := uuid.New().String() + ruuid := uuid.New().String() + pruuid := uuid.New().String() + + mock.ExpectQuery(`SELECT "partner"."id" FROM "authsrv_partner" AS "partner"`). + WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(puuid)) + mock.ExpectQuery(`SELECT "organization"."id" FROM "authsrv_organization" AS "organization"`). + WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(ouuid)) + mock.ExpectQuery(`SELECT "identities"."id", "identities"."schema_id", "identities"."traits", "identities"."created_at", "identities"."updated_at", "identities"."state", "identities"."state_changed_at", "identities"."nid", "identity_credential"."id" AS "identity_credential__id", "identity_credential"."identity_id" AS "identity_credential__identity_id", "identity_credential"."identity_credential_type_id" AS "identity_credential__identity_credential_type_id", "identity_credential__identity_credential_type"."id" AS "identity_credential__identity_credential_type__id", "identity_credential__identity_credential_type"."name" AS "identity_credential__identity_credential_type__name" FROM "identities" LEFT JOIN "identity_credentials" AS "identity_credential" ON ."identity_credential"."identity_id" = "identities"."id". LEFT JOIN "identity_credential_types" AS "identity_credential__identity_credential_type" ON ."identity_credential__identity_credential_type"."id" = "identity_credential"."identity_credential_type_id". WHERE .name = 'password'. LIMIT 10`). + WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id", "traits"}). + AddRow(uuuid1, []byte(`{"email":"johndoe@provider.com", "first_name": "John", "last_name": "Doe", "organization_id": "`+ouuid+`", "partner_id": "`+puuid+`", "description": "My awesome user"}`)). + AddRow(uuuid2, []byte(`{"email":"johndoe@provider.com", "first_name": "John", "last_name": "Doe", "organization_id": "`+ouuid+`", "partner_id": "`+puuid+`", "description": "My awesome user"}`))) + + mock.ExpectQuery(`SELECT "group"."id".* FROM "authsrv_group" AS "group" JOIN authsrv_groupaccount ON authsrv_groupaccount.group_id="group".id WHERE .authsrv_groupaccount.account_id = '` + uuuid1 + `'`). + WithArgs().WillReturnRows(sqlmock.NewRows([]string{"name"}). + AddRow("group-" + guuid)) + mock.ExpectQuery(`SELECT authsrv_resourcerole.name as role, authsrv_group.name as group FROM "authsrv_grouprole" JOIN authsrv_resourcerole ON authsrv_resourcerole.id=authsrv_grouprole.role_id JOIN authsrv_group ON authsrv_group.id=authsrv_grouprole.group_id WHERE`). + WithArgs().WillReturnRows(sqlmock.NewRows([]string{"role", "group"}).AddRow("role-"+ruuid, "group-"+guuid)) + mock.ExpectQuery(`SELECT authsrv_resourcerole.name as role, authsrv_project.name as project, authsrv_group.name as group FROM "authsrv_projectgrouprole" JOIN authsrv_resourcerole ON authsrv_resourcerole.id=authsrv_projectgrouprole.role_id JOIN authsrv_project ON authsrv_project.id=authsrv_projectgrouprole.project_id JOIN authsrv_group ON authsrv_group.id=authsrv_projectgrouprole.group_id WHERE`). + WithArgs().WillReturnRows(sqlmock.NewRows([]string{"role", "project"}).AddRow("role-"+ruuid, "project-"+puuid)) + mock.ExpectQuery(`SELECT authsrv_resourcerole.name as role, authsrv_project.name as project, namespace_id as namespace, authsrv_group.name as group FROM "authsrv_projectgroupnamespacerole"`). + WithArgs().WillReturnRows(sqlmock.NewRows([]string{"role", "project"}).AddRow("role-"+ruuid, "project-"+puuid)) + mock.ExpectQuery(`SELECT authsrv_resourcerole.name as role FROM "authsrv_accountresourcerole" JOIN authsrv_resourcerole ON authsrv_resourcerole.id=authsrv_accountresourcerole.role_id WHERE .authsrv_accountresourcerole.account_id = '` + uuuid1 + `'`). + WithArgs().WillReturnRows(sqlmock.NewRows([]string{"role"}).AddRow("role-" + ruuid)) + mock.ExpectQuery(`SELECT distinct authsrv_resourcerole.name as role, authsrv_project.name as project FROM "authsrv_projectaccountresourcerole" JOIN authsrv_resourcerole ON authsrv_resourcerole.id=authsrv_projectaccountresourcerole.role_id JOIN authsrv_project ON authsrv_project.id=authsrv_projectaccountresourcerole.project_id WHERE .authsrv_projectaccountresourcerole.account_id = '` + uuuid1 + `'`). + WithArgs().WillReturnRows(sqlmock.NewRows([]string{"role", "project"}).AddRow("role-"+ruuid, "project-"+pruuid)) + mock.ExpectQuery(`SELECT authsrv_resourcerole.name as role, authsrv_project.name as project, namespace_id as namespace FROM "authsrv_projectaccountnamespacerole" JOIN authsrv_resourcerole ON authsrv_resourcerole.id=authsrv_projectaccountnamespacerole.role_id JOIN authsrv_project ON authsrv_project.id=authsrv_projectaccountnamespacerole.project_id WHERE .authsrv_projectaccountnamespacerole.account_id = '` + uuuid1 + `'`). + WithArgs().WillReturnRows(sqlmock.NewRows([]string{"role", "project", "namespace"}).AddRow("role-"+ruuid, "project-"+pruuid, 9)) + + mock.ExpectQuery(`SELECT "group"."id".* FROM "authsrv_group" AS "group" JOIN authsrv_groupaccount ON authsrv_groupaccount.group_id="group".id WHERE .authsrv_groupaccount.account_id = '` + uuuid2 + `'`). + WithArgs().WillReturnRows(sqlmock.NewRows([]string{"name"}). + AddRow("group-" + guuid)) + mock.ExpectQuery(`SELECT authsrv_resourcerole.name as role, authsrv_group.name as group FROM "authsrv_grouprole" JOIN authsrv_resourcerole ON authsrv_resourcerole.id=authsrv_grouprole.role_id JOIN authsrv_group ON authsrv_group.id=authsrv_grouprole.group_id WHERE`). + WithArgs().WillReturnRows(sqlmock.NewRows([]string{"role", "group"}).AddRow("role-"+ruuid, "group-"+guuid)) + mock.ExpectQuery(`SELECT authsrv_resourcerole.name as role, authsrv_project.name as project, authsrv_group.name as group FROM "authsrv_projectgrouprole" JOIN authsrv_resourcerole ON authsrv_resourcerole.id=authsrv_projectgrouprole.role_id JOIN authsrv_project ON authsrv_project.id=authsrv_projectgrouprole.project_id JOIN authsrv_group ON authsrv_group.id=authsrv_projectgrouprole.group_id WHERE`). + WithArgs().WillReturnRows(sqlmock.NewRows([]string{"role", "project"}).AddRow("role-"+ruuid, "project-"+puuid)) + mock.ExpectQuery(`SELECT authsrv_resourcerole.name as role, authsrv_project.name as project, namespace_id as namespace, authsrv_group.name as group FROM "authsrv_projectgroupnamespacerole"`). + WithArgs().WillReturnRows(sqlmock.NewRows([]string{"role", "project"}).AddRow("role-"+ruuid, "project-"+puuid)) + mock.ExpectQuery(`SELECT authsrv_resourcerole.name as role FROM "authsrv_accountresourcerole" JOIN authsrv_resourcerole ON authsrv_resourcerole.id=authsrv_accountresourcerole.role_id WHERE .authsrv_accountresourcerole.account_id = '` + uuuid2 + `'`). + WithArgs().WillReturnRows(sqlmock.NewRows([]string{"role"}).AddRow("role-" + ruuid)) + mock.ExpectQuery(`SELECT distinct authsrv_resourcerole.name as role, authsrv_project.name as project FROM "authsrv_projectaccountresourcerole" JOIN authsrv_resourcerole ON authsrv_resourcerole.id=authsrv_projectaccountresourcerole.role_id JOIN authsrv_project ON authsrv_project.id=authsrv_projectaccountresourcerole.project_id WHERE .authsrv_projectaccountresourcerole.account_id = '` + uuuid2 + `'`). + WithArgs().WillReturnRows(sqlmock.NewRows([]string{"role", "project"}).AddRow("role-"+ruuid, "project-"+pruuid)) + mock.ExpectQuery(`SELECT authsrv_resourcerole.name as role, authsrv_project.name as project, namespace_id as namespace FROM "authsrv_projectaccountnamespacerole" JOIN authsrv_resourcerole ON authsrv_resourcerole.id=authsrv_projectaccountnamespacerole.role_id JOIN authsrv_project ON authsrv_project.id=authsrv_projectaccountnamespacerole.project_id WHERE .authsrv_projectaccountnamespacerole.account_id = '` + uuuid2 + `'`). + WithArgs().WillReturnRows(sqlmock.NewRows([]string{"role", "project", "namespace"}).AddRow("role-"+ruuid, "project-"+pruuid, 9)) + + qo := &commonv3.QueryOptions{Organization: ouuid, Partner: puuid, Type: "password"} + userlist, err := us.List(context.Background(), query.WithOptions(qo)) + if err != nil { + t.Fatal("could not list users:", err) + } + if userlist.Metadata.Count != 2 { + t.Fatalf("incorrect number of users returned, expected 2; got %v", userlist.Metadata.Count) + } + if userlist.Items[0].Metadata.Name != "johndoe@provider.com" || userlist.Items[1].Metadata.Name != "johndoe@provider.com" { + t.Errorf("incorrect user names returned when listing; expected '%v' and '%v'; got '%v' and '%v'", "johndoe@provider.com", "johndoe@provider.com", userlist.Items[0].Metadata.Name, userlist.Items[1].Metadata.Name) + } + if len(userlist.Items[0].GetSpec().GetGroups()) != 1 { + t.Errorf("invalid number of groups returned for user, expected 1; got '%v'", len(userlist.Items[0].GetSpec().GetGroups())) + } + + if len(userlist.Items[0].GetSpec().GetProjectNamespaceRoles()) != 6 { + t.Errorf("invalid number of roles returned for user, expected 6; got '%v'", len(userlist.Items[0].GetSpec().GetProjectNamespaceRoles())) + } + if userlist.Items[0].GetSpec().GetProjectNamespaceRoles()[2].GetNamespace() != 9 { + t.Errorf("invalid namespace in role returned for user, expected 9; got '%v'", userlist.Items[0].GetSpec().GetProjectNamespaceRoles()[2].Namespace) + } + + performBasicAuthProviderChecks(t, *ap, 0, 0, 0, 0) +} + func TestUserFiltered(t *testing.T) { db, mock := getDB(t) defer db.Close()