diff --git a/api/user/v1/user.pb.go b/api/user/v1/user.pb.go index 12a954ca3f4..0cbc35158e2 100644 --- a/api/user/v1/user.pb.go +++ b/api/user/v1/user.pb.go @@ -13,6 +13,7 @@ import ( _ "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options" _ "google.golang.org/genproto/googleapis/api/annotations" + _ "google.golang.org/genproto/googleapis/api/visibility" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" timestamppb "google.golang.org/protobuf/types/known/timestamppb" @@ -151,6 +152,96 @@ func (x *GetUserResponse) GetSnoozeCount() uint32 { return 0 } +type GetDemoUserCredentialsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetDemoUserCredentialsRequest) Reset() { + *x = GetDemoUserCredentialsRequest{} + mi := &file_user_v1_user_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetDemoUserCredentialsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetDemoUserCredentialsRequest) ProtoMessage() {} + +func (x *GetDemoUserCredentialsRequest) ProtoReflect() protoreflect.Message { + mi := &file_user_v1_user_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetDemoUserCredentialsRequest.ProtoReflect.Descriptor instead. +func (*GetDemoUserCredentialsRequest) Descriptor() ([]byte, []int) { + return file_user_v1_user_proto_rawDescGZIP(), []int{2} +} + +type GetDemoUserCredentialsResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Demo username + Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"` + // Demo password + Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetDemoUserCredentialsResponse) Reset() { + *x = GetDemoUserCredentialsResponse{} + mi := &file_user_v1_user_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetDemoUserCredentialsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetDemoUserCredentialsResponse) ProtoMessage() {} + +func (x *GetDemoUserCredentialsResponse) ProtoReflect() protoreflect.Message { + mi := &file_user_v1_user_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetDemoUserCredentialsResponse.ProtoReflect.Descriptor instead. +func (*GetDemoUserCredentialsResponse) Descriptor() ([]byte, []int) { + return file_user_v1_user_proto_rawDescGZIP(), []int{3} +} + +func (x *GetDemoUserCredentialsResponse) GetUsername() string { + if x != nil { + return x.Username + } + return "" +} + +func (x *GetDemoUserCredentialsResponse) GetPassword() string { + if x != nil { + return x.Password + } + return "" +} + type UpdateUserRequest struct { state protoimpl.MessageState `protogen:"open.v1"` // Product Tour @@ -165,7 +256,7 @@ type UpdateUserRequest struct { func (x *UpdateUserRequest) Reset() { *x = UpdateUserRequest{} - mi := &file_user_v1_user_proto_msgTypes[2] + mi := &file_user_v1_user_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -177,7 +268,7 @@ func (x *UpdateUserRequest) String() string { func (*UpdateUserRequest) ProtoMessage() {} func (x *UpdateUserRequest) ProtoReflect() protoreflect.Message { - mi := &file_user_v1_user_proto_msgTypes[2] + mi := &file_user_v1_user_proto_msgTypes[4] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -190,7 +281,7 @@ func (x *UpdateUserRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateUserRequest.ProtoReflect.Descriptor instead. func (*UpdateUserRequest) Descriptor() ([]byte, []int) { - return file_user_v1_user_proto_rawDescGZIP(), []int{2} + return file_user_v1_user_proto_rawDescGZIP(), []int{4} } func (x *UpdateUserRequest) GetProductTourCompleted() bool { @@ -234,7 +325,7 @@ type UpdateUserResponse struct { func (x *UpdateUserResponse) Reset() { *x = UpdateUserResponse{} - mi := &file_user_v1_user_proto_msgTypes[3] + mi := &file_user_v1_user_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -246,7 +337,7 @@ func (x *UpdateUserResponse) String() string { func (*UpdateUserResponse) ProtoMessage() {} func (x *UpdateUserResponse) ProtoReflect() protoreflect.Message { - mi := &file_user_v1_user_proto_msgTypes[3] + mi := &file_user_v1_user_proto_msgTypes[5] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -259,7 +350,7 @@ func (x *UpdateUserResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateUserResponse.ProtoReflect.Descriptor instead. func (*UpdateUserResponse) Descriptor() ([]byte, []int) { - return file_user_v1_user_proto_rawDescGZIP(), []int{3} + return file_user_v1_user_proto_rawDescGZIP(), []int{5} } func (x *UpdateUserResponse) GetUserId() uint32 { @@ -312,7 +403,7 @@ type ListUsersRequest struct { func (x *ListUsersRequest) Reset() { *x = ListUsersRequest{} - mi := &file_user_v1_user_proto_msgTypes[4] + mi := &file_user_v1_user_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -324,7 +415,7 @@ func (x *ListUsersRequest) String() string { func (*ListUsersRequest) ProtoMessage() {} func (x *ListUsersRequest) ProtoReflect() protoreflect.Message { - mi := &file_user_v1_user_proto_msgTypes[4] + mi := &file_user_v1_user_proto_msgTypes[6] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -337,7 +428,7 @@ func (x *ListUsersRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListUsersRequest.ProtoReflect.Descriptor instead. func (*ListUsersRequest) Descriptor() ([]byte, []int) { - return file_user_v1_user_proto_rawDescGZIP(), []int{4} + return file_user_v1_user_proto_rawDescGZIP(), []int{6} } type ListUsersResponse struct { @@ -349,7 +440,7 @@ type ListUsersResponse struct { func (x *ListUsersResponse) Reset() { *x = ListUsersResponse{} - mi := &file_user_v1_user_proto_msgTypes[5] + mi := &file_user_v1_user_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -361,7 +452,7 @@ func (x *ListUsersResponse) String() string { func (*ListUsersResponse) ProtoMessage() {} func (x *ListUsersResponse) ProtoReflect() protoreflect.Message { - mi := &file_user_v1_user_proto_msgTypes[5] + mi := &file_user_v1_user_proto_msgTypes[7] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -374,7 +465,7 @@ func (x *ListUsersResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListUsersResponse.ProtoReflect.Descriptor instead. func (*ListUsersResponse) Descriptor() ([]byte, []int) { - return file_user_v1_user_proto_rawDescGZIP(), []int{5} + return file_user_v1_user_proto_rawDescGZIP(), []int{7} } func (x *ListUsersResponse) GetUsers() []*ListUsersResponse_UserDetail { @@ -395,7 +486,7 @@ type ListUsersResponse_UserDetail struct { func (x *ListUsersResponse_UserDetail) Reset() { *x = ListUsersResponse_UserDetail{} - mi := &file_user_v1_user_proto_msgTypes[6] + mi := &file_user_v1_user_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -407,7 +498,7 @@ func (x *ListUsersResponse_UserDetail) String() string { func (*ListUsersResponse_UserDetail) ProtoMessage() {} func (x *ListUsersResponse_UserDetail) ProtoReflect() protoreflect.Message { - mi := &file_user_v1_user_proto_msgTypes[6] + mi := &file_user_v1_user_proto_msgTypes[8] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -420,7 +511,7 @@ func (x *ListUsersResponse_UserDetail) ProtoReflect() protoreflect.Message { // Deprecated: Use ListUsersResponse_UserDetail.ProtoReflect.Descriptor instead. func (*ListUsersResponse_UserDetail) Descriptor() ([]byte, []int) { - return file_user_v1_user_proto_rawDescGZIP(), []int{5, 0} + return file_user_v1_user_proto_rawDescGZIP(), []int{7, 0} } func (x *ListUsersResponse_UserDetail) GetUserId() uint32 { @@ -441,7 +532,7 @@ var File_user_v1_user_proto protoreflect.FileDescriptor const file_user_v1_user_proto_rawDesc = "" + "\n" + - "\x12user/v1/user.proto\x12\auser.v1\x1a\x1cgoogle/api/annotations.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a.protoc-gen-openapiv2/options/annotations.proto\"\x10\n" + + "\x12user/v1/user.proto\x12\auser.v1\x1a\x1cgoogle/api/annotations.proto\x1a\x1bgoogle/api/visibility.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a.protoc-gen-openapiv2/options/annotations.proto\"\x10\n" + "\x0eGetUserRequest\"\xac\x02\n" + "\x0fGetUserResponse\x12\x17\n" + "\auser_id\x18\x01 \x01(\rR\x06userId\x124\n" + @@ -450,7 +541,13 @@ const file_user_v1_user_proto_rawDesc = "" + "\x13snoozed_pmm_version\x18\x04 \x01(\tR\x11snoozedPmmVersion\x129\n" + "\n" + "snoozed_at\x18\x06 \x01(\v2\x1a.google.protobuf.TimestampR\tsnoozedAt\x12!\n" + - "\fsnooze_count\x18\a \x01(\rR\vsnoozeCountJ\x04\b\x05\x10\x06\"\x95\x02\n" + + "\fsnooze_count\x18\a \x01(\rR\vsnoozeCountJ\x04\b\x05\x10\x06\"1\n" + + "\x1dGetDemoUserCredentialsRequest:\x10\xfa\xd2\xe4\x93\x02\n" + + "\x12\bINTERNAL\"j\n" + + "\x1eGetDemoUserCredentialsResponse\x12\x1a\n" + + "\busername\x18\x01 \x01(\tR\busername\x12\x1a\n" + + "\bpassword\x18\x02 \x01(\tR\bpassword:\x10\xfa\xd2\xe4\x93\x02\n" + + "\x12\bINTERNAL\"\x95\x02\n" + "\x11UpdateUserRequest\x129\n" + "\x16product_tour_completed\x18\x02 \x01(\bH\x00R\x14productTourCompleted\x88\x01\x01\x12;\n" + "\x17alerting_tour_completed\x18\x03 \x01(\bH\x01R\x15alertingTourCompleted\x88\x01\x01\x123\n" + @@ -472,12 +569,14 @@ const file_user_v1_user_proto_rawDesc = "" + "\n" + "UserDetail\x12\x17\n" + "\auser_id\x18\x01 \x01(\rR\x06userId\x12\x19\n" + - "\brole_ids\x18\x02 \x03(\rR\aroleIds2\xd4\x03\n" + + "\brole_ids\x18\x02 \x03(\rR\aroleIds2\xc3\x05\n" + "\vUserService\x12\x8e\x01\n" + "\aGetUser\x12\x17.user.v1.GetUserRequest\x1a\x18.user.v1.GetUserResponse\"P\x92A9\x12\x10Get user details\x1a%Retrieve user details from PMM server\x82\xd3\xe4\x93\x02\x0e\x12\f/v1/users/me\x12\x93\x01\n" + "\n" + "UpdateUser\x12\x1a.user.v1.UpdateUserRequest\x1a\x1b.user.v1.UpdateUserResponse\"L\x92A2\x12\rUpdate a user\x1a!Update user details in PMM server\x82\xd3\xe4\x93\x02\x11:\x01*\x1a\f/v1/users/me\x12\x9d\x01\n" + - "\tListUsers\x12\x19.user.v1.ListUsersRequest\x1a\x1a.user.v1.ListUsersResponse\"Y\x92AE\x12\x0eList all users\x1a3Retrieve user details for all users from PMM server\x82\xd3\xe4\x93\x02\v\x12\t/v1/usersB\x8f\x01\x92A\f\x12\n" + + "\tListUsers\x12\x19.user.v1.ListUsersRequest\x1a\x1a.user.v1.ListUsersResponse\"Y\x92AE\x12\x0eList all users\x1a3Retrieve user details for all users from PMM server\x82\xd3\xe4\x93\x02\v\x12\t/v1/users\x12\xec\x01\n" + + "\x16GetDemoUserCredentials\x12&.user.v1.GetDemoUserCredentialsRequest\x1a'.user.v1.GetDemoUserCredentialsResponse\"\x80\x01\x92AK\x12\x19Get demo user credentials\x1a.Retrieve demo user credentials from PMM server\xfa\xd2\xe4\x93\x02\n" + + "\x12\bINTERNAL\x82\xd3\xe4\x93\x02\x1c\x12\x1a/v1/users/demo/credentialsB\x8f\x01\x92A\f\x12\n" + "\n" + "\bUser API\n" + "\vcom.user.v1B\tUserProtoP\x01Z)github.com/percona/pmm/api/user/v1;userv1\xa2\x02\x03UXX\xaa\x02\aUser.V1\xca\x02\aUser\\V1\xe2\x02\x13User\\V1\\GPBMetadata\xea\x02\bUser::V1b\x06proto3" @@ -495,31 +594,35 @@ func file_user_v1_user_proto_rawDescGZIP() []byte { } var ( - file_user_v1_user_proto_msgTypes = make([]protoimpl.MessageInfo, 7) + file_user_v1_user_proto_msgTypes = make([]protoimpl.MessageInfo, 9) file_user_v1_user_proto_goTypes = []any{ - (*GetUserRequest)(nil), // 0: user.v1.GetUserRequest - (*GetUserResponse)(nil), // 1: user.v1.GetUserResponse - (*UpdateUserRequest)(nil), // 2: user.v1.UpdateUserRequest - (*UpdateUserResponse)(nil), // 3: user.v1.UpdateUserResponse - (*ListUsersRequest)(nil), // 4: user.v1.ListUsersRequest - (*ListUsersResponse)(nil), // 5: user.v1.ListUsersResponse - (*ListUsersResponse_UserDetail)(nil), // 6: user.v1.ListUsersResponse.UserDetail - (*timestamppb.Timestamp)(nil), // 7: google.protobuf.Timestamp + (*GetUserRequest)(nil), // 0: user.v1.GetUserRequest + (*GetUserResponse)(nil), // 1: user.v1.GetUserResponse + (*GetDemoUserCredentialsRequest)(nil), // 2: user.v1.GetDemoUserCredentialsRequest + (*GetDemoUserCredentialsResponse)(nil), // 3: user.v1.GetDemoUserCredentialsResponse + (*UpdateUserRequest)(nil), // 4: user.v1.UpdateUserRequest + (*UpdateUserResponse)(nil), // 5: user.v1.UpdateUserResponse + (*ListUsersRequest)(nil), // 6: user.v1.ListUsersRequest + (*ListUsersResponse)(nil), // 7: user.v1.ListUsersResponse + (*ListUsersResponse_UserDetail)(nil), // 8: user.v1.ListUsersResponse.UserDetail + (*timestamppb.Timestamp)(nil), // 9: google.protobuf.Timestamp } ) var file_user_v1_user_proto_depIdxs = []int32{ - 7, // 0: user.v1.GetUserResponse.snoozed_at:type_name -> google.protobuf.Timestamp - 7, // 1: user.v1.UpdateUserResponse.snoozed_at:type_name -> google.protobuf.Timestamp - 6, // 2: user.v1.ListUsersResponse.users:type_name -> user.v1.ListUsersResponse.UserDetail + 9, // 0: user.v1.GetUserResponse.snoozed_at:type_name -> google.protobuf.Timestamp + 9, // 1: user.v1.UpdateUserResponse.snoozed_at:type_name -> google.protobuf.Timestamp + 8, // 2: user.v1.ListUsersResponse.users:type_name -> user.v1.ListUsersResponse.UserDetail 0, // 3: user.v1.UserService.GetUser:input_type -> user.v1.GetUserRequest - 2, // 4: user.v1.UserService.UpdateUser:input_type -> user.v1.UpdateUserRequest - 4, // 5: user.v1.UserService.ListUsers:input_type -> user.v1.ListUsersRequest - 1, // 6: user.v1.UserService.GetUser:output_type -> user.v1.GetUserResponse - 3, // 7: user.v1.UserService.UpdateUser:output_type -> user.v1.UpdateUserResponse - 5, // 8: user.v1.UserService.ListUsers:output_type -> user.v1.ListUsersResponse - 6, // [6:9] is the sub-list for method output_type - 3, // [3:6] is the sub-list for method input_type + 4, // 4: user.v1.UserService.UpdateUser:input_type -> user.v1.UpdateUserRequest + 6, // 5: user.v1.UserService.ListUsers:input_type -> user.v1.ListUsersRequest + 2, // 6: user.v1.UserService.GetDemoUserCredentials:input_type -> user.v1.GetDemoUserCredentialsRequest + 1, // 7: user.v1.UserService.GetUser:output_type -> user.v1.GetUserResponse + 5, // 8: user.v1.UserService.UpdateUser:output_type -> user.v1.UpdateUserResponse + 7, // 9: user.v1.UserService.ListUsers:output_type -> user.v1.ListUsersResponse + 3, // 10: user.v1.UserService.GetDemoUserCredentials:output_type -> user.v1.GetDemoUserCredentialsResponse + 7, // [7:11] is the sub-list for method output_type + 3, // [3:7] is the sub-list for method input_type 3, // [3:3] is the sub-list for extension type_name 3, // [3:3] is the sub-list for extension extendee 0, // [0:3] is the sub-list for field type_name @@ -530,14 +633,14 @@ func file_user_v1_user_proto_init() { if File_user_v1_user_proto != nil { return } - file_user_v1_user_proto_msgTypes[2].OneofWrappers = []any{} + file_user_v1_user_proto_msgTypes[4].OneofWrappers = []any{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_user_v1_user_proto_rawDesc), len(file_user_v1_user_proto_rawDesc)), NumEnums: 0, - NumMessages: 7, + NumMessages: 9, NumExtensions: 0, NumServices: 1, }, diff --git a/api/user/v1/user.pb.gw.go b/api/user/v1/user.pb.gw.go index 52268099c70..0784efe7c47 100644 --- a/api/user/v1/user.pb.gw.go +++ b/api/user/v1/user.pb.gw.go @@ -104,6 +104,27 @@ func local_request_UserService_ListUsers_0(ctx context.Context, marshaler runtim return msg, metadata, err } +func request_UserService_GetDemoUserCredentials_0(ctx context.Context, marshaler runtime.Marshaler, client UserServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var ( + protoReq GetDemoUserCredentialsRequest + metadata runtime.ServerMetadata + ) + if req.Body != nil { + _, _ = io.Copy(io.Discard, req.Body) + } + msg, err := client.GetDemoUserCredentials(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err +} + +func local_request_UserService_GetDemoUserCredentials_0(ctx context.Context, marshaler runtime.Marshaler, server UserServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var ( + protoReq GetDemoUserCredentialsRequest + metadata runtime.ServerMetadata + ) + msg, err := server.GetDemoUserCredentials(ctx, &protoReq) + return msg, metadata, err +} + // RegisterUserServiceHandlerServer registers the http handlers for service UserService to "mux". // UnaryRPC :call UserServiceServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. @@ -170,6 +191,26 @@ func RegisterUserServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux } forward_UserService_ListUsers_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) + mux.Handle(http.MethodGet, pattern_UserService_GetDemoUserCredentials_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/user.v1.UserService/GetDemoUserCredentials", runtime.WithHTTPPathPattern("/v1/users/demo/credentials")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_UserService_GetDemoUserCredentials_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + forward_UserService_GetDemoUserCredentials_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) return nil } @@ -261,17 +302,36 @@ func RegisterUserServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux } forward_UserService_ListUsers_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) + mux.Handle(http.MethodGet, pattern_UserService_GetDemoUserCredentials_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/user.v1.UserService/GetDemoUserCredentials", runtime.WithHTTPPathPattern("/v1/users/demo/credentials")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_UserService_GetDemoUserCredentials_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + forward_UserService_GetDemoUserCredentials_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) return nil } var ( - pattern_UserService_GetUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "users", "me"}, "")) - pattern_UserService_UpdateUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "users", "me"}, "")) - pattern_UserService_ListUsers_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "users"}, "")) + pattern_UserService_GetUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "users", "me"}, "")) + pattern_UserService_UpdateUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "users", "me"}, "")) + pattern_UserService_ListUsers_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "users"}, "")) + pattern_UserService_GetDemoUserCredentials_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v1", "users", "demo", "credentials"}, "")) ) var ( - forward_UserService_GetUser_0 = runtime.ForwardResponseMessage - forward_UserService_UpdateUser_0 = runtime.ForwardResponseMessage - forward_UserService_ListUsers_0 = runtime.ForwardResponseMessage + forward_UserService_GetUser_0 = runtime.ForwardResponseMessage + forward_UserService_UpdateUser_0 = runtime.ForwardResponseMessage + forward_UserService_ListUsers_0 = runtime.ForwardResponseMessage + forward_UserService_GetDemoUserCredentials_0 = runtime.ForwardResponseMessage ) diff --git a/api/user/v1/user.pb.validate.go b/api/user/v1/user.pb.validate.go index a6c5de6f159..023b79bbd64 100644 --- a/api/user/v1/user.pb.validate.go +++ b/api/user/v1/user.pb.validate.go @@ -274,6 +274,216 @@ var _ interface { ErrorName() string } = GetUserResponseValidationError{} +// Validate checks the field values on GetDemoUserCredentialsRequest with the +// rules defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *GetDemoUserCredentialsRequest) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on GetDemoUserCredentialsRequest with +// the rules defined in the proto definition for this message. If any rules +// are violated, the result is a list of violation errors wrapped in +// GetDemoUserCredentialsRequestMultiError, or nil if none found. +func (m *GetDemoUserCredentialsRequest) ValidateAll() error { + return m.validate(true) +} + +func (m *GetDemoUserCredentialsRequest) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if len(errors) > 0 { + return GetDemoUserCredentialsRequestMultiError(errors) + } + + return nil +} + +// GetDemoUserCredentialsRequestMultiError is an error wrapping multiple +// validation errors returned by GetDemoUserCredentialsRequest.ValidateAll() +// if the designated constraints aren't met. +type GetDemoUserCredentialsRequestMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m GetDemoUserCredentialsRequestMultiError) Error() string { + msgs := make([]string, 0, len(m)) + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m GetDemoUserCredentialsRequestMultiError) AllErrors() []error { return m } + +// GetDemoUserCredentialsRequestValidationError is the validation error +// returned by GetDemoUserCredentialsRequest.Validate if the designated +// constraints aren't met. +type GetDemoUserCredentialsRequestValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e GetDemoUserCredentialsRequestValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e GetDemoUserCredentialsRequestValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e GetDemoUserCredentialsRequestValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e GetDemoUserCredentialsRequestValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e GetDemoUserCredentialsRequestValidationError) ErrorName() string { + return "GetDemoUserCredentialsRequestValidationError" +} + +// Error satisfies the builtin error interface +func (e GetDemoUserCredentialsRequestValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sGetDemoUserCredentialsRequest.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = GetDemoUserCredentialsRequestValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = GetDemoUserCredentialsRequestValidationError{} + +// Validate checks the field values on GetDemoUserCredentialsResponse with the +// rules defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *GetDemoUserCredentialsResponse) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on GetDemoUserCredentialsResponse with +// the rules defined in the proto definition for this message. If any rules +// are violated, the result is a list of violation errors wrapped in +// GetDemoUserCredentialsResponseMultiError, or nil if none found. +func (m *GetDemoUserCredentialsResponse) ValidateAll() error { + return m.validate(true) +} + +func (m *GetDemoUserCredentialsResponse) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for Username + + // no validation rules for Password + + if len(errors) > 0 { + return GetDemoUserCredentialsResponseMultiError(errors) + } + + return nil +} + +// GetDemoUserCredentialsResponseMultiError is an error wrapping multiple +// validation errors returned by GetDemoUserCredentialsResponse.ValidateAll() +// if the designated constraints aren't met. +type GetDemoUserCredentialsResponseMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m GetDemoUserCredentialsResponseMultiError) Error() string { + msgs := make([]string, 0, len(m)) + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m GetDemoUserCredentialsResponseMultiError) AllErrors() []error { return m } + +// GetDemoUserCredentialsResponseValidationError is the validation error +// returned by GetDemoUserCredentialsResponse.Validate if the designated +// constraints aren't met. +type GetDemoUserCredentialsResponseValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e GetDemoUserCredentialsResponseValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e GetDemoUserCredentialsResponseValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e GetDemoUserCredentialsResponseValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e GetDemoUserCredentialsResponseValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e GetDemoUserCredentialsResponseValidationError) ErrorName() string { + return "GetDemoUserCredentialsResponseValidationError" +} + +// Error satisfies the builtin error interface +func (e GetDemoUserCredentialsResponseValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sGetDemoUserCredentialsResponse.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = GetDemoUserCredentialsResponseValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = GetDemoUserCredentialsResponseValidationError{} + // Validate checks the field values on UpdateUserRequest with the rules defined // in the proto definition for this message. If any rules are violated, the // first error encountered is returned, or nil if there are no violations. diff --git a/api/user/v1/user.proto b/api/user/v1/user.proto index 300cef97db9..6d3d984e778 100644 --- a/api/user/v1/user.proto +++ b/api/user/v1/user.proto @@ -3,6 +3,7 @@ syntax = "proto3"; package user.v1; import "google/api/annotations.proto"; +import "google/api/visibility.proto"; import "google/protobuf/timestamp.proto"; import "protoc-gen-openapiv2/options/annotations.proto"; @@ -28,6 +29,19 @@ message GetUserResponse { uint32 snooze_count = 7; } +message GetDemoUserCredentialsRequest { + option (google.api.message_visibility).restriction = "INTERNAL"; +} + +message GetDemoUserCredentialsResponse { + option (google.api.message_visibility).restriction = "INTERNAL"; + + // Demo username + string username = 1; + // Demo password + string password = 2; +} + message UpdateUserRequest { // Product Tour optional bool product_tour_completed = 2; @@ -92,4 +106,15 @@ service UserService { description: "Retrieve user details for all users from PMM server" }; } + + // GetDemoUserCredentials is an internal API to retrieve demo user credentials from PMM server. + // It is not exposed to external users and is only used for testing and demonstration purposes. + rpc GetDemoUserCredentials(GetDemoUserCredentialsRequest) returns (GetDemoUserCredentialsResponse) { + option (google.api.method_visibility).restriction = "INTERNAL"; + option (google.api.http) = {get: "/v1/users/demo/credentials"}; + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + summary: "Get demo user credentials" + description: "Retrieve demo user credentials from PMM server" + }; + } } diff --git a/api/user/v1/user_grpc.pb.go b/api/user/v1/user_grpc.pb.go index 4201de2b381..8946f4bfb1a 100644 --- a/api/user/v1/user_grpc.pb.go +++ b/api/user/v1/user_grpc.pb.go @@ -20,9 +20,10 @@ import ( const _ = grpc.SupportPackageIsVersion9 const ( - UserService_GetUser_FullMethodName = "/user.v1.UserService/GetUser" - UserService_UpdateUser_FullMethodName = "/user.v1.UserService/UpdateUser" - UserService_ListUsers_FullMethodName = "/user.v1.UserService/ListUsers" + UserService_GetUser_FullMethodName = "/user.v1.UserService/GetUser" + UserService_UpdateUser_FullMethodName = "/user.v1.UserService/UpdateUser" + UserService_ListUsers_FullMethodName = "/user.v1.UserService/ListUsers" + UserService_GetDemoUserCredentials_FullMethodName = "/user.v1.UserService/GetDemoUserCredentials" ) // UserServiceClient is the client API for UserService service. @@ -34,6 +35,9 @@ type UserServiceClient interface { GetUser(ctx context.Context, in *GetUserRequest, opts ...grpc.CallOption) (*GetUserResponse, error) UpdateUser(ctx context.Context, in *UpdateUserRequest, opts ...grpc.CallOption) (*UpdateUserResponse, error) ListUsers(ctx context.Context, in *ListUsersRequest, opts ...grpc.CallOption) (*ListUsersResponse, error) + // GetDemoUserCredentials is an internal API to retrieve demo user credentials from PMM server. + // It is not exposed to external users and is only used for testing and demonstration purposes. + GetDemoUserCredentials(ctx context.Context, in *GetDemoUserCredentialsRequest, opts ...grpc.CallOption) (*GetDemoUserCredentialsResponse, error) } type userServiceClient struct { @@ -74,6 +78,16 @@ func (c *userServiceClient) ListUsers(ctx context.Context, in *ListUsersRequest, return out, nil } +func (c *userServiceClient) GetDemoUserCredentials(ctx context.Context, in *GetDemoUserCredentialsRequest, opts ...grpc.CallOption) (*GetDemoUserCredentialsResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(GetDemoUserCredentialsResponse) + err := c.cc.Invoke(ctx, UserService_GetDemoUserCredentials_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + // UserServiceServer is the server API for UserService service. // All implementations must embed UnimplementedUserServiceServer // for forward compatibility. @@ -83,6 +97,9 @@ type UserServiceServer interface { GetUser(context.Context, *GetUserRequest) (*GetUserResponse, error) UpdateUser(context.Context, *UpdateUserRequest) (*UpdateUserResponse, error) ListUsers(context.Context, *ListUsersRequest) (*ListUsersResponse, error) + // GetDemoUserCredentials is an internal API to retrieve demo user credentials from PMM server. + // It is not exposed to external users and is only used for testing and demonstration purposes. + GetDemoUserCredentials(context.Context, *GetDemoUserCredentialsRequest) (*GetDemoUserCredentialsResponse, error) mustEmbedUnimplementedUserServiceServer() } @@ -104,6 +121,10 @@ func (UnimplementedUserServiceServer) UpdateUser(context.Context, *UpdateUserReq func (UnimplementedUserServiceServer) ListUsers(context.Context, *ListUsersRequest) (*ListUsersResponse, error) { return nil, status.Error(codes.Unimplemented, "method ListUsers not implemented") } + +func (UnimplementedUserServiceServer) GetDemoUserCredentials(context.Context, *GetDemoUserCredentialsRequest) (*GetDemoUserCredentialsResponse, error) { + return nil, status.Error(codes.Unimplemented, "method GetDemoUserCredentials not implemented") +} func (UnimplementedUserServiceServer) mustEmbedUnimplementedUserServiceServer() {} func (UnimplementedUserServiceServer) testEmbeddedByValue() {} @@ -179,6 +200,24 @@ func _UserService_ListUsers_Handler(srv interface{}, ctx context.Context, dec fu return interceptor(ctx, in, info, handler) } +func _UserService_GetDemoUserCredentials_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetDemoUserCredentialsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServiceServer).GetDemoUserCredentials(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: UserService_GetDemoUserCredentials_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServiceServer).GetDemoUserCredentials(ctx, req.(*GetDemoUserCredentialsRequest)) + } + return interceptor(ctx, in, info, handler) +} + // UserService_ServiceDesc is the grpc.ServiceDesc for UserService service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -198,6 +237,10 @@ var UserService_ServiceDesc = grpc.ServiceDesc{ MethodName: "ListUsers", Handler: _UserService_ListUsers_Handler, }, + { + MethodName: "GetDemoUserCredentials", + Handler: _UserService_GetDemoUserCredentials_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "user/v1/user.proto", diff --git a/managed/services/grafana/auth_server.go b/managed/services/grafana/auth_server.go index bc47cbd0447..44642dd9ad7 100644 --- a/managed/services/grafana/auth_server.go +++ b/managed/services/grafana/auth_server.go @@ -86,6 +86,9 @@ var rules = map[string]role{ "/v1/platform:": admin, "/v1/platform/": viewer, "/v1/users": viewer, + // special case - used on Grafana login page before user can be authenticated. + // Used for PMM Demo user only. + "/v1/users/demo/credentials": none, // must be available without authentication for health checking "/v1/server/readyz": none, diff --git a/managed/services/user/user.go b/managed/services/user/user.go index 2ae4deb33fc..dfddb0c413f 100644 --- a/managed/services/user/user.go +++ b/managed/services/user/user.go @@ -18,6 +18,7 @@ package user import ( "context" + "os" "time" "github.com/AlekSi/pointer" @@ -165,3 +166,12 @@ func (s *Service) ListUsers(_ context.Context, _ *userv1.ListUsersRequest) (*use return resp, nil } + +// GetDemoUserCredentials is an internal API to retrieve demo user credentials from PMM server. +// It is not exposed to external users and is only used for testing and demonstration purposes. +func (s *Service) GetDemoUserCredentials(_ context.Context, _ *userv1.GetDemoUserCredentialsRequest) (*userv1.GetDemoUserCredentialsResponse, error) { //nolint:unparam + return &userv1.GetDemoUserCredentialsResponse{ + Username: os.Getenv("PMM_DEMO_USER_USERNAME"), + Password: os.Getenv("PMM_DEMO_USER_PASSWORD"), + }, nil +} diff --git a/managed/services/user/user_test.go b/managed/services/user/user_test.go index a9ac601fee8..6e9ddebf181 100644 --- a/managed/services/user/user_test.go +++ b/managed/services/user/user_test.go @@ -285,3 +285,19 @@ func TestSnoozeUpdate(t *testing.T) { mockClient.AssertExpectations(t) }) } + +func TestService_GetDemoUserCredentials(t *testing.T) { + // Set environment variables for the test + demoUserUsername := "demo_user" + demoUserPassword := "demo_pass" + t.Setenv("PMM_DEMO_USER_USERNAME", demoUserUsername) + t.Setenv("PMM_DEMO_USER_PASSWORD", demoUserPassword) + + s := &Service{} + + resp, err := s.GetDemoUserCredentials(context.Background(), &userv1.GetDemoUserCredentialsRequest{}) + require.NoError(t, err) + assert.NotNil(t, resp) + assert.Equal(t, demoUserUsername, resp.Username) + assert.Equal(t, demoUserPassword, resp.Password) +}