From 78a6e548ad8e20de5110cff23a13c9c2961ed761 Mon Sep 17 00:00:00 2001 From: Andre Sterba <andre.sterba@stud.h-da.de> Date: Mon, 4 Jul 2022 12:30:02 +0000 Subject: [PATCH] Enhance northbound interface to get user and roles by id See merge request danet/gosdn!344 --- api/go/gosdn/rbac/role.pb.go | 13 +++++++++-- api/go/gosdn/rbac/user.pb.go | 13 +++++++++-- api/openapiv2/gosdn_northbound.swagger.json | 26 +++++++++++++++------ api/proto/buf.lock | 10 ++------ api/proto/gosdn/rbac/role.proto | 1 + api/proto/gosdn/rbac/user.proto | 1 + cli/cmd/userGet.go | 8 ++++++- controller/api/role.go | 4 +++- controller/api/role_test.go | 5 +++- controller/api/user.go | 5 +++- controller/api/user_test.go | 5 +++- controller/northbound/server/role.go | 8 ++++++- controller/northbound/server/role_test.go | 2 ++ controller/northbound/server/user.go | 8 ++++++- controller/northbound/server/user_test.go | 2 ++ 15 files changed, 85 insertions(+), 26 deletions(-) diff --git a/api/go/gosdn/rbac/role.pb.go b/api/go/gosdn/rbac/role.pb.go index e3dfae038..c4212deaa 100644 --- a/api/go/gosdn/rbac/role.pb.go +++ b/api/go/gosdn/rbac/role.pb.go @@ -213,6 +213,7 @@ type GetRoleRequest struct { Timestamp int64 `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"` RoleName string `protobuf:"bytes,2,opt,name=role_name,json=roleName,proto3" json:"role_name,omitempty"` + Id string `protobuf:"bytes,3,opt,name=id,proto3" json:"id,omitempty"` } func (x *GetRoleRequest) Reset() { @@ -261,6 +262,13 @@ func (x *GetRoleRequest) GetRoleName() string { return "" } +func (x *GetRoleRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + type GetRoleResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -808,12 +816,13 @@ var file_gosdn_rbac_role_proto_rawDesc = []byte{ 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x2a, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, - 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x4b, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x52, 0x6f, + 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x5b, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1b, 0x0a, 0x09, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x6f, 0x6c, 0x65, - 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x81, 0x01, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x02, 0x69, 0x64, 0x22, 0x81, 0x01, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x2a, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, diff --git a/api/go/gosdn/rbac/user.pb.go b/api/go/gosdn/rbac/user.pb.go index f999c7dde..ef2f31b24 100644 --- a/api/go/gosdn/rbac/user.pb.go +++ b/api/go/gosdn/rbac/user.pb.go @@ -221,6 +221,7 @@ type GetUserRequest struct { Timestamp int64 `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"` Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Id string `protobuf:"bytes,3,opt,name=id,proto3" json:"id,omitempty"` } func (x *GetUserRequest) Reset() { @@ -269,6 +270,13 @@ func (x *GetUserRequest) GetName() string { return "" } +func (x *GetUserRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + type GetUserResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -703,11 +711,12 @@ var file_gosdn_rbac_user_proto_rawDesc = []byte{ 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x2a, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x22, 0x42, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, + 0x73, 0x22, 0x52, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x81, 0x01, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x81, 0x01, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x2a, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, diff --git a/api/openapiv2/gosdn_northbound.swagger.json b/api/openapiv2/gosdn_northbound.swagger.json index 9db819cb0..3fd28b3f1 100644 --- a/api/openapiv2/gosdn_northbound.swagger.json +++ b/api/openapiv2/gosdn_northbound.swagger.json @@ -17,6 +17,9 @@ { "name": "PndService" }, + { + "name": "Collector" + }, { "name": "gNMI" }, @@ -30,19 +33,16 @@ "name": "CoreService" }, { - "name": "Collector" + "name": "CsbiService" }, { "name": "AuthService" }, { - "name": "UserService" - }, - { - "name": "CsbiService" + "name": "RoleService" }, { - "name": "RoleService" + "name": "UserService" } ], "consumes": [ @@ -991,6 +991,12 @@ "in": "query", "required": false, "type": "string" + }, + { + "name": "id", + "in": "query", + "required": false, + "type": "string" } ], "tags": [ @@ -1169,6 +1175,12 @@ "in": "query", "required": false, "type": "string" + }, + { + "name": "id", + "in": "query", + "required": false, + "type": "string" } ], "tags": [ @@ -2889,7 +2901,7 @@ } }, "additionalProperties": {}, - "description": "`Any` contains an arbitrary serialized protocol buffer message along with a\nURL that describes the type of the serialized message.\n\nProtobuf library provides support to pack/unpack Any values in the form\nof utility functions or additional generated methods of the Any type.\n\nExample 1: Pack and unpack a message in C++.\n\n Foo foo = ...;\n Any any;\n any.PackFrom(foo);\n ...\n if (any.UnpackTo(\u0026foo)) {\n ...\n }\n\nExample 2: Pack and unpack a message in Java.\n\n Foo foo = ...;\n Any any = Any.pack(foo);\n ...\n if (any.is(Foo.class)) {\n foo = any.unpack(Foo.class);\n }\n\n Example 3: Pack and unpack a message in Python.\n\n foo = Foo(...)\n any = Any()\n any.Pack(foo)\n ...\n if any.Is(Foo.DESCRIPTOR):\n any.Unpack(foo)\n ...\n\n Example 4: Pack and unpack a message in Go\n\n foo := \u0026pb.Foo{...}\n any, err := anypb.New(foo)\n if err != nil {\n ...\n }\n ...\n foo := \u0026pb.Foo{}\n if err := any.UnmarshalTo(foo); err != nil {\n ...\n }\n\nThe pack methods provided by protobuf library will by default use\n'type.googleapis.com/full.type.name' as the type URL and the unpack\nmethods only use the fully qualified type name after the last '/'\nin the type URL, for example \"foo.bar.com/x/y.z\" will yield type\nname \"y.z\".\n\n\nJSON\n====\nThe JSON representation of an `Any` value uses the regular\nrepresentation of the deserialized, embedded message, with an\nadditional field `@type` which contains the type URL. Example:\n\n package google.profile;\n message Person {\n string first_name = 1;\n string last_name = 2;\n }\n\n {\n \"@type\": \"type.googleapis.com/google.profile.Person\",\n \"firstName\": \u003cstring\u003e,\n \"lastName\": \u003cstring\u003e\n }\n\nIf the embedded message type is well-known and has a custom JSON\nrepresentation, that representation will be embedded adding a field\n`value` which holds the custom JSON in addition to the `@type`\nfield. Example (for message [google.protobuf.Duration][]):\n\n {\n \"@type\": \"type.googleapis.com/google.protobuf.Duration\",\n \"value\": \"1.212s\"\n }" + "description": "`Any` contains an arbitrary serialized protocol buffer message along with a\nURL that describes the type of the serialized message.\n\nProtobuf library provides support to pack/unpack Any values in the form\nof utility functions or additional generated methods of the Any type.\n\nExample 1: Pack and unpack a message in C++.\n\n Foo foo = ...;\n Any any;\n any.PackFrom(foo);\n ...\n if (any.UnpackTo(\u0026foo)) {\n ...\n }\n\nExample 2: Pack and unpack a message in Java.\n\n Foo foo = ...;\n Any any = Any.pack(foo);\n ...\n if (any.is(Foo.class)) {\n foo = any.unpack(Foo.class);\n }\n\nExample 3: Pack and unpack a message in Python.\n\n foo = Foo(...)\n any = Any()\n any.Pack(foo)\n ...\n if any.Is(Foo.DESCRIPTOR):\n any.Unpack(foo)\n ...\n\nExample 4: Pack and unpack a message in Go\n\n foo := \u0026pb.Foo{...}\n any, err := anypb.New(foo)\n if err != nil {\n ...\n }\n ...\n foo := \u0026pb.Foo{}\n if err := any.UnmarshalTo(foo); err != nil {\n ...\n }\n\nThe pack methods provided by protobuf library will by default use\n'type.googleapis.com/full.type.name' as the type URL and the unpack\nmethods only use the fully qualified type name after the last '/'\nin the type URL, for example \"foo.bar.com/x/y.z\" will yield type\nname \"y.z\".\n\n\nJSON\n\nThe JSON representation of an `Any` value uses the regular\nrepresentation of the deserialized, embedded message, with an\nadditional field `@type` which contains the type URL. Example:\n\n package google.profile;\n message Person {\n string first_name = 1;\n string last_name = 2;\n }\n\n {\n \"@type\": \"type.googleapis.com/google.profile.Person\",\n \"firstName\": \u003cstring\u003e,\n \"lastName\": \u003cstring\u003e\n }\n\nIf the embedded message type is well-known and has a custom JSON\nrepresentation, that representation will be embedded adding a field\n`value` which holds the custom JSON in addition to the `@type`\nfield. Example (for message [google.protobuf.Duration][]):\n\n {\n \"@type\": \"type.googleapis.com/google.protobuf.Duration\",\n \"value\": \"1.212s\"\n }" }, "rbacCreateRolesRequest": { "type": "object", diff --git a/api/proto/buf.lock b/api/proto/buf.lock index 7cb8f4758..91a4b401f 100644 --- a/api/proto/buf.lock +++ b/api/proto/buf.lock @@ -4,14 +4,8 @@ deps: - remote: buf.build owner: googleapis repository: googleapis - branch: main - commit: ebc3077fbae84b63a71f742dd72f7101 - digest: b1-gGcU24imC8L2I93v0LRssRMDGX0Fw9yrqgptNqVsTAU= - create_time: 2022-05-12T15:09:22.684487Z + commit: fdc236b6d1644b29a6161156ce08d8a2 - remote: buf.build owner: grpc-ecosystem repository: grpc-gateway - branch: main - commit: febd9e8be39b4f4b878b9c64bcc203fd - digest: b1-K5jSHBrJ24jZXRgQgkmphZuP-cAL2b90ssKrgvDK2hU= - create_time: 2022-04-17T01:28:07.574665Z + commit: 00116f302b12478b85deb33b734e026c diff --git a/api/proto/gosdn/rbac/role.proto b/api/proto/gosdn/rbac/role.proto index 044fbef8a..29edc1cd4 100644 --- a/api/proto/gosdn/rbac/role.proto +++ b/api/proto/gosdn/rbac/role.proto @@ -84,6 +84,7 @@ message CreateRolesResponse { message GetRoleRequest { int64 timestamp = 1; string role_name = 2; + string id = 3; } message GetRoleResponse { diff --git a/api/proto/gosdn/rbac/user.proto b/api/proto/gosdn/rbac/user.proto index 3ad7f88de..8de04465c 100644 --- a/api/proto/gosdn/rbac/user.proto +++ b/api/proto/gosdn/rbac/user.proto @@ -78,6 +78,7 @@ message CreateUsersResponse { message GetUserRequest { int64 timestamp = 1; string name = 2; + string id = 3; } message GetUserResponse { diff --git a/cli/cmd/userGet.go b/cli/cmd/userGet.go index b5f1a0bd9..1a487a3a7 100644 --- a/cli/cmd/userGet.go +++ b/cli/cmd/userGet.go @@ -33,6 +33,7 @@ package cmd import ( "code.fbi.h-da.de/danet/gosdn/controller/api" + "github.com/google/uuid" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -45,7 +46,12 @@ var userGetCmd = &cobra.Command{ Long: `Requests one user using the provided name to search for it in the stored users.`, RunE: func(cmd *cobra.Command, args []string) error { - resp, err := api.GetUser(createContextWithAuthorization(), viper.GetString("controllerAPIEndpoint"), nbUserName) + resp, err := api.GetUser( + createContextWithAuthorization(), + viper.GetString("controllerAPIEndpoint"), + nbUserName, + uuid.Nil, + ) if err != nil { return err } diff --git a/controller/api/role.go b/controller/api/role.go index b9d6bcc5c..cef731972 100644 --- a/controller/api/role.go +++ b/controller/api/role.go @@ -6,6 +6,7 @@ import ( apb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/rbac" nbi "code.fbi.h-da.de/danet/gosdn/controller/northbound/client" + "github.com/google/uuid" ) // CreateRoles creates roles with provided data @@ -24,7 +25,7 @@ func CreateRoles(ctx context.Context, addr string, roles []*apb.Role) (*apb.Crea } // GetRole returns one requested role found by name -func GetRole(ctx context.Context, addr, name string) (*apb.GetRoleResponse, error) { +func GetRole(ctx context.Context, addr, name string, uuid uuid.UUID) (*apb.GetRoleResponse, error) { roleClient, err := nbi.RoleClient(addr, dialOptions...) if err != nil { return nil, err @@ -33,6 +34,7 @@ func GetRole(ctx context.Context, addr, name string) (*apb.GetRoleResponse, erro r := &apb.GetRoleRequest{ Timestamp: time.Now().UnixNano(), RoleName: name, + Id: uuid.String(), } return roleClient.GetRole(ctx, r) diff --git a/controller/api/role_test.go b/controller/api/role_test.go index c98b0d277..785ae3128 100644 --- a/controller/api/role_test.go +++ b/controller/api/role_test.go @@ -61,6 +61,7 @@ func TestGetRole(t *testing.T) { ctx context.Context addr string name string + id uuid.UUID } tests := []struct { name string @@ -74,6 +75,7 @@ func TestGetRole(t *testing.T) { ctx: context.TODO(), addr: testAPIEndpoint, name: "adminTestRole", + id: uuid.Nil, }, want: &apb.GetRoleResponse{ Status: apb.Status_STATUS_OK, @@ -90,6 +92,7 @@ func TestGetRole(t *testing.T) { ctx: context.TODO(), addr: testAPIEndpoint, name: "not role", + id: uuid.Nil, }, want: nil, wantErr: true, @@ -97,7 +100,7 @@ func TestGetRole(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := GetRole(tt.args.ctx, tt.args.addr, tt.args.name) + got, err := GetRole(tt.args.ctx, tt.args.addr, tt.args.name, tt.args.id) if (err != nil) != tt.wantErr { t.Errorf("GetRole() error = %v, wantErr %v", err, tt.wantErr) return diff --git a/controller/api/user.go b/controller/api/user.go index 31d682860..f5f49ea4d 100644 --- a/controller/api/user.go +++ b/controller/api/user.go @@ -6,6 +6,8 @@ import ( apb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/rbac" nbi "code.fbi.h-da.de/danet/gosdn/controller/northbound/client" + + "github.com/google/uuid" ) // CreateUsers creates users with provided data @@ -24,7 +26,7 @@ func CreateUsers(ctx context.Context, addr string, users []*apb.User) (*apb.Crea } //GetUser returns one requested user found by name -func GetUser(ctx context.Context, addr, name string) (*apb.GetUserResponse, error) { +func GetUser(ctx context.Context, addr, name string, uuid uuid.UUID) (*apb.GetUserResponse, error) { userClient, err := nbi.UserClient(addr, dialOptions...) if err != nil { return nil, err @@ -33,6 +35,7 @@ func GetUser(ctx context.Context, addr, name string) (*apb.GetUserResponse, erro r := &apb.GetUserRequest{ Timestamp: time.Now().UnixNano(), Name: name, + Id: uuid.String(), } return userClient.GetUser(ctx, r) diff --git a/controller/api/user_test.go b/controller/api/user_test.go index ab8cf858e..afa2f6dc6 100644 --- a/controller/api/user_test.go +++ b/controller/api/user_test.go @@ -65,6 +65,7 @@ func TestGetUser(t *testing.T) { ctx context.Context addr string name string + id uuid.UUID } tests := []struct { name string @@ -78,6 +79,7 @@ func TestGetUser(t *testing.T) { ctx: context.TODO(), addr: testAPIEndpoint, name: "testAdmin", + id: uuid.Nil, }, want: &apb.GetUserResponse{ Status: apb.Status_STATUS_OK, @@ -94,6 +96,7 @@ func TestGetUser(t *testing.T) { ctx: context.TODO(), addr: testAPIEndpoint, name: "foos", + id: uuid.Nil, }, want: nil, wantErr: true, @@ -102,7 +105,7 @@ func TestGetUser(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := GetUser(tt.args.ctx, tt.args.addr, tt.args.name) + got, err := GetUser(tt.args.ctx, tt.args.addr, tt.args.name, tt.args.id) if (err != nil) != tt.wantErr { t.Errorf("GetUser() error = %v, wantErr %v", err, tt.wantErr) return diff --git a/controller/northbound/server/role.go b/controller/northbound/server/role.go index 4cb05b6e1..4141c6250 100644 --- a/controller/northbound/server/role.go +++ b/controller/northbound/server/role.go @@ -2,6 +2,7 @@ package server import ( "context" + "fmt" "time" apb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/rbac" @@ -59,7 +60,12 @@ func (r Role) GetRole(ctx context.Context, request *apb.GetRoleRequest) (*apb.Ge start := metrics.StartHook(labels, grpcRequestsTotal) defer metrics.FinishHook(labels, start, grpcRequestDurationSecondsTotal, grpcRequestDurationSeconds) - roleData, err := r.roleService.Get(store.Query{Name: request.RoleName}) + roleID, err := uuid.Parse(request.Id) + if err != nil { + return nil, fmt.Errorf("could not parse role uuid") + } + + roleData, err := r.roleService.Get(store.Query{Name: request.RoleName, ID: roleID}) if err != nil { return nil, err } diff --git a/controller/northbound/server/role_test.go b/controller/northbound/server/role_test.go index 1f75f2bc4..75582e3c2 100644 --- a/controller/northbound/server/role_test.go +++ b/controller/northbound/server/role_test.go @@ -90,6 +90,7 @@ func TestRole_GetRole(t *testing.T) { ctx: context.TODO(), request: &apb.GetRoleRequest{ RoleName: "adminTestRole", + Id: uuid.Nil.String(), }, }, want: &apb.GetRoleResponse{ @@ -107,6 +108,7 @@ func TestRole_GetRole(t *testing.T) { ctx: context.TODO(), request: &apb.GetRoleRequest{ RoleName: "not role", + Id: uuid.Nil.String(), }, }, want: nil, diff --git a/controller/northbound/server/user.go b/controller/northbound/server/user.go index 238858637..2e0bfed22 100644 --- a/controller/northbound/server/user.go +++ b/controller/northbound/server/user.go @@ -3,6 +3,7 @@ package server import ( "context" "encoding/base64" + "fmt" "time" apb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/rbac" @@ -82,7 +83,12 @@ func (u User) GetUser(ctx context.Context, request *apb.GetUserRequest) (*apb.Ge start := metrics.StartHook(labels, grpcRequestsTotal) defer metrics.FinishHook(labels, start, grpcRequestDurationSecondsTotal, grpcRequestDurationSeconds) - userData, err := u.userService.Get(store.Query{Name: request.Name}) + userID, err := uuid.Parse(request.Id) + if err != nil { + return nil, fmt.Errorf("could not parse user uuid") + } + + userData, err := u.userService.Get(store.Query{Name: request.Name, ID: userID}) if err != nil { return nil, err } diff --git a/controller/northbound/server/user_test.go b/controller/northbound/server/user_test.go index c84533635..eb8f27fb3 100644 --- a/controller/northbound/server/user_test.go +++ b/controller/northbound/server/user_test.go @@ -93,6 +93,7 @@ func TestUser_GetUser(t *testing.T) { ctx: context.TODO(), request: &apb.GetUserRequest{ Name: "testAdmin", + Id: uuid.Nil.String(), }, }, want: &apb.GetUserResponse{Status: apb.Status_STATUS_OK, @@ -106,6 +107,7 @@ func TestUser_GetUser(t *testing.T) { ctx: context.TODO(), request: &apb.GetUserRequest{ Name: "nope", + Id: uuid.Nil.String(), }, }, want: nil, -- GitLab