From 0277c25cef6fd2507a95afbd8066edaf77581906 Mon Sep 17 00:00:00 2001 From: Nicholas Cristofaro Date: Mon, 25 Nov 2024 07:30:48 -0300 Subject: [PATCH 01/40] dev: Create AllReadAdminRights --- pkg/ttnpb/rights.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pkg/ttnpb/rights.go b/pkg/ttnpb/rights.go index b77fa4aca5..6827b6b980 100644 --- a/pkg/ttnpb/rights.go +++ b/pkg/ttnpb/rights.go @@ -28,6 +28,7 @@ var ( AllGatewayRights = &Rights{} AllOrganizationRights = &Rights{} AllClusterRights = &Rights{} + AllReadAdminRights = &Rights{} AllAdminRights = &Rights{} AllRights = &Rights{} ) @@ -55,6 +56,12 @@ func init() { if strings.HasSuffix(k, "_READ") || strings.HasSuffix(k, "_INFO") { AllClusterRights.Rights = append(AllClusterRights.Rights, Right(v)) } + if strings.HasSuffix(k, "_READ") || + strings.HasSuffix(k, "_INFO") || + strings.HasSuffix(k, "_LIST") || + strings.HasSuffix(k, "_GET") { + AllReadAdminRights.Rights = append(AllReadAdminRights.Rights, Right(v)) + } if !strings.HasSuffix(k, "_KEYS") && !strings.HasSuffix(k, "_ALL") { AllAdminRights.Rights = append(AllAdminRights.Rights, Right(v)) } From 0b8bd4018ab8b53d790bb0f57bf02e8be6160cea Mon Sep 17 00:00:00 2001 From: Nicholas Cristofaro Date: Mon, 25 Nov 2024 07:34:45 -0300 Subject: [PATCH 02/40] api: Add universal_rights to user proto definition --- api/ttn/lorawan/v3/api.md | 3 +- api/ttn/lorawan/v3/api.swagger.json | 20 +- api/ttn/lorawan/v3/user.proto | 6 +- pkg/ttnpb/user.pb.go | 822 ++++++++++++++------------- pkg/ttnpb/user.pb.paths.fm.go | 4 + pkg/ttnpb/user.pb.setters.fm.go | 9 + pkg/ttnpb/user.pb.validate.go | 2 + pkg/ttnpb/user_flags.pb.go | 20 + pkg/ttnpb/user_json.pb.go | 22 + sdk/js/generated/api-definition.json | 4 + sdk/js/generated/api.json | 14 +- 11 files changed, 515 insertions(+), 411 deletions(-) diff --git a/api/ttn/lorawan/v3/api.md b/api/ttn/lorawan/v3/api.md index b70b84c1a2..be45688bd1 100644 --- a/api/ttn/lorawan/v3/api.md +++ b/api/ttn/lorawan/v3/api.md @@ -11803,7 +11803,8 @@ User is the message that defines a user on the network. | `temporary_password_expires_at` | [`google.protobuf.Timestamp`](#google.protobuf.Timestamp) | | | | `profile_picture` | [`Picture`](#ttn.lorawan.v3.Picture) | | A profile picture for the user. This information is public and can be seen by any authenticated user in the network. | | `console_preferences` | [`UserConsolePreferences`](#ttn.lorawan.v3.UserConsolePreferences) | | Console preferences contains the user's preferences regarding the behavior of the Console. | -| `email_notification_preferences` | [`EmailNotificationPreferences`](#ttn.lorawan.v3.EmailNotificationPreferences) | | next: 27 | +| `email_notification_preferences` | [`EmailNotificationPreferences`](#ttn.lorawan.v3.EmailNotificationPreferences) | | | +| `universal_rights` | [`Right`](#ttn.lorawan.v3.Right) | repeated | Universal rights are capable of restricting the user's interactions with the API, be it an admin or not. | #### Field Rules diff --git a/api/ttn/lorawan/v3/api.swagger.json b/api/ttn/lorawan/v3/api.swagger.json index 2749116e47..d2b129248c 100644 --- a/api/ttn/lorawan/v3/api.swagger.json +++ b/api/ttn/lorawan/v3/api.swagger.json @@ -29654,8 +29654,14 @@ "description": "Console preferences contains the user's preferences regarding the behavior of the Console." }, "email_notification_preferences": { - "$ref": "#/definitions/v3EmailNotificationPreferences", - "title": "next: 27" + "$ref": "#/definitions/v3EmailNotificationPreferences" + }, + "universal_rights": { + "type": "array", + "items": { + "$ref": "#/definitions/v3Right" + }, + "description": "Universal rights are capable of restricting the user's interactions with the API, be it an admin or not." } }, "description": "User is the message that defines a user on the network." @@ -29920,8 +29926,14 @@ "description": "Console preferences contains the user's preferences regarding the behavior of the Console." }, "email_notification_preferences": { - "$ref": "#/definitions/v3EmailNotificationPreferences", - "title": "next: 27" + "$ref": "#/definitions/v3EmailNotificationPreferences" + }, + "universal_rights": { + "type": "array", + "items": { + "$ref": "#/definitions/v3Right" + }, + "description": "Universal rights are capable of restricting the user's interactions with the API, be it an admin or not." } }, "description": "User is the message that defines a user on the network." diff --git a/api/ttn/lorawan/v3/user.proto b/api/ttn/lorawan/v3/user.proto index d20b242a91..7663cb151a 100644 --- a/api/ttn/lorawan/v3/user.proto +++ b/api/ttn/lorawan/v3/user.proto @@ -318,7 +318,11 @@ message User { UserConsolePreferences console_preferences = 25; EmailNotificationPreferences email_notification_preferences = 26; - // next: 27 + + // Universal rights are capable of restricting the user's interactions with the API, be it an admin or not. + repeated Right universal_rights = 27; + + // next: 28 } message Users { diff --git a/pkg/ttnpb/user.pb.go b/pkg/ttnpb/user.pb.go index e6ce9bd1ff..7c665595e2 100644 --- a/pkg/ttnpb/user.pb.go +++ b/pkg/ttnpb/user.pb.go @@ -368,7 +368,9 @@ type User struct { ProfilePicture *Picture `protobuf:"bytes,18,opt,name=profile_picture,json=profilePicture,proto3" json:"profile_picture,omitempty"` // Console preferences contains the user's preferences regarding the behavior of the Console. ConsolePreferences *UserConsolePreferences `protobuf:"bytes,25,opt,name=console_preferences,json=consolePreferences,proto3" json:"console_preferences,omitempty"` - EmailNotificationPreferences *EmailNotificationPreferences `protobuf:"bytes,26,opt,name=email_notification_preferences,json=emailNotificationPreferences,proto3" json:"email_notification_preferences,omitempty"` // next: 27 + EmailNotificationPreferences *EmailNotificationPreferences `protobuf:"bytes,26,opt,name=email_notification_preferences,json=emailNotificationPreferences,proto3" json:"email_notification_preferences,omitempty"` + // Universal rights are capable of restricting the user's interactions with the API, be it an admin or not. + UniversalRights []Right `protobuf:"varint,27,rep,packed,name=universal_rights,json=universalRights,proto3,enum=ttn.lorawan.v3.Right" json:"universal_rights,omitempty"` } func (x *User) Reset() { @@ -558,6 +560,13 @@ func (x *User) GetEmailNotificationPreferences() *EmailNotificationPreferences { return nil } +func (x *User) GetUniversalRights() []Right { + if x != nil { + return x.UniversalRights + } + return nil +} + type Users struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2816,7 +2825,7 @@ var file_ttn_lorawan_v3_user_proto_rawDesc = []byte{ 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x54, 0x75, 0x74, 0x6f, 0x72, 0x69, 0x61, 0x6c, 0x42, 0x0f, 0xfa, 0x42, 0x0c, 0x92, 0x01, 0x09, 0x18, 0x01, 0x22, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x04, 0x73, 0x65, 0x65, 0x6e, 0x3a, 0x08, - 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x01, 0x22, 0xc8, 0x0d, 0x0a, 0x04, 0x55, 0x73, 0x65, + 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x01, 0x22, 0x8a, 0x0e, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x43, 0x0a, 0x03, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x42, @@ -2914,368 +2923,372 @@ var file_ttn_lorawan_v3_user_proto_rawDesc = []byte{ 0x2e, 0x76, 0x33, 0x2e, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x1c, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x1a, 0x3d, - 0x0a, 0x0f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 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, 0x3a, 0x08, 0xf2, - 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x01, 0x4a, 0x04, 0x08, 0x15, 0x10, 0x16, 0x4a, 0x04, 0x08, - 0x16, 0x10, 0x17, 0x4a, 0x04, 0x08, 0x17, 0x10, 0x18, 0x4a, 0x04, 0x08, 0x18, 0x10, 0x19, 0x52, - 0x11, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6c, 0x69, 0x6d, - 0x69, 0x74, 0x52, 0x0c, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, - 0x52, 0x0d, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x52, - 0x12, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6c, 0x69, - 0x6d, 0x69, 0x74, 0x22, 0x33, 0x0a, 0x05, 0x55, 0x73, 0x65, 0x72, 0x73, 0x12, 0x2a, 0x0a, 0x05, - 0x75, 0x73, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x74, - 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x73, 0x65, - 0x72, 0x52, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x22, 0x91, 0x01, 0x0a, 0x0e, 0x47, 0x65, 0x74, - 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x44, 0x0a, 0x08, 0x75, - 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, + 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x40, + 0x0a, 0x10, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x61, 0x6c, 0x5f, 0x72, 0x69, 0x67, 0x68, + 0x74, 0x73, 0x18, 0x1b, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, + 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x52, 0x69, 0x67, 0x68, 0x74, 0x52, + 0x0f, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x61, 0x6c, 0x52, 0x69, 0x67, 0x68, 0x74, 0x73, + 0x1a, 0x3d, 0x0a, 0x0f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 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, 0x3a, + 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x01, 0x4a, 0x04, 0x08, 0x15, 0x10, 0x16, 0x4a, + 0x04, 0x08, 0x16, 0x10, 0x17, 0x4a, 0x04, 0x08, 0x17, 0x10, 0x18, 0x4a, 0x04, 0x08, 0x18, 0x10, + 0x19, 0x52, 0x11, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6c, + 0x69, 0x6d, 0x69, 0x74, 0x52, 0x0c, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x6c, 0x69, 0x6d, + 0x69, 0x74, 0x52, 0x0d, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x6c, 0x69, 0x6d, 0x69, + 0x74, 0x52, 0x12, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, + 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x22, 0x33, 0x0a, 0x05, 0x55, 0x73, 0x65, 0x72, 0x73, 0x12, 0x2a, + 0x0a, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x55, - 0x73, 0x65, 0x72, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x42, 0x08, - 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x07, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, - 0x73, 0x12, 0x39, 0x0a, 0x0a, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, - 0x6b, 0x52, 0x09, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x22, 0xce, 0x02, 0x0a, - 0x10, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, - 0x6b, 0x52, 0x09, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x12, 0xa6, 0x01, 0x0a, - 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x8f, 0x01, 0xfa, - 0x42, 0x8b, 0x01, 0x72, 0x88, 0x01, 0x52, 0x00, 0x52, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, - 0x64, 0x52, 0x08, 0x2d, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x52, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x52, 0x05, 0x2d, 0x6e, 0x61, 0x6d, 0x65, 0x52, 0x15, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, - 0x79, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, - 0x16, 0x2d, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x5f, - 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x52, 0x06, - 0x2d, 0x73, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x52, 0x06, 0x2d, - 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, - 0x74, 0x52, 0x0b, 0x2d, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x52, 0x05, - 0x6f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x1e, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0d, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x2a, 0x03, 0x18, 0xe8, 0x07, 0x52, 0x05, - 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x0d, 0x52, 0x04, 0x70, 0x61, 0x67, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x64, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x64, 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x01, 0x22, 0x72, 0x0a, - 0x11, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x32, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x14, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, - 0x33, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, - 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x29, 0x0a, 0x10, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0f, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, - 0x6e, 0x22, 0x82, 0x01, 0x0a, 0x11, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, - 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x42, 0x08, 0xfa, 0x42, 0x05, - 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x39, 0x0a, 0x0a, 0x66, - 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x52, 0x09, 0x66, 0x69, 0x65, - 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x22, 0x66, 0x0a, 0x1e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x54, 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, 0x72, 0x79, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, - 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x44, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, - 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x74, 0x6e, - 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x73, 0x65, 0x72, - 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, - 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x07, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x73, 0x22, 0xc5, - 0x01, 0x0a, 0x19, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x50, 0x61, 0x73, - 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x44, 0x0a, 0x08, - 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, - 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, - 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x42, - 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x07, 0x75, 0x73, 0x65, 0x72, 0x49, - 0x64, 0x73, 0x12, 0x1a, 0x0a, 0x03, 0x6e, 0x65, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, - 0x08, 0xfa, 0x42, 0x05, 0x72, 0x03, 0x18, 0xe8, 0x07, 0x52, 0x03, 0x6e, 0x65, 0x77, 0x12, 0x1a, - 0x0a, 0x03, 0x6f, 0x6c, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xfa, 0x42, 0x05, - 0x72, 0x03, 0x18, 0xe8, 0x07, 0x52, 0x03, 0x6f, 0x6c, 0x64, 0x12, 0x2a, 0x0a, 0x11, 0x72, 0x65, - 0x76, 0x6f, 0x6b, 0x65, 0x5f, 0x61, 0x6c, 0x6c, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x72, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x41, 0x6c, 0x6c, - 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0x93, 0x02, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x55, - 0x73, 0x65, 0x72, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x44, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, - 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, - 0x69, 0x65, 0x72, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x07, - 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x73, 0x12, 0x75, 0x0a, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x5f, 0xfa, 0x42, 0x5c, 0x72, 0x5a, 0x52, 0x00, 0x52, - 0x0a, 0x61, 0x70, 0x69, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x52, 0x0b, 0x2d, 0x61, 0x70, - 0x69, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x52, 0x05, - 0x2d, 0x6e, 0x61, 0x6d, 0x65, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, - 0x74, 0x52, 0x0b, 0x2d, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x52, 0x0a, - 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x61, 0x74, 0x52, 0x0b, 0x2d, 0x65, 0x78, 0x70, - 0x69, 0x72, 0x65, 0x73, 0x5f, 0x61, 0x74, 0x52, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x1e, - 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x08, 0xfa, - 0x42, 0x05, 0x2a, 0x03, 0x18, 0xe8, 0x07, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x12, - 0x0a, 0x04, 0x70, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x70, 0x61, - 0x67, 0x65, 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x00, 0x10, 0x01, 0x22, 0x73, 0x0a, 0x14, - 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x44, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, - 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x65, 0x6e, - 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, - 0x01, 0x52, 0x07, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x73, 0x12, 0x15, 0x0a, 0x06, 0x6b, 0x65, - 0x79, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6b, 0x65, 0x79, 0x49, - 0x64, 0x22, 0x83, 0x02, 0x0a, 0x17, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, - 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x44, 0x0a, + 0x73, 0x65, 0x72, 0x52, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x22, 0x91, 0x01, 0x0a, 0x0e, 0x47, + 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x44, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x07, 0x75, 0x73, 0x65, 0x72, - 0x49, 0x64, 0x73, 0x12, 0x1b, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x18, 0x32, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x12, 0x40, 0x0a, 0x06, 0x72, 0x69, 0x67, 0x68, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0e, - 0x32, 0x15, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, - 0x33, 0x2e, 0x52, 0x69, 0x67, 0x68, 0x74, 0x42, 0x11, 0xfa, 0x42, 0x0e, 0x92, 0x01, 0x0b, 0x08, - 0x01, 0x18, 0x01, 0x22, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x06, 0x72, 0x69, 0x67, 0x68, - 0x74, 0x73, 0x12, 0x43, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x61, 0x74, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x42, 0x08, 0xfa, 0x42, 0x05, 0xb2, 0x01, 0x02, 0x40, 0x01, 0x52, 0x09, 0x65, 0x78, - 0x70, 0x69, 0x72, 0x65, 0x73, 0x41, 0x74, 0x22, 0xd5, 0x01, 0x0a, 0x17, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x44, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, - 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x65, 0x6e, 0x74, - 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, - 0x52, 0x07, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x73, 0x12, 0x39, 0x0a, 0x07, 0x61, 0x70, 0x69, - 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x74, 0x74, 0x6e, - 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x50, 0x49, 0x4b, - 0x65, 0x79, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x06, 0x61, 0x70, - 0x69, 0x4b, 0x65, 0x79, 0x12, 0x39, 0x0a, 0x0a, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6d, 0x61, - 0x73, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, - 0x4d, 0x61, 0x73, 0x6b, 0x52, 0x09, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x22, - 0x76, 0x0a, 0x17, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x41, 0x50, 0x49, - 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x44, 0x0a, 0x08, 0x75, 0x73, + 0x49, 0x64, 0x73, 0x12, 0x39, 0x0a, 0x0a, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6d, 0x61, 0x73, + 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, + 0x61, 0x73, 0x6b, 0x52, 0x09, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x22, 0xce, + 0x02, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6d, 0x61, 0x73, + 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, + 0x61, 0x73, 0x6b, 0x52, 0x09, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x12, 0xa6, + 0x01, 0x0a, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x8f, + 0x01, 0xfa, 0x42, 0x8b, 0x01, 0x72, 0x88, 0x01, 0x52, 0x00, 0x52, 0x07, 0x75, 0x73, 0x65, 0x72, + 0x5f, 0x69, 0x64, 0x52, 0x08, 0x2d, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x52, 0x05, 0x2d, 0x6e, 0x61, 0x6d, 0x65, 0x52, 0x15, 0x70, 0x72, 0x69, 0x6d, + 0x61, 0x72, 0x79, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x52, 0x16, 0x2d, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x65, 0x6d, 0x61, 0x69, + 0x6c, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, + 0x52, 0x06, 0x2d, 0x73, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x52, + 0x06, 0x2d, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, + 0x5f, 0x61, 0x74, 0x52, 0x0b, 0x2d, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, + 0x52, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x1e, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x2a, 0x03, 0x18, 0xe8, 0x07, + 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x67, 0x65, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x70, 0x61, 0x67, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x64, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x64, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x64, 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x01, 0x22, + 0x72, 0x0a, 0x11, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, + 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, + 0x10, 0x01, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x29, 0x0a, 0x10, 0x69, 0x6e, 0x76, 0x69, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0f, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x6f, + 0x6b, 0x65, 0x6e, 0x22, 0x82, 0x01, 0x0a, 0x11, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, + 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x04, 0x75, 0x73, 0x65, + 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, + 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x42, 0x08, 0xfa, + 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x39, 0x0a, + 0x0a, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x52, 0x09, 0x66, + 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x22, 0x66, 0x0a, 0x1e, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x54, 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, 0x72, 0x79, 0x50, 0x61, 0x73, 0x73, 0x77, + 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x44, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x07, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x73, - 0x12, 0x15, 0x0a, 0x06, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x6b, 0x65, 0x79, 0x49, 0x64, 0x22, 0xf1, 0x02, 0x0a, 0x0a, 0x49, 0x6e, 0x76, 0x69, - 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x60, 0x01, 0x52, 0x05, - 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x39, 0x0a, 0x0a, 0x65, - 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x65, 0x78, 0x70, - 0x69, 0x72, 0x65, 0x73, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x64, 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, - 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x3b, 0x0a, 0x0b, - 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x61, - 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x40, 0x0a, 0x0b, 0x61, 0x63, 0x63, - 0x65, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, - 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, - 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x52, - 0x0a, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x42, 0x79, 0x22, 0x4c, 0x0a, 0x16, 0x4c, - 0x69, 0x73, 0x74, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1e, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0d, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x2a, 0x03, 0x18, 0xe8, 0x07, 0x52, 0x05, - 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0d, 0x52, 0x04, 0x70, 0x61, 0x67, 0x65, 0x22, 0x4b, 0x0a, 0x0b, 0x49, 0x6e, 0x76, - 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x3c, 0x0a, 0x0b, 0x69, 0x6e, 0x76, 0x69, - 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, - 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x49, - 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x69, 0x6e, 0x76, 0x69, 0x74, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x36, 0x0a, 0x15, 0x53, 0x65, 0x6e, 0x64, 0x49, 0x6e, - 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x1d, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, - 0xfa, 0x42, 0x04, 0x72, 0x02, 0x60, 0x01, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x22, 0x38, - 0x0a, 0x17, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x05, 0x65, 0x6d, 0x61, - 0x69, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x60, - 0x01, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x22, 0x86, 0x01, 0x0a, 0x16, 0x55, 0x73, 0x65, - 0x72, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, - 0x65, 0x72, 0x73, 0x12, 0x44, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, + 0x22, 0xc5, 0x01, 0x0a, 0x19, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x50, + 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x44, + 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1f, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, + 0x33, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, + 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x07, 0x75, 0x73, 0x65, + 0x72, 0x49, 0x64, 0x73, 0x12, 0x1a, 0x0a, 0x03, 0x6e, 0x65, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x72, 0x03, 0x18, 0xe8, 0x07, 0x52, 0x03, 0x6e, 0x65, 0x77, + 0x12, 0x1a, 0x0a, 0x03, 0x6f, 0x6c, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xfa, + 0x42, 0x05, 0x72, 0x03, 0x18, 0xe8, 0x07, 0x52, 0x03, 0x6f, 0x6c, 0x64, 0x12, 0x2a, 0x0a, 0x11, + 0x72, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x5f, 0x61, 0x6c, 0x6c, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x72, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x41, + 0x6c, 0x6c, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0x93, 0x02, 0x0a, 0x16, 0x4c, 0x69, 0x73, + 0x74, 0x55, 0x73, 0x65, 0x72, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x44, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, - 0x52, 0x07, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x73, 0x12, 0x26, 0x0a, 0x0a, 0x73, 0x65, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, - 0x42, 0x04, 0x72, 0x02, 0x18, 0x40, 0x52, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, - 0x64, 0x22, 0xd3, 0x02, 0x0a, 0x0b, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x12, 0x44, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, - 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, - 0x69, 0x65, 0x72, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x07, - 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x73, 0x12, 0x26, 0x0a, 0x0a, 0x73, 0x65, 0x73, 0x73, 0x69, - 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, - 0x72, 0x02, 0x18, 0x40, 0x52, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, - 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, - 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, - 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x41, 0x74, - 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x65, 0x63, 0x72, - 0x65, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x22, 0x47, 0x0a, 0x0c, 0x55, 0x73, 0x65, 0x72, 0x53, - 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x37, 0x0a, 0x08, 0x73, 0x65, 0x73, 0x73, 0x69, - 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x74, 0x6e, 0x2e, - 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x53, - 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, - 0x22, 0xcb, 0x01, 0x0a, 0x17, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x44, 0x0a, 0x08, + 0x52, 0x07, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x73, 0x12, 0x75, 0x0a, 0x05, 0x6f, 0x72, 0x64, + 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x5f, 0xfa, 0x42, 0x5c, 0x72, 0x5a, 0x52, + 0x00, 0x52, 0x0a, 0x61, 0x70, 0x69, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x52, 0x0b, 0x2d, + 0x61, 0x70, 0x69, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x52, 0x05, 0x2d, 0x6e, 0x61, 0x6d, 0x65, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, + 0x5f, 0x61, 0x74, 0x52, 0x0b, 0x2d, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, + 0x52, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x61, 0x74, 0x52, 0x0b, 0x2d, 0x65, + 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x61, 0x74, 0x52, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, + 0x12, 0x1e, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x42, + 0x08, 0xfa, 0x42, 0x05, 0x2a, 0x03, 0x18, 0xe8, 0x07, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, + 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, + 0x70, 0x61, 0x67, 0x65, 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x00, 0x10, 0x01, 0x22, 0x73, + 0x0a, 0x14, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x44, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, + 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, + 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, + 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, + 0x02, 0x10, 0x01, 0x52, 0x07, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x73, 0x12, 0x15, 0x0a, 0x06, + 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6b, 0x65, + 0x79, 0x49, 0x64, 0x22, 0x83, 0x02, 0x0a, 0x17, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, + 0x65, 0x72, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x44, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, + 0x76, 0x33, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, + 0x72, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x07, 0x75, 0x73, + 0x65, 0x72, 0x49, 0x64, 0x73, 0x12, 0x1b, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x18, 0x32, 0x52, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x40, 0x0a, 0x06, 0x72, 0x69, 0x67, 0x68, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, + 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, + 0x2e, 0x76, 0x33, 0x2e, 0x52, 0x69, 0x67, 0x68, 0x74, 0x42, 0x11, 0xfa, 0x42, 0x0e, 0x92, 0x01, + 0x0b, 0x08, 0x01, 0x18, 0x01, 0x22, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x06, 0x72, 0x69, + 0x67, 0x68, 0x74, 0x73, 0x12, 0x43, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x5f, + 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x42, 0x08, 0xfa, 0x42, 0x05, 0xb2, 0x01, 0x02, 0x40, 0x01, 0x52, 0x09, + 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x41, 0x74, 0x22, 0xd5, 0x01, 0x0a, 0x17, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x44, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, + 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, + 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x65, + 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, + 0x10, 0x01, 0x52, 0x07, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x73, 0x12, 0x39, 0x0a, 0x07, 0x61, + 0x70, 0x69, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x74, + 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x50, + 0x49, 0x4b, 0x65, 0x79, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x06, + 0x61, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x12, 0x39, 0x0a, 0x0a, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, + 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, + 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x52, 0x09, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, + 0x6b, 0x22, 0x76, 0x0a, 0x17, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x41, + 0x50, 0x49, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x44, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x07, 0x75, 0x73, 0x65, 0x72, 0x49, - 0x64, 0x73, 0x12, 0x36, 0x0a, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x42, 0x20, 0xfa, 0x42, 0x1d, 0x72, 0x1b, 0x52, 0x00, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x52, 0x0b, 0x2d, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, - 0x5f, 0x61, 0x74, 0x52, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x1e, 0x0a, 0x05, 0x6c, 0x69, - 0x6d, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x2a, 0x03, - 0x18, 0xe8, 0x07, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, - 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x70, 0x61, 0x67, 0x65, 0x22, 0xad, - 0x02, 0x0a, 0x0a, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x44, 0x0a, - 0x08, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1f, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, - 0x2e, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, - 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x07, 0x75, 0x73, 0x65, 0x72, - 0x49, 0x64, 0x73, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, - 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, - 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, - 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x65, 0x78, 0x70, - 0x69, 0x72, 0x65, 0x73, 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x65, 0x78, 0x70, 0x69, 0x72, - 0x65, 0x73, 0x41, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x73, - 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x75, 0x73, 0x65, 0x64, 0x22, 0x7e, - 0x0a, 0x17, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x54, 0x6f, 0x6b, - 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x44, 0x0a, 0x08, 0x75, 0x73, 0x65, - 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x74, - 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x73, 0x65, - 0x72, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x42, 0x08, 0xfa, 0x42, - 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x07, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x73, 0x12, - 0x1d, 0x0a, 0x0a, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x09, 0x73, 0x6b, 0x69, 0x70, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x22, 0x30, - 0x0a, 0x18, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x54, 0x6f, 0x6b, - 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, - 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, - 0x22, 0xdb, 0x01, 0x0a, 0x0c, 0x55, 0x73, 0x65, 0x72, 0x42, 0x6f, 0x6f, 0x6b, 0x6d, 0x61, 0x72, - 0x6b, 0x12, 0x44, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, - 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, - 0x69, 0x65, 0x72, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x07, - 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x73, 0x12, 0x4a, 0x0a, 0x0a, 0x65, 0x6e, 0x74, 0x69, 0x74, - 0x79, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x74, 0x74, - 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x45, 0x6e, 0x74, - 0x69, 0x74, 0x79, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x42, 0x08, - 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x09, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, - 0x49, 0x64, 0x73, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, - 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x64, 0x73, 0x12, 0x15, 0x0a, 0x06, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x6b, 0x65, 0x79, 0x49, 0x64, 0x22, 0xf1, 0x02, 0x0a, 0x0a, 0x49, 0x6e, + 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, + 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x60, 0x01, + 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x39, 0x0a, + 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x65, + 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, + 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x22, 0x4b, - 0x0a, 0x0d, 0x55, 0x73, 0x65, 0x72, 0x42, 0x6f, 0x6f, 0x6b, 0x6d, 0x61, 0x72, 0x6b, 0x73, 0x12, - 0x3a, 0x0a, 0x09, 0x62, 0x6f, 0x6f, 0x6b, 0x6d, 0x61, 0x72, 0x6b, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, - 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x42, 0x6f, 0x6f, 0x6b, 0x6d, 0x61, 0x72, 0x6b, - 0x52, 0x09, 0x62, 0x6f, 0x6f, 0x6b, 0x6d, 0x61, 0x72, 0x6b, 0x73, 0x22, 0xad, 0x01, 0x0a, 0x19, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x42, 0x6f, 0x6f, 0x6b, 0x6d, 0x61, - 0x72, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x44, 0x0a, 0x08, 0x75, 0x73, 0x65, - 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x74, + 0x61, 0x6d, 0x70, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x3b, + 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, + 0x0a, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x40, 0x0a, 0x0b, 0x61, + 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1f, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, + 0x33, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, + 0x73, 0x52, 0x0a, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x42, 0x79, 0x22, 0x4c, 0x0a, + 0x16, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1e, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x2a, 0x03, 0x18, 0xe8, 0x07, + 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x67, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x70, 0x61, 0x67, 0x65, 0x22, 0x4b, 0x0a, 0x0b, 0x49, + 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x3c, 0x0a, 0x0b, 0x69, 0x6e, + 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x1a, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, + 0x2e, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x69, 0x6e, 0x76, + 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x36, 0x0a, 0x15, 0x53, 0x65, 0x6e, 0x64, + 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x1d, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x60, 0x01, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, + 0x22, 0x38, 0x0a, 0x17, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x05, 0x65, + 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, + 0x02, 0x60, 0x01, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x22, 0x86, 0x01, 0x0a, 0x16, 0x55, + 0x73, 0x65, 0x72, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, + 0x66, 0x69, 0x65, 0x72, 0x73, 0x12, 0x44, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, + 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, + 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x65, + 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, + 0x10, 0x01, 0x52, 0x07, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x73, 0x12, 0x26, 0x0a, 0x0a, 0x73, + 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x18, 0x40, 0x52, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x49, 0x64, 0x22, 0xd3, 0x02, 0x0a, 0x0b, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x12, 0x44, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, + 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, + 0x52, 0x07, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x73, 0x12, 0x26, 0x0a, 0x0a, 0x73, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, + 0x42, 0x04, 0x72, 0x02, 0x18, 0x40, 0x52, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, + 0x64, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, + 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x75, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, + 0x65, 0x73, 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, + 0x41, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x65, + 0x63, 0x72, 0x65, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x65, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x22, 0x47, 0x0a, 0x0c, 0x55, 0x73, 0x65, + 0x72, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x37, 0x0a, 0x08, 0x73, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x73, 0x65, - 0x72, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x42, 0x08, 0xfa, 0x42, - 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x07, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x73, 0x12, - 0x4a, 0x0a, 0x0a, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, - 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x64, 0x65, 0x6e, 0x74, + 0x72, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x73, 0x22, 0xcb, 0x01, 0x0a, 0x17, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x53, + 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x44, + 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1f, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, + 0x33, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, + 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x07, 0x75, 0x73, 0x65, + 0x72, 0x49, 0x64, 0x73, 0x12, 0x36, 0x0a, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x42, 0x20, 0xfa, 0x42, 0x1d, 0x72, 0x1b, 0x52, 0x00, 0x52, 0x0a, 0x63, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x52, 0x0b, 0x2d, 0x63, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x64, 0x5f, 0x61, 0x74, 0x52, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x1e, 0x0a, 0x05, + 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x08, 0xfa, 0x42, 0x05, + 0x2a, 0x03, 0x18, 0xe8, 0x07, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x12, 0x0a, 0x04, + 0x70, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x70, 0x61, 0x67, 0x65, + 0x22, 0xad, 0x02, 0x0a, 0x0a, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, + 0x44, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, + 0x76, 0x33, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, + 0x72, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x07, 0x75, 0x73, + 0x65, 0x72, 0x49, 0x64, 0x73, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, + 0x5f, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, + 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x65, + 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x65, 0x78, 0x70, + 0x69, 0x72, 0x65, 0x73, 0x41, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x12, 0x0a, 0x04, + 0x75, 0x73, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x75, 0x73, 0x65, 0x64, + 0x22, 0x7e, 0x0a, 0x17, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x54, + 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x44, 0x0a, 0x08, 0x75, + 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, + 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x55, + 0x73, 0x65, 0x72, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x42, 0x08, + 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x07, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, + 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x73, 0x6b, 0x69, 0x70, 0x45, 0x6d, 0x61, 0x69, 0x6c, + 0x22, 0x30, 0x0a, 0x18, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x54, + 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, + 0x65, 0x6e, 0x22, 0xdb, 0x01, 0x0a, 0x0c, 0x55, 0x73, 0x65, 0x72, 0x42, 0x6f, 0x6f, 0x6b, 0x6d, + 0x61, 0x72, 0x6b, 0x12, 0x44, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, + 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, - 0x52, 0x09, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x64, 0x73, 0x22, 0xa4, 0x03, 0x0a, 0x18, - 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x42, 0x6f, 0x6f, 0x6b, 0x6d, 0x61, 0x72, 0x6b, + 0x52, 0x07, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x73, 0x12, 0x4a, 0x0a, 0x0a, 0x65, 0x6e, 0x74, + 0x69, 0x74, 0x79, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, + 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x45, + 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, + 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x09, 0x65, 0x6e, 0x74, 0x69, + 0x74, 0x79, 0x49, 0x64, 0x73, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, + 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, + 0x22, 0x4b, 0x0a, 0x0d, 0x55, 0x73, 0x65, 0x72, 0x42, 0x6f, 0x6f, 0x6b, 0x6d, 0x61, 0x72, 0x6b, + 0x73, 0x12, 0x3a, 0x0a, 0x09, 0x62, 0x6f, 0x6f, 0x6b, 0x6d, 0x61, 0x72, 0x6b, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, + 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x42, 0x6f, 0x6f, 0x6b, 0x6d, 0x61, + 0x72, 0x6b, 0x52, 0x09, 0x62, 0x6f, 0x6f, 0x6b, 0x6d, 0x61, 0x72, 0x6b, 0x73, 0x22, 0xad, 0x01, + 0x0a, 0x19, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x42, 0x6f, 0x6f, 0x6b, + 0x6d, 0x61, 0x72, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x44, 0x0a, 0x08, 0x75, + 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, + 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x55, + 0x73, 0x65, 0x72, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x42, 0x08, + 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x07, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, + 0x73, 0x12, 0x4a, 0x0a, 0x0a, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x64, 0x73, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, + 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x64, 0x65, + 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, + 0x10, 0x01, 0x52, 0x09, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x64, 0x73, 0x22, 0xa4, 0x03, + 0x0a, 0x18, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x42, 0x6f, 0x6f, 0x6b, 0x6d, 0x61, + 0x72, 0x6b, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x44, 0x0a, 0x08, 0x75, 0x73, + 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, + 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x73, + 0x65, 0x72, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x42, 0x08, 0xfa, + 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x07, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x73, + 0x12, 0x1e, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x42, + 0x08, 0xfa, 0x42, 0x05, 0x2a, 0x03, 0x18, 0xe8, 0x07, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, + 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, + 0x70, 0x61, 0x67, 0x65, 0x12, 0x7b, 0x0a, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x42, 0x65, 0xfa, 0x42, 0x62, 0x72, 0x60, 0x52, 0x00, 0x52, 0x07, 0x75, 0x73, + 0x65, 0x72, 0x5f, 0x69, 0x64, 0x52, 0x08, 0x2d, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x52, + 0x0b, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x52, 0x0c, 0x2d, 0x65, + 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x52, 0x09, 0x65, 0x6e, 0x74, 0x69, + 0x74, 0x79, 0x5f, 0x69, 0x64, 0x52, 0x0a, 0x2d, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x69, + 0x64, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x52, 0x0b, 0x2d, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x52, 0x05, 0x6f, 0x72, 0x64, 0x65, + 0x72, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x07, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x12, 0x6d, 0x0a, 0x0c, 0x65, + 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, + 0x09, 0x42, 0x4a, 0xfa, 0x42, 0x47, 0x92, 0x01, 0x44, 0x18, 0x01, 0x22, 0x40, 0x72, 0x3e, 0x52, + 0x0b, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x52, 0x0a, 0x65, 0x6e, 0x64, 0x20, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x52, 0x07, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x52, 0x0c, 0x6f, 0x72, 0x67, 0x61, 0x6e, + 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x52, 0x0b, 0x65, + 0x6e, 0x74, 0x69, 0x74, 0x79, 0x54, 0x79, 0x70, 0x65, 0x73, 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, + 0x08, 0x00, 0x10, 0x01, 0x22, 0xad, 0x01, 0x0a, 0x19, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, + 0x73, 0x65, 0x72, 0x42, 0x6f, 0x6f, 0x6b, 0x6d, 0x61, 0x72, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x44, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, + 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, + 0x66, 0x69, 0x65, 0x72, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, + 0x07, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x73, 0x12, 0x4a, 0x0a, 0x0a, 0x65, 0x6e, 0x74, 0x69, + 0x74, 0x79, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x74, + 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x45, 0x6e, + 0x74, 0x69, 0x74, 0x79, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x42, + 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x09, 0x65, 0x6e, 0x74, 0x69, 0x74, + 0x79, 0x49, 0x64, 0x73, 0x22, 0xb5, 0x01, 0x0a, 0x1f, 0x42, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x42, 0x6f, 0x6f, 0x6b, 0x6d, 0x61, 0x72, 0x6b, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x44, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, - 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x07, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x73, 0x12, 0x1e, - 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x08, 0xfa, - 0x42, 0x05, 0x2a, 0x03, 0x18, 0xe8, 0x07, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x12, - 0x0a, 0x04, 0x70, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x70, 0x61, - 0x67, 0x65, 0x12, 0x7b, 0x0a, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x09, 0x42, 0x65, 0xfa, 0x42, 0x62, 0x72, 0x60, 0x52, 0x00, 0x52, 0x07, 0x75, 0x73, 0x65, 0x72, - 0x5f, 0x69, 0x64, 0x52, 0x08, 0x2d, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x52, 0x0b, 0x65, - 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x52, 0x0c, 0x2d, 0x65, 0x6e, 0x74, - 0x69, 0x74, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x52, 0x09, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, - 0x5f, 0x69, 0x64, 0x52, 0x0a, 0x2d, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x64, 0x52, - 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x52, 0x0b, 0x2d, 0x63, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x52, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x12, - 0x18, 0x0a, 0x07, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x07, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x12, 0x6d, 0x0a, 0x0c, 0x65, 0x6e, 0x74, - 0x69, 0x74, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x42, - 0x4a, 0xfa, 0x42, 0x47, 0x92, 0x01, 0x44, 0x18, 0x01, 0x22, 0x40, 0x72, 0x3e, 0x52, 0x0b, 0x61, - 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x63, 0x6c, 0x69, 0x65, - 0x6e, 0x74, 0x52, 0x0a, 0x65, 0x6e, 0x64, 0x20, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x07, - 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x52, 0x0c, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x52, 0x0b, 0x65, 0x6e, 0x74, - 0x69, 0x74, 0x79, 0x54, 0x79, 0x70, 0x65, 0x73, 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x00, - 0x10, 0x01, 0x22, 0xad, 0x01, 0x0a, 0x19, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, - 0x72, 0x42, 0x6f, 0x6f, 0x6b, 0x6d, 0x61, 0x72, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x44, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, - 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, - 0x65, 0x72, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x07, 0x75, - 0x73, 0x65, 0x72, 0x49, 0x64, 0x73, 0x12, 0x4a, 0x0a, 0x0a, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, - 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x74, 0x74, 0x6e, - 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x45, 0x6e, 0x74, 0x69, - 0x74, 0x79, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x42, 0x08, 0xfa, - 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x09, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, - 0x64, 0x73, 0x22, 0xb5, 0x01, 0x0a, 0x1f, 0x42, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x42, 0x6f, 0x6f, 0x6b, 0x6d, 0x61, 0x72, 0x6b, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x44, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, - 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, - 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, - 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, - 0x02, 0x10, 0x01, 0x52, 0x07, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x73, 0x12, 0x4c, 0x0a, 0x0a, - 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x21, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, - 0x33, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, - 0x65, 0x72, 0x73, 0x42, 0x0a, 0xfa, 0x42, 0x07, 0x92, 0x01, 0x04, 0x08, 0x01, 0x10, 0x14, 0x52, - 0x09, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x64, 0x73, 0x2a, 0x70, 0x0a, 0x0c, 0x43, 0x6f, - 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x54, 0x68, 0x65, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x14, 0x43, 0x4f, - 0x4e, 0x53, 0x4f, 0x4c, 0x45, 0x5f, 0x54, 0x48, 0x45, 0x4d, 0x45, 0x5f, 0x53, 0x59, 0x53, 0x54, - 0x45, 0x4d, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, 0x43, 0x4f, 0x4e, 0x53, 0x4f, 0x4c, 0x45, 0x5f, - 0x54, 0x48, 0x45, 0x4d, 0x45, 0x5f, 0x4c, 0x49, 0x47, 0x48, 0x54, 0x10, 0x01, 0x12, 0x16, 0x0a, - 0x12, 0x43, 0x4f, 0x4e, 0x53, 0x4f, 0x4c, 0x45, 0x5f, 0x54, 0x48, 0x45, 0x4d, 0x45, 0x5f, 0x44, - 0x41, 0x52, 0x4b, 0x10, 0x02, 0x1a, 0x15, 0xea, 0xaa, 0x19, 0x11, 0x18, 0x01, 0x2a, 0x0d, 0x43, - 0x4f, 0x4e, 0x53, 0x4f, 0x4c, 0x45, 0x5f, 0x54, 0x48, 0x45, 0x4d, 0x45, 0x2a, 0x4b, 0x0a, 0x08, - 0x54, 0x75, 0x74, 0x6f, 0x72, 0x69, 0x61, 0x6c, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x55, 0x54, 0x4f, - 0x52, 0x49, 0x41, 0x4c, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x21, - 0x0a, 0x1d, 0x54, 0x55, 0x54, 0x4f, 0x52, 0x49, 0x41, 0x4c, 0x5f, 0x4c, 0x49, 0x56, 0x45, 0x5f, - 0x44, 0x41, 0x54, 0x41, 0x5f, 0x53, 0x50, 0x4c, 0x49, 0x54, 0x5f, 0x56, 0x49, 0x45, 0x57, 0x10, - 0x01, 0x1a, 0x06, 0xea, 0xaa, 0x19, 0x02, 0x18, 0x01, 0x2a, 0x7d, 0x0a, 0x0f, 0x44, 0x61, 0x73, - 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x4c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x12, 0x1a, 0x0a, 0x16, - 0x44, 0x41, 0x53, 0x48, 0x42, 0x4f, 0x41, 0x52, 0x44, 0x5f, 0x4c, 0x41, 0x59, 0x4f, 0x55, 0x54, - 0x5f, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x44, 0x41, 0x53, 0x48, - 0x42, 0x4f, 0x41, 0x52, 0x44, 0x5f, 0x4c, 0x41, 0x59, 0x4f, 0x55, 0x54, 0x5f, 0x4c, 0x49, 0x53, - 0x54, 0x10, 0x01, 0x12, 0x19, 0x0a, 0x15, 0x44, 0x41, 0x53, 0x48, 0x42, 0x4f, 0x41, 0x52, 0x44, - 0x5f, 0x4c, 0x41, 0x59, 0x4f, 0x55, 0x54, 0x5f, 0x47, 0x52, 0x49, 0x44, 0x10, 0x02, 0x1a, 0x18, - 0xea, 0xaa, 0x19, 0x14, 0x18, 0x01, 0x2a, 0x10, 0x44, 0x41, 0x53, 0x48, 0x42, 0x4f, 0x41, 0x52, - 0x44, 0x5f, 0x4c, 0x41, 0x59, 0x4f, 0x55, 0x54, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x6f, 0x2e, 0x74, - 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, - 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, - 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x74, 0x6e, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, + 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x07, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x73, 0x12, 0x4c, + 0x0a, 0x0a, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, + 0x2e, 0x76, 0x33, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, + 0x66, 0x69, 0x65, 0x72, 0x73, 0x42, 0x0a, 0xfa, 0x42, 0x07, 0x92, 0x01, 0x04, 0x08, 0x01, 0x10, + 0x14, 0x52, 0x09, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x64, 0x73, 0x2a, 0x70, 0x0a, 0x0c, + 0x43, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x54, 0x68, 0x65, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x14, + 0x43, 0x4f, 0x4e, 0x53, 0x4f, 0x4c, 0x45, 0x5f, 0x54, 0x48, 0x45, 0x4d, 0x45, 0x5f, 0x53, 0x59, + 0x53, 0x54, 0x45, 0x4d, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, 0x43, 0x4f, 0x4e, 0x53, 0x4f, 0x4c, + 0x45, 0x5f, 0x54, 0x48, 0x45, 0x4d, 0x45, 0x5f, 0x4c, 0x49, 0x47, 0x48, 0x54, 0x10, 0x01, 0x12, + 0x16, 0x0a, 0x12, 0x43, 0x4f, 0x4e, 0x53, 0x4f, 0x4c, 0x45, 0x5f, 0x54, 0x48, 0x45, 0x4d, 0x45, + 0x5f, 0x44, 0x41, 0x52, 0x4b, 0x10, 0x02, 0x1a, 0x15, 0xea, 0xaa, 0x19, 0x11, 0x18, 0x01, 0x2a, + 0x0d, 0x43, 0x4f, 0x4e, 0x53, 0x4f, 0x4c, 0x45, 0x5f, 0x54, 0x48, 0x45, 0x4d, 0x45, 0x2a, 0x4b, + 0x0a, 0x08, 0x54, 0x75, 0x74, 0x6f, 0x72, 0x69, 0x61, 0x6c, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x55, + 0x54, 0x4f, 0x52, 0x49, 0x41, 0x4c, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, + 0x12, 0x21, 0x0a, 0x1d, 0x54, 0x55, 0x54, 0x4f, 0x52, 0x49, 0x41, 0x4c, 0x5f, 0x4c, 0x49, 0x56, + 0x45, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x53, 0x50, 0x4c, 0x49, 0x54, 0x5f, 0x56, 0x49, 0x45, + 0x57, 0x10, 0x01, 0x1a, 0x06, 0xea, 0xaa, 0x19, 0x02, 0x18, 0x01, 0x2a, 0x7d, 0x0a, 0x0f, 0x44, + 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x4c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x12, 0x1a, + 0x0a, 0x16, 0x44, 0x41, 0x53, 0x48, 0x42, 0x4f, 0x41, 0x52, 0x44, 0x5f, 0x4c, 0x41, 0x59, 0x4f, + 0x55, 0x54, 0x5f, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x44, 0x41, + 0x53, 0x48, 0x42, 0x4f, 0x41, 0x52, 0x44, 0x5f, 0x4c, 0x41, 0x59, 0x4f, 0x55, 0x54, 0x5f, 0x4c, + 0x49, 0x53, 0x54, 0x10, 0x01, 0x12, 0x19, 0x0a, 0x15, 0x44, 0x41, 0x53, 0x48, 0x42, 0x4f, 0x41, + 0x52, 0x44, 0x5f, 0x4c, 0x41, 0x59, 0x4f, 0x55, 0x54, 0x5f, 0x47, 0x52, 0x49, 0x44, 0x10, 0x02, + 0x1a, 0x18, 0xea, 0xaa, 0x19, 0x14, 0x18, 0x01, 0x2a, 0x10, 0x44, 0x41, 0x53, 0x48, 0x42, 0x4f, + 0x41, 0x52, 0x44, 0x5f, 0x4c, 0x41, 0x59, 0x4f, 0x55, 0x54, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x6f, + 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, + 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, + 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x74, 0x6e, 0x70, 0x62, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -3339,8 +3352,8 @@ var file_ttn_lorawan_v3_user_proto_goTypes = []interface{}{ (*ContactInfo)(nil), // 43: ttn.lorawan.v3.ContactInfo (State)(0), // 44: ttn.lorawan.v3.State (*Picture)(nil), // 45: ttn.lorawan.v3.Picture - (*fieldmaskpb.FieldMask)(nil), // 46: google.protobuf.FieldMask - (Right)(0), // 47: ttn.lorawan.v3.Right + (Right)(0), // 46: ttn.lorawan.v3.Right + (*fieldmaskpb.FieldMask)(nil), // 47: google.protobuf.FieldMask (*APIKey)(nil), // 48: ttn.lorawan.v3.APIKey (*EntityIdentifiers)(nil), // 49: ttn.lorawan.v3.EntityIdentifiers } @@ -3364,67 +3377,68 @@ var file_ttn_lorawan_v3_user_proto_depIdxs = []int32{ 45, // 16: ttn.lorawan.v3.User.profile_picture:type_name -> ttn.lorawan.v3.Picture 4, // 17: ttn.lorawan.v3.User.console_preferences:type_name -> ttn.lorawan.v3.UserConsolePreferences 3, // 18: ttn.lorawan.v3.User.email_notification_preferences:type_name -> ttn.lorawan.v3.EmailNotificationPreferences - 5, // 19: ttn.lorawan.v3.Users.users:type_name -> ttn.lorawan.v3.User - 41, // 20: ttn.lorawan.v3.GetUserRequest.user_ids:type_name -> ttn.lorawan.v3.UserIdentifiers - 46, // 21: ttn.lorawan.v3.GetUserRequest.field_mask:type_name -> google.protobuf.FieldMask - 46, // 22: ttn.lorawan.v3.ListUsersRequest.field_mask:type_name -> google.protobuf.FieldMask - 5, // 23: ttn.lorawan.v3.CreateUserRequest.user:type_name -> ttn.lorawan.v3.User - 5, // 24: ttn.lorawan.v3.UpdateUserRequest.user:type_name -> ttn.lorawan.v3.User - 46, // 25: ttn.lorawan.v3.UpdateUserRequest.field_mask:type_name -> google.protobuf.FieldMask - 41, // 26: ttn.lorawan.v3.CreateTemporaryPasswordRequest.user_ids:type_name -> ttn.lorawan.v3.UserIdentifiers - 41, // 27: ttn.lorawan.v3.UpdateUserPasswordRequest.user_ids:type_name -> ttn.lorawan.v3.UserIdentifiers - 41, // 28: ttn.lorawan.v3.ListUserAPIKeysRequest.user_ids:type_name -> ttn.lorawan.v3.UserIdentifiers - 41, // 29: ttn.lorawan.v3.GetUserAPIKeyRequest.user_ids:type_name -> ttn.lorawan.v3.UserIdentifiers - 41, // 30: ttn.lorawan.v3.CreateUserAPIKeyRequest.user_ids:type_name -> ttn.lorawan.v3.UserIdentifiers - 47, // 31: ttn.lorawan.v3.CreateUserAPIKeyRequest.rights:type_name -> ttn.lorawan.v3.Right - 42, // 32: ttn.lorawan.v3.CreateUserAPIKeyRequest.expires_at:type_name -> google.protobuf.Timestamp - 41, // 33: ttn.lorawan.v3.UpdateUserAPIKeyRequest.user_ids:type_name -> ttn.lorawan.v3.UserIdentifiers - 48, // 34: ttn.lorawan.v3.UpdateUserAPIKeyRequest.api_key:type_name -> ttn.lorawan.v3.APIKey - 46, // 35: ttn.lorawan.v3.UpdateUserAPIKeyRequest.field_mask:type_name -> google.protobuf.FieldMask - 41, // 36: ttn.lorawan.v3.DeleteUserAPIKeyRequest.user_ids:type_name -> ttn.lorawan.v3.UserIdentifiers - 42, // 37: ttn.lorawan.v3.Invitation.expires_at:type_name -> google.protobuf.Timestamp - 42, // 38: ttn.lorawan.v3.Invitation.created_at:type_name -> google.protobuf.Timestamp - 42, // 39: ttn.lorawan.v3.Invitation.updated_at:type_name -> google.protobuf.Timestamp - 42, // 40: ttn.lorawan.v3.Invitation.accepted_at:type_name -> google.protobuf.Timestamp - 41, // 41: ttn.lorawan.v3.Invitation.accepted_by:type_name -> ttn.lorawan.v3.UserIdentifiers - 18, // 42: ttn.lorawan.v3.Invitations.invitations:type_name -> ttn.lorawan.v3.Invitation - 41, // 43: ttn.lorawan.v3.UserSessionIdentifiers.user_ids:type_name -> ttn.lorawan.v3.UserIdentifiers - 41, // 44: ttn.lorawan.v3.UserSession.user_ids:type_name -> ttn.lorawan.v3.UserIdentifiers - 42, // 45: ttn.lorawan.v3.UserSession.created_at:type_name -> google.protobuf.Timestamp - 42, // 46: ttn.lorawan.v3.UserSession.updated_at:type_name -> google.protobuf.Timestamp - 42, // 47: ttn.lorawan.v3.UserSession.expires_at:type_name -> google.protobuf.Timestamp - 24, // 48: ttn.lorawan.v3.UserSessions.sessions:type_name -> ttn.lorawan.v3.UserSession - 41, // 49: ttn.lorawan.v3.ListUserSessionsRequest.user_ids:type_name -> ttn.lorawan.v3.UserIdentifiers - 41, // 50: ttn.lorawan.v3.LoginToken.user_ids:type_name -> ttn.lorawan.v3.UserIdentifiers - 42, // 51: ttn.lorawan.v3.LoginToken.created_at:type_name -> google.protobuf.Timestamp - 42, // 52: ttn.lorawan.v3.LoginToken.updated_at:type_name -> google.protobuf.Timestamp - 42, // 53: ttn.lorawan.v3.LoginToken.expires_at:type_name -> google.protobuf.Timestamp - 41, // 54: ttn.lorawan.v3.CreateLoginTokenRequest.user_ids:type_name -> ttn.lorawan.v3.UserIdentifiers - 41, // 55: ttn.lorawan.v3.UserBookmark.user_ids:type_name -> ttn.lorawan.v3.UserIdentifiers - 49, // 56: ttn.lorawan.v3.UserBookmark.entity_ids:type_name -> ttn.lorawan.v3.EntityIdentifiers - 42, // 57: ttn.lorawan.v3.UserBookmark.created_at:type_name -> google.protobuf.Timestamp - 30, // 58: ttn.lorawan.v3.UserBookmarks.bookmarks:type_name -> ttn.lorawan.v3.UserBookmark - 41, // 59: ttn.lorawan.v3.CreateUserBookmarkRequest.user_ids:type_name -> ttn.lorawan.v3.UserIdentifiers - 49, // 60: ttn.lorawan.v3.CreateUserBookmarkRequest.entity_ids:type_name -> ttn.lorawan.v3.EntityIdentifiers - 41, // 61: ttn.lorawan.v3.ListUserBookmarksRequest.user_ids:type_name -> ttn.lorawan.v3.UserIdentifiers - 41, // 62: ttn.lorawan.v3.DeleteUserBookmarkRequest.user_ids:type_name -> ttn.lorawan.v3.UserIdentifiers - 49, // 63: ttn.lorawan.v3.DeleteUserBookmarkRequest.entity_ids:type_name -> ttn.lorawan.v3.EntityIdentifiers - 41, // 64: ttn.lorawan.v3.BatchDeleteUserBookmarksRequest.user_ids:type_name -> ttn.lorawan.v3.UserIdentifiers - 49, // 65: ttn.lorawan.v3.BatchDeleteUserBookmarksRequest.entity_ids:type_name -> ttn.lorawan.v3.EntityIdentifiers - 2, // 66: ttn.lorawan.v3.UserConsolePreferences.DashboardLayouts.api_key:type_name -> ttn.lorawan.v3.DashboardLayout - 2, // 67: ttn.lorawan.v3.UserConsolePreferences.DashboardLayouts.application:type_name -> ttn.lorawan.v3.DashboardLayout - 2, // 68: ttn.lorawan.v3.UserConsolePreferences.DashboardLayouts.collaborator:type_name -> ttn.lorawan.v3.DashboardLayout - 2, // 69: ttn.lorawan.v3.UserConsolePreferences.DashboardLayouts.end_device:type_name -> ttn.lorawan.v3.DashboardLayout - 2, // 70: ttn.lorawan.v3.UserConsolePreferences.DashboardLayouts.gateway:type_name -> ttn.lorawan.v3.DashboardLayout - 2, // 71: ttn.lorawan.v3.UserConsolePreferences.DashboardLayouts.organization:type_name -> ttn.lorawan.v3.DashboardLayout - 2, // 72: ttn.lorawan.v3.UserConsolePreferences.DashboardLayouts.overview:type_name -> ttn.lorawan.v3.DashboardLayout - 2, // 73: ttn.lorawan.v3.UserConsolePreferences.DashboardLayouts.user:type_name -> ttn.lorawan.v3.DashboardLayout - 1, // 74: ttn.lorawan.v3.UserConsolePreferences.Tutorials.seen:type_name -> ttn.lorawan.v3.Tutorial - 75, // [75:75] is the sub-list for method output_type - 75, // [75:75] is the sub-list for method input_type - 75, // [75:75] is the sub-list for extension type_name - 75, // [75:75] is the sub-list for extension extendee - 0, // [0:75] is the sub-list for field type_name + 46, // 19: ttn.lorawan.v3.User.universal_rights:type_name -> ttn.lorawan.v3.Right + 5, // 20: ttn.lorawan.v3.Users.users:type_name -> ttn.lorawan.v3.User + 41, // 21: ttn.lorawan.v3.GetUserRequest.user_ids:type_name -> ttn.lorawan.v3.UserIdentifiers + 47, // 22: ttn.lorawan.v3.GetUserRequest.field_mask:type_name -> google.protobuf.FieldMask + 47, // 23: ttn.lorawan.v3.ListUsersRequest.field_mask:type_name -> google.protobuf.FieldMask + 5, // 24: ttn.lorawan.v3.CreateUserRequest.user:type_name -> ttn.lorawan.v3.User + 5, // 25: ttn.lorawan.v3.UpdateUserRequest.user:type_name -> ttn.lorawan.v3.User + 47, // 26: ttn.lorawan.v3.UpdateUserRequest.field_mask:type_name -> google.protobuf.FieldMask + 41, // 27: ttn.lorawan.v3.CreateTemporaryPasswordRequest.user_ids:type_name -> ttn.lorawan.v3.UserIdentifiers + 41, // 28: ttn.lorawan.v3.UpdateUserPasswordRequest.user_ids:type_name -> ttn.lorawan.v3.UserIdentifiers + 41, // 29: ttn.lorawan.v3.ListUserAPIKeysRequest.user_ids:type_name -> ttn.lorawan.v3.UserIdentifiers + 41, // 30: ttn.lorawan.v3.GetUserAPIKeyRequest.user_ids:type_name -> ttn.lorawan.v3.UserIdentifiers + 41, // 31: ttn.lorawan.v3.CreateUserAPIKeyRequest.user_ids:type_name -> ttn.lorawan.v3.UserIdentifiers + 46, // 32: ttn.lorawan.v3.CreateUserAPIKeyRequest.rights:type_name -> ttn.lorawan.v3.Right + 42, // 33: ttn.lorawan.v3.CreateUserAPIKeyRequest.expires_at:type_name -> google.protobuf.Timestamp + 41, // 34: ttn.lorawan.v3.UpdateUserAPIKeyRequest.user_ids:type_name -> ttn.lorawan.v3.UserIdentifiers + 48, // 35: ttn.lorawan.v3.UpdateUserAPIKeyRequest.api_key:type_name -> ttn.lorawan.v3.APIKey + 47, // 36: ttn.lorawan.v3.UpdateUserAPIKeyRequest.field_mask:type_name -> google.protobuf.FieldMask + 41, // 37: ttn.lorawan.v3.DeleteUserAPIKeyRequest.user_ids:type_name -> ttn.lorawan.v3.UserIdentifiers + 42, // 38: ttn.lorawan.v3.Invitation.expires_at:type_name -> google.protobuf.Timestamp + 42, // 39: ttn.lorawan.v3.Invitation.created_at:type_name -> google.protobuf.Timestamp + 42, // 40: ttn.lorawan.v3.Invitation.updated_at:type_name -> google.protobuf.Timestamp + 42, // 41: ttn.lorawan.v3.Invitation.accepted_at:type_name -> google.protobuf.Timestamp + 41, // 42: ttn.lorawan.v3.Invitation.accepted_by:type_name -> ttn.lorawan.v3.UserIdentifiers + 18, // 43: ttn.lorawan.v3.Invitations.invitations:type_name -> ttn.lorawan.v3.Invitation + 41, // 44: ttn.lorawan.v3.UserSessionIdentifiers.user_ids:type_name -> ttn.lorawan.v3.UserIdentifiers + 41, // 45: ttn.lorawan.v3.UserSession.user_ids:type_name -> ttn.lorawan.v3.UserIdentifiers + 42, // 46: ttn.lorawan.v3.UserSession.created_at:type_name -> google.protobuf.Timestamp + 42, // 47: ttn.lorawan.v3.UserSession.updated_at:type_name -> google.protobuf.Timestamp + 42, // 48: ttn.lorawan.v3.UserSession.expires_at:type_name -> google.protobuf.Timestamp + 24, // 49: ttn.lorawan.v3.UserSessions.sessions:type_name -> ttn.lorawan.v3.UserSession + 41, // 50: ttn.lorawan.v3.ListUserSessionsRequest.user_ids:type_name -> ttn.lorawan.v3.UserIdentifiers + 41, // 51: ttn.lorawan.v3.LoginToken.user_ids:type_name -> ttn.lorawan.v3.UserIdentifiers + 42, // 52: ttn.lorawan.v3.LoginToken.created_at:type_name -> google.protobuf.Timestamp + 42, // 53: ttn.lorawan.v3.LoginToken.updated_at:type_name -> google.protobuf.Timestamp + 42, // 54: ttn.lorawan.v3.LoginToken.expires_at:type_name -> google.protobuf.Timestamp + 41, // 55: ttn.lorawan.v3.CreateLoginTokenRequest.user_ids:type_name -> ttn.lorawan.v3.UserIdentifiers + 41, // 56: ttn.lorawan.v3.UserBookmark.user_ids:type_name -> ttn.lorawan.v3.UserIdentifiers + 49, // 57: ttn.lorawan.v3.UserBookmark.entity_ids:type_name -> ttn.lorawan.v3.EntityIdentifiers + 42, // 58: ttn.lorawan.v3.UserBookmark.created_at:type_name -> google.protobuf.Timestamp + 30, // 59: ttn.lorawan.v3.UserBookmarks.bookmarks:type_name -> ttn.lorawan.v3.UserBookmark + 41, // 60: ttn.lorawan.v3.CreateUserBookmarkRequest.user_ids:type_name -> ttn.lorawan.v3.UserIdentifiers + 49, // 61: ttn.lorawan.v3.CreateUserBookmarkRequest.entity_ids:type_name -> ttn.lorawan.v3.EntityIdentifiers + 41, // 62: ttn.lorawan.v3.ListUserBookmarksRequest.user_ids:type_name -> ttn.lorawan.v3.UserIdentifiers + 41, // 63: ttn.lorawan.v3.DeleteUserBookmarkRequest.user_ids:type_name -> ttn.lorawan.v3.UserIdentifiers + 49, // 64: ttn.lorawan.v3.DeleteUserBookmarkRequest.entity_ids:type_name -> ttn.lorawan.v3.EntityIdentifiers + 41, // 65: ttn.lorawan.v3.BatchDeleteUserBookmarksRequest.user_ids:type_name -> ttn.lorawan.v3.UserIdentifiers + 49, // 66: ttn.lorawan.v3.BatchDeleteUserBookmarksRequest.entity_ids:type_name -> ttn.lorawan.v3.EntityIdentifiers + 2, // 67: ttn.lorawan.v3.UserConsolePreferences.DashboardLayouts.api_key:type_name -> ttn.lorawan.v3.DashboardLayout + 2, // 68: ttn.lorawan.v3.UserConsolePreferences.DashboardLayouts.application:type_name -> ttn.lorawan.v3.DashboardLayout + 2, // 69: ttn.lorawan.v3.UserConsolePreferences.DashboardLayouts.collaborator:type_name -> ttn.lorawan.v3.DashboardLayout + 2, // 70: ttn.lorawan.v3.UserConsolePreferences.DashboardLayouts.end_device:type_name -> ttn.lorawan.v3.DashboardLayout + 2, // 71: ttn.lorawan.v3.UserConsolePreferences.DashboardLayouts.gateway:type_name -> ttn.lorawan.v3.DashboardLayout + 2, // 72: ttn.lorawan.v3.UserConsolePreferences.DashboardLayouts.organization:type_name -> ttn.lorawan.v3.DashboardLayout + 2, // 73: ttn.lorawan.v3.UserConsolePreferences.DashboardLayouts.overview:type_name -> ttn.lorawan.v3.DashboardLayout + 2, // 74: ttn.lorawan.v3.UserConsolePreferences.DashboardLayouts.user:type_name -> ttn.lorawan.v3.DashboardLayout + 1, // 75: ttn.lorawan.v3.UserConsolePreferences.Tutorials.seen:type_name -> ttn.lorawan.v3.Tutorial + 76, // [76:76] is the sub-list for method output_type + 76, // [76:76] is the sub-list for method input_type + 76, // [76:76] is the sub-list for extension type_name + 76, // [76:76] is the sub-list for extension extendee + 0, // [0:76] is the sub-list for field type_name } func init() { file_ttn_lorawan_v3_user_proto_init() } diff --git a/pkg/ttnpb/user.pb.paths.fm.go b/pkg/ttnpb/user.pb.paths.fm.go index 3b66ec7f99..a0b62f317a 100644 --- a/pkg/ttnpb/user.pb.paths.fm.go +++ b/pkg/ttnpb/user.pb.paths.fm.go @@ -87,6 +87,7 @@ var UserFieldPathsNested = []string{ "temporary_password", "temporary_password_created_at", "temporary_password_expires_at", + "universal_rights", "updated_at", } @@ -112,6 +113,7 @@ var UserFieldPathsTopLevel = []string{ "temporary_password", "temporary_password_created_at", "temporary_password_expires_at", + "universal_rights", "updated_at", } var UsersFieldPathsNested = []string{ @@ -198,6 +200,7 @@ var CreateUserRequestFieldPathsNested = []string{ "user.temporary_password", "user.temporary_password_created_at", "user.temporary_password_expires_at", + "user.universal_rights", "user.updated_at", } @@ -256,6 +259,7 @@ var UpdateUserRequestFieldPathsNested = []string{ "user.temporary_password", "user.temporary_password_created_at", "user.temporary_password_expires_at", + "user.universal_rights", "user.updated_at", } diff --git a/pkg/ttnpb/user.pb.setters.fm.go b/pkg/ttnpb/user.pb.setters.fm.go index 761067afec..a367421b77 100644 --- a/pkg/ttnpb/user.pb.setters.fm.go +++ b/pkg/ttnpb/user.pb.setters.fm.go @@ -392,6 +392,15 @@ func (dst *User) SetFields(src *User, paths ...string) error { dst.EmailNotificationPreferences = nil } } + case "universal_rights": + if len(subs) > 0 { + return fmt.Errorf("'universal_rights' has no subfields, but %s were specified", subs) + } + if src != nil { + dst.UniversalRights = src.UniversalRights + } else { + dst.UniversalRights = nil + } default: return fmt.Errorf("invalid field: '%s'", name) diff --git a/pkg/ttnpb/user.pb.validate.go b/pkg/ttnpb/user.pb.validate.go index be280ed361..7d7ca8d3e1 100644 --- a/pkg/ttnpb/user.pb.validate.go +++ b/pkg/ttnpb/user.pb.validate.go @@ -538,6 +538,8 @@ func (m *User) ValidateFields(paths ...string) error { } } + case "universal_rights": + default: return UserValidationError{ field: name, diff --git a/pkg/ttnpb/user_flags.pb.go b/pkg/ttnpb/user_flags.pb.go index 40e33d112c..dde3aa9ce5 100644 --- a/pkg/ttnpb/user_flags.pb.go +++ b/pkg/ttnpb/user_flags.pb.go @@ -101,6 +101,7 @@ func AddSelectFlagsForUser(flags *pflag.FlagSet, prefix string, hidden bool) { AddSelectFlagsForUserConsolePreferences(flags, flagsplugin.Prefix("console-preferences", prefix), hidden) flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("email-notification-preferences", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("email-notification-preferences", prefix), true), flagsplugin.WithHidden(hidden))) // NOTE: email_notification_preferences (EmailNotificationPreferences) does not seem to have select flags. + flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("universal-rights", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("universal-rights", prefix), false), flagsplugin.WithHidden(hidden))) } // SelectFromFlags outputs the fieldmask paths forUser message from select flags. @@ -207,6 +208,11 @@ func PathsFromSelectFlagsForUser(flags *pflag.FlagSet, prefix string) (paths []s paths = append(paths, flagsplugin.Prefix("email_notification_preferences", prefix)) } // NOTE: email_notification_preferences (EmailNotificationPreferences) does not seem to have select flags. + if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("universal_rights", prefix)); err != nil { + return nil, err + } else if selected && val { + paths = append(paths, flagsplugin.Prefix("universal_rights", prefix)) + } return paths, nil } @@ -228,6 +234,7 @@ func AddSetFlagsForUser(flags *pflag.FlagSet, prefix string, hidden bool) { // FIXME: Skipping ProfilePicture because it does not seem to implement AddSetFlags. AddSetFlagsForUserConsolePreferences(flags, flagsplugin.Prefix("console-preferences", prefix), hidden) // FIXME: Skipping EmailNotificationPreferences because it does not seem to implement AddSetFlags. + flags.AddFlag(flagsplugin.NewStringSliceFlag(flagsplugin.Prefix("universal-rights", prefix), flagsplugin.EnumValueDesc(Right_value), flagsplugin.WithHidden(hidden))) } // SetFromFlags sets the User message from flags. @@ -325,6 +332,19 @@ func (m *User) SetFromFlags(flags *pflag.FlagSet, prefix string) (paths []string } } // FIXME: Skipping EmailNotificationPreferences because it does not seem to implement AddSetFlags. + if val, changed, err := flagsplugin.GetStringSlice(flags, flagsplugin.Prefix("universal_rights", prefix)); err != nil { + return nil, err + } else if changed { + m.UniversalRights = make([]Right, len(val)) + for i, v := range val { + enumValue, err := flagsplugin.SetEnumString(v, Right_value) + if err != nil { + return nil, err + } + m.UniversalRights[i] = Right(enumValue) + } + paths = append(paths, flagsplugin.Prefix("universal_rights", prefix)) + } return paths, nil } diff --git a/pkg/ttnpb/user_json.pb.go b/pkg/ttnpb/user_json.pb.go index 4699648bc3..eca5eac75c 100644 --- a/pkg/ttnpb/user_json.pb.go +++ b/pkg/ttnpb/user_json.pb.go @@ -598,6 +598,17 @@ func (x *User) MarshalProtoJSON(s *jsonplugin.MarshalState) { s.WriteObjectField("email_notification_preferences") x.EmailNotificationPreferences.MarshalProtoJSON(s.WithField("email_notification_preferences")) } + if len(x.UniversalRights) > 0 || s.HasField("universal_rights") { + s.WriteMoreIf(&wroteField) + s.WriteObjectField("universal_rights") + s.WriteArrayStart() + var wroteElement bool + for _, element := range x.UniversalRights { + s.WriteMoreIf(&wroteElement) + element.MarshalProtoJSON(s) + } + s.WriteArrayEnd() + } s.WriteObjectEnd() } @@ -781,6 +792,17 @@ func (x *User) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) { } x.EmailNotificationPreferences = &EmailNotificationPreferences{} x.EmailNotificationPreferences.UnmarshalProtoJSON(s.WithField("email_notification_preferences", true)) + case "universal_rights", "universalRights": + s.AddField("universal_rights") + if s.ReadNil() { + x.UniversalRights = nil + return + } + s.ReadArray(func() { + var v Right + v.UnmarshalProtoJSON(s) + x.UniversalRights = append(x.UniversalRights, v) + }) } }) } diff --git a/sdk/js/generated/api-definition.json b/sdk/js/generated/api-definition.json index a9a3a82437..27bf4962ff 100644 --- a/sdk/js/generated/api-definition.json +++ b/sdk/js/generated/api-definition.json @@ -8169,6 +8169,7 @@ "state_description", "temporary_password_created_at", "temporary_password_expires_at", + "universal_rights", "updated_at" ] }, @@ -8534,6 +8535,7 @@ "state_description", "temporary_password_created_at", "temporary_password_expires_at", + "universal_rights", "updated_at" ] }, @@ -8593,6 +8595,7 @@ "state_description", "temporary_password_created_at", "temporary_password_expires_at", + "universal_rights", "updated_at" ] }, @@ -8655,6 +8658,7 @@ "temporary_password", "temporary_password_created_at", "temporary_password_expires_at", + "universal_rights", "updated_at" ] }, diff --git a/sdk/js/generated/api.json b/sdk/js/generated/api.json index bf296f86f1..e3ccb712e0 100644 --- a/sdk/js/generated/api.json +++ b/sdk/js/generated/api.json @@ -54813,7 +54813,7 @@ }, { "name": "email_notification_preferences", - "description": "next: 27", + "description": "", "label": "", "type": "EmailNotificationPreferences", "longType": "EmailNotificationPreferences", @@ -54822,6 +54822,18 @@ "isoneof": false, "oneofdecl": "", "defaultValue": "" + }, + { + "name": "universal_rights", + "description": "Universal rights are capable of restricting the user's interactions with the API, be it an admin or not.", + "label": "repeated", + "type": "Right", + "longType": "Right", + "fullType": "ttn.lorawan.v3.Right", + "ismap": false, + "isoneof": false, + "oneofdecl": "", + "defaultValue": "" } ] }, From a9fb77d35d7aa8024fcc48ca6c33030275251eab Mon Sep 17 00:00:00 2001 From: Nicholas Cristofaro Date: Mon, 25 Nov 2024 07:52:46 -0300 Subject: [PATCH 03/40] is: Update user store to include universal_rights column --- pkg/identityserver/bunstore/user_store.go | 6 +++++- pkg/identityserver/storetest/user_store.go | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/pkg/identityserver/bunstore/user_store.go b/pkg/identityserver/bunstore/user_store.go index 20c51edc56..0bc40108a4 100644 --- a/pkg/identityserver/bunstore/user_store.go +++ b/pkg/identityserver/bunstore/user_store.go @@ -108,10 +108,10 @@ func userToPB(m *User, fieldMask ...string) (*ttnpb.User, error) { TemporaryPasswordExpiresAt: ttnpb.ProtoTime(m.TemporaryPasswordExpiresAt), ConsolePreferences: &ttnpb.UserConsolePreferences{}, - EmailNotificationPreferences: &ttnpb.EmailNotificationPreferences{ Types: convertIntSlice[int, ttnpb.NotificationType](m.EmailNotificationPreferences), }, + UniversalRights: convertIntSlice[int, ttnpb.Right](m.UniversalRights), } if len(m.Attributes) > 0 { @@ -187,6 +187,7 @@ func (s *userStore) CreateUser(ctx context.Context, pb *ttnpb.User) (*ttnpb.User TemporaryPasswordCreatedAt: cleanTimePtr(ttnpb.StdTime(pb.TemporaryPasswordCreatedAt)), TemporaryPasswordExpiresAt: cleanTimePtr(ttnpb.StdTime(pb.TemporaryPasswordExpiresAt)), EmailNotificationPreferences: convertIntSlice[ttnpb.NotificationType, int](pb.EmailNotificationPreferences.GetTypes()), // nolint:lll + UniversalRights: convertIntSlice[ttnpb.Right, int](pb.UniversalRights), } if pb.ProfilePicture != nil { @@ -290,6 +291,8 @@ func (*userStore) selectWithFields(q *bun.SelectQuery, fieldMask store.FieldMask columns = append(columns, "console_preferences") case "email_notification_preferences", "email_notification_preferences.types": columns = append(columns, "email_notification_preferences") + case "universal_rights": + columns = append(columns, "universal_rights") case "attributes": q = q.Relation("Attributes") case "administrative_contact": @@ -608,6 +611,7 @@ func (s *userStore) updateUserModel( //nolint:gocyclo updateConsolePreferences = true consolePreferences.Tutorials = pb.ConsolePreferences.GetTutorials() case "universal_rights": + model.UniversalRights = convertIntSlice[ttnpb.Right, int](pb.UniversalRights) columns = append(columns, "universal_rights") case "email_notification_preferences", "email_notification_preferences.types": model.EmailNotificationPreferences = convertIntSlice[ttnpb.NotificationType, int](pb.EmailNotificationPreferences.Types) // nolint:lll diff --git a/pkg/identityserver/storetest/user_store.go b/pkg/identityserver/storetest/user_store.go index 820908ddb6..ecf3d3c639 100644 --- a/pkg/identityserver/storetest/user_store.go +++ b/pkg/identityserver/storetest/user_store.go @@ -80,6 +80,7 @@ func (st *StoreTest) TestUserStoreCRUD(t *T) { ttnpb.NotificationType_API_KEY_CREATED, }, }, + UniversalRights: []ttnpb.Right{ttnpb.Right_RIGHT_ALL}, }) if a.So(err, should.BeNil) && a.So(created, should.NotBeNil) { @@ -104,6 +105,7 @@ func (st *StoreTest) TestUserStoreCRUD(t *T) { should.Resemble, &ttnpb.UserConsolePreferences{ConsoleTheme: ttnpb.ConsoleTheme_CONSOLE_THEME_LIGHT}, ) + a.So(created.UniversalRights, should.Resemble, []ttnpb.Right{ttnpb.Right_RIGHT_ALL}) a.So(*ttnpb.StdTime(created.CreatedAt), should.HappenWithin, 5*time.Second, start) a.So(*ttnpb.StdTime(created.UpdatedAt), should.HappenWithin, 5*time.Second, start) a.So(created.EmailNotificationPreferences, should.Resemble, &ttnpb.EmailNotificationPreferences{ @@ -240,6 +242,7 @@ func (st *StoreTest) TestUserStoreCRUD(t *T) { ttnpb.NotificationType_API_KEY_CREATED, }, }, + UniversalRights: []ttnpb.Right{ttnpb.Right_RIGHT_USER_INFO}, }, mask) if a.So(err, should.BeNil) && a.So(updated, should.NotBeNil) { a.So(updated.GetIds().GetUserId(), should.Equal, "foo") @@ -276,6 +279,7 @@ func (st *StoreTest) TestUserStoreCRUD(t *T) { ttnpb.NotificationType_API_KEY_CREATED, }, }) + a.So(updated.UniversalRights, should.Resemble, []ttnpb.Right{ttnpb.Right_RIGHT_USER_INFO}) a.So(*ttnpb.StdTime(updated.CreatedAt), should.Equal, *ttnpb.StdTime(created.CreatedAt)) a.So(*ttnpb.StdTime(updated.UpdatedAt), should.HappenWithin, 5*time.Second, start) } From 5cbef5af758ad78f61819978ecf2fbd4d8468093 Mon Sep 17 00:00:00 2001 From: Nicholas Cristofaro Date: Mon, 25 Nov 2024 08:28:01 -0300 Subject: [PATCH 04/40] is: Refactor user_access loginToken creation --- pkg/identityserver/user_access.go | 56 ++++++++++++++----------------- 1 file changed, 26 insertions(+), 30 deletions(-) diff --git a/pkg/identityserver/user_access.go b/pkg/identityserver/user_access.go index 27f7ad4149..de585af182 100644 --- a/pkg/identityserver/user_access.go +++ b/pkg/identityserver/user_access.go @@ -247,49 +247,45 @@ func (is *IdentityServer) createLoginToken( return nil, errLoginTokensDisabled.New() } - var canCreateMoreTokens bool - err := is.store.Transact(ctx, func(ctx context.Context, st store.Store) error { + // Admin callers can skip sending emails. + canSkipEmail := is.IsAdmin(ctx) + var canReturnToken bool + + token, err := auth.GenerateKey(ctx) + if err != nil { + return nil, err + } + expiresAt := time.Now().Add(loginTokenConfig.TokenTTL) + + err = is.store.Transact(ctx, func(ctx context.Context, st store.Store) error { activeTokens, err := st.FindActiveLoginTokens(ctx, req.GetUserIds()) if err != nil { return err } - canCreateMoreTokens = len(activeTokens) < maxActiveLoginTokens - return nil - }) - if err != nil { - return nil, err - } - if !canCreateMoreTokens { - return nil, errLoginTokensStillValid.New() - } + if len(activeTokens) >= maxActiveLoginTokens { + return errLoginTokensStillValid.New() + } - var canSkipEmail, canReturnToken bool - if is.IsAdmin(ctx) { - canSkipEmail = true // Admin callers can skip sending emails. - err := is.store.Transact(ctx, func(ctx context.Context, st store.Store) error { + if is.IsAdmin(ctx) { usr, err := st.GetUser(ctx, req.GetUserIds(), []string{"admin"}) - if !usr.Admin { - canReturnToken = true // Admin callers can get login tokens for non-admin users. + if err != nil { + return err } - return err - }) - if err != nil { - return nil, err + + // Admin callers can get login tokens for non-admin users. + canReturnToken = !usr.GetAdmin() } - } - token, err := auth.GenerateKey(ctx) - if err != nil { - return nil, err - } - expiresAt := time.Now().Add(loginTokenConfig.TokenTTL) - err = is.store.Transact(ctx, func(ctx context.Context, st store.Store) error { - _, err := st.CreateLoginToken(ctx, &ttnpb.LoginToken{ + _, err = st.CreateLoginToken(ctx, &ttnpb.LoginToken{ UserIds: req.GetUserIds(), ExpiresAt: timestamppb.New(expiresAt), Token: token, }) - return err + if err != nil { + return err + } + + return nil }) if err != nil { return nil, err From e98adbdbd2ccf907a870475842ef29898fd0764f Mon Sep 17 00:00:00 2001 From: Nicholas Cristofaro Date: Mon, 25 Nov 2024 08:31:00 -0300 Subject: [PATCH 05/40] is: Skip over support user when creating a notification --- pkg/identityserver/email.go | 7 +++++++ pkg/identityserver/notification_registry.go | 5 +++++ 2 files changed, 12 insertions(+) diff --git a/pkg/identityserver/email.go b/pkg/identityserver/email.go index 09ddd6e525..9407a67554 100644 --- a/pkg/identityserver/email.go +++ b/pkg/identityserver/email.go @@ -102,6 +102,13 @@ func (is *IdentityServer) SendNotificationEmailToUsers(ctx context.Context, noti var wg errgroup.Group for _, receiver := range receivers { receiver := receiver // shadow range variable. + + // Skips over the possible `support` user. + // This user can only be created via the API endpoints defined in the tenant access service. + if receiver.Ids.IDString() == "support" { + continue + } + wg.Go(func() error { templateData, err := emailNotification.DataBuilder( ctx, diff --git a/pkg/identityserver/notification_registry.go b/pkg/identityserver/notification_registry.go index 607be17f47..6eb9f0b2c2 100644 --- a/pkg/identityserver/notification_registry.go +++ b/pkg/identityserver/notification_registry.go @@ -345,6 +345,11 @@ func (is *IdentityServer) notifyAdminsInternal(ctx context.Context, req *ttnpb.C receiverUserIDs := make([]*ttnpb.UserIdentifiers, len(receivers)) for i, receiver := range receivers { + // Skips over the possible `support` user. + // This user can only be created via the API endpoints defined in the tenant access service. + if receiver.Ids.IDString() == "support" { + continue + } receiverUserIDs[i] = receiver.Ids } From 7a18ec379f19e832b730a45cb8c4bdb913f6da10 Mon Sep 17 00:00:00 2001 From: Nicholas Cristofaro Date: Mon, 25 Nov 2024 09:48:50 -0300 Subject: [PATCH 06/40] dev: Update AuthInfoResponse.GetRights to filter by universalRights --- pkg/ttnpb/identityserver.go | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/pkg/ttnpb/identityserver.go b/pkg/ttnpb/identityserver.go index 0670ba9ea1..ffddf666b8 100644 --- a/pkg/ttnpb/identityserver.go +++ b/pkg/ttnpb/identityserver.go @@ -37,17 +37,28 @@ func (m *AuthInfoResponse) GetRights() []Right { if m == nil { return nil } + + var rights []Right switch accessMethod := m.GetAccessMethod().(type) { case *AuthInfoResponse_ApiKey: - return accessMethod.ApiKey.GetApiKey().GetRights() + rights = accessMethod.ApiKey.GetApiKey().GetRights() case *AuthInfoResponse_OauthAccessToken: - return accessMethod.OauthAccessToken.GetRights() + rights = accessMethod.OauthAccessToken.GetRights() case *AuthInfoResponse_UserSession: - return RightsFrom(Right_RIGHT_ALL).Implied().GetRights() + rights = RightsFrom(Right_RIGHT_ALL).Implied().GetRights() case *AuthInfoResponse_GatewayToken_: - return accessMethod.GatewayToken.GetRights() + rights = accessMethod.GatewayToken.GetRights() } - return nil + + // Limit standard rights with the UniversalRights. There are two possibilities here. + // + // 1. User is an admin which has all rights and therefore the conditional is moot. + // 2. User has its own set of universal rights, which should limit their ability to perform operations. + if universalRights := m.GetUniversalRights(); universalRights != nil { + return RightsFrom(rights...).Intersect(universalRights).GetRights() + } + + return rights } // GetOrganizationOrUserIdentifiers returns the OrganizationOrUserIdentifiers for the used access method. From e6953a798f6e591d715b868e34ebe1adf92a988f Mon Sep 17 00:00:00 2001 From: Nicholas Cristofaro Date: Mon, 25 Nov 2024 09:53:54 -0300 Subject: [PATCH 07/40] is: Update authInfo to change UniversalRights based on the user's field --- pkg/identityserver/entity_access.go | 12 +++++++++++- pkg/identityserver/rights.go | 4 +++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/pkg/identityserver/entity_access.go b/pkg/identityserver/entity_access.go index 95d16f761c..98f203926e 100644 --- a/pkg/identityserver/entity_access.go +++ b/pkg/identityserver/entity_access.go @@ -122,7 +122,13 @@ func (is *IdentityServer) authInfo(ctx context.Context) (info *ttnpb.AuthInfoRes var fetch func(ctx context.Context, st store.Store) error res := &ttnpb.AuthInfoResponse{} - userFieldMask := []string{"admin", "state", "state_description", "primary_email_address_validated_at"} + userFieldMask := []string{ + "admin", + "state", + "state_description", + "primary_email_address_validated_at", + "universal_rights", + } clientFieldMask := []string{"state", "state_description"} var user *ttnpb.User var userRights *ttnpb.Rights @@ -303,6 +309,10 @@ func (is *IdentityServer) authInfo(ctx context.Context) (info *ttnpb.AuthInfoRes } else { res.UniversalRights = ttnpb.AllAdminRights.Implied().Intersect(userRights) } + + if len(user.UniversalRights) > 0 { + res.UniversalRights = res.UniversalRights.Intersect(ttnpb.RightsFrom(user.UniversalRights...)) + } } case ttnpb.State_STATE_REJECTED: // Go to profile page, delete account. diff --git a/pkg/identityserver/rights.go b/pkg/identityserver/rights.go index b021745dfd..7e0fe62bf1 100644 --- a/pkg/identityserver/rights.go +++ b/pkg/identityserver/rights.go @@ -38,7 +38,9 @@ func allPotentialRights(eIDs *ttnpb.EntityIdentifiers, rights *ttnpb.Rights) *tt return nil } -func (is *IdentityServer) getRights(ctx context.Context, entityID *ttnpb.EntityIdentifiers) (entityRights, universalRights *ttnpb.Rights, err error) { +func (is *IdentityServer) getRights( + ctx context.Context, entityID *ttnpb.EntityIdentifiers, +) (entityRights, universalRights *ttnpb.Rights, err error) { authInfo, err := is.authInfo(ctx) if err != nil { return nil, nil, err From eab3ab18018441cea4f131dbe24fb8a2b434025c Mon Sep 17 00:00:00 2001 From: Nicholas Cristofaro Date: Mon, 25 Nov 2024 10:03:21 -0300 Subject: [PATCH 08/40] api: Add RIGHT_APPLICATION_PURGE --- api/ttn/lorawan/v3/api.md | 1 + api/ttn/lorawan/v3/api.swagger.json | 6 +- api/ttn/lorawan/v3/rights.proto | 4 +- pkg/ttnpb/rights.pb.go | 194 ++++++++++++++-------------- pkg/ttnpb/rights_json.pb.go | 1 + sdk/js/generated/api.json | 5 + 6 files changed, 114 insertions(+), 97 deletions(-) diff --git a/api/ttn/lorawan/v3/api.md b/api/ttn/lorawan/v3/api.md index be45688bd1..6d13d53819 100644 --- a/api/ttn/lorawan/v3/api.md +++ b/api/ttn/lorawan/v3/api.md @@ -10993,6 +10993,7 @@ Right is the enum that defines all the different rights to do something in the n | `RIGHT_APPLICATION_SETTINGS_COLLABORATORS` | 18 | The right to view and edit application collaborators. | | `RIGHT_APPLICATION_SETTINGS_PACKAGES` | 56 | The right to view and edit application packages and associations. | | `RIGHT_APPLICATION_DELETE` | 19 | The right to delete application. | +| `RIGHT_APPLICATION_PURGE` | 64 | The right to purge application. | | `RIGHT_APPLICATION_DEVICES_READ` | 20 | The right to view devices in application. | | `RIGHT_APPLICATION_DEVICES_WRITE` | 21 | The right to create devices in application. | | `RIGHT_APPLICATION_DEVICES_READ_KEYS` | 22 | The right to view device keys in application. Note that keys may not be stored in a way that supports viewing them. | diff --git a/api/ttn/lorawan/v3/api.swagger.json b/api/ttn/lorawan/v3/api.swagger.json index d2b129248c..35bba8cf1f 100644 --- a/api/ttn/lorawan/v3/api.swagger.json +++ b/api/ttn/lorawan/v3/api.swagger.json @@ -6911,7 +6911,7 @@ "parameters": [ { "name": "required.rights", - "description": " - RIGHT_USER_INFO: The right to view user information.\n - RIGHT_USER_SETTINGS_BASIC: The right to edit basic user settings.\n - RIGHT_USER_SETTINGS_API_KEYS: The right to view and edit user API keys.\n - RIGHT_USER_DELETE: The right to delete user account.\n - RIGHT_USER_AUTHORIZED_CLIENTS: The right to view and edit authorized OAuth clients of the user.\n - RIGHT_USER_APPLICATIONS_LIST: The right to list applications the user is a collaborator of.\n - RIGHT_USER_APPLICATIONS_CREATE: The right to create an application under the user account.\n - RIGHT_USER_GATEWAYS_LIST: The right to list gateways the user is a collaborator of.\n - RIGHT_USER_GATEWAYS_CREATE: The right to create a gateway under the account of the user.\n - RIGHT_USER_CLIENTS_LIST: The right to list OAuth clients the user is a collaborator of.\n - RIGHT_USER_CLIENTS_CREATE: The right to create an OAuth client under the account of the user.\n - RIGHT_USER_ORGANIZATIONS_LIST: The right to list organizations the user is a member of.\n - RIGHT_USER_ORGANIZATIONS_CREATE: The right to create an organization under the user account.\n - RIGHT_USER_NOTIFICATIONS_READ: The right to read notifications sent to the user.\n - RIGHT_USER_ALL: The pseudo-right for all (current and future) user rights.\n - RIGHT_APPLICATION_INFO: The right to view application information.\n - RIGHT_APPLICATION_SETTINGS_BASIC: The right to edit basic application settings.\n - RIGHT_APPLICATION_SETTINGS_API_KEYS: The right to view and edit application API keys.\n - RIGHT_APPLICATION_SETTINGS_COLLABORATORS: The right to view and edit application collaborators.\n - RIGHT_APPLICATION_SETTINGS_PACKAGES: The right to view and edit application packages and associations.\n - RIGHT_APPLICATION_DELETE: The right to delete application.\n - RIGHT_APPLICATION_DEVICES_READ: The right to view devices in application.\n - RIGHT_APPLICATION_DEVICES_WRITE: The right to create devices in application.\n - RIGHT_APPLICATION_DEVICES_READ_KEYS: The right to view device keys in application.\nNote that keys may not be stored in a way that supports viewing them.\n - RIGHT_APPLICATION_DEVICES_WRITE_KEYS: The right to edit device keys in application.\n - RIGHT_APPLICATION_TRAFFIC_READ: The right to read application traffic (uplink and downlink).\n - RIGHT_APPLICATION_TRAFFIC_UP_WRITE: The right to write uplink application traffic.\n - RIGHT_APPLICATION_TRAFFIC_DOWN_WRITE: The right to write downlink application traffic.\n - RIGHT_APPLICATION_LINK: The right to link as Application to a Network Server for traffic exchange,\ni.e. read uplink and write downlink (API keys only).\nThis right is typically only given to an Application Server.\nThis right implies RIGHT_APPLICATION_INFO, RIGHT_APPLICATION_TRAFFIC_READ,\nand RIGHT_APPLICATION_TRAFFIC_DOWN_WRITE.\n - RIGHT_APPLICATION_ALL: The pseudo-right for all (current and future) application rights.\n - RIGHT_CLIENT_ALL: The pseudo-right for all (current and future) OAuth client rights.\n - RIGHT_CLIENT_INFO: The right to read client information.\n - RIGHT_CLIENT_SETTINGS_BASIC: The right to edit basic client settings.\n - RIGHT_CLIENT_SETTINGS_COLLABORATORS: The right to view and edit client collaborators.\n - RIGHT_CLIENT_DELETE: The right to delete a client.\n - RIGHT_GATEWAY_INFO: The right to view gateway information.\n - RIGHT_GATEWAY_SETTINGS_BASIC: The right to edit basic gateway settings.\n - RIGHT_GATEWAY_SETTINGS_API_KEYS: The right to view and edit gateway API keys.\n - RIGHT_GATEWAY_SETTINGS_COLLABORATORS: The right to view and edit gateway collaborators.\n - RIGHT_GATEWAY_DELETE: The right to delete gateway.\n - RIGHT_GATEWAY_TRAFFIC_READ: The right to read gateway traffic.\n - RIGHT_GATEWAY_TRAFFIC_DOWN_WRITE: The right to write downlink gateway traffic.\n - RIGHT_GATEWAY_LINK: The right to link as Gateway to a Gateway Server for traffic exchange,\ni.e. write uplink and read downlink (API keys only)\nThis right is typically only given to a gateway.\nThis right implies RIGHT_GATEWAY_INFO.\n - RIGHT_GATEWAY_STATUS_READ: The right to view gateway status.\n - RIGHT_GATEWAY_LOCATION_READ: The right to view view gateway location.\n - RIGHT_GATEWAY_WRITE_SECRETS: The right to store secrets associated with this gateway.\n - RIGHT_GATEWAY_READ_SECRETS: The right to retrieve secrets associated with this gateway.\n - RIGHT_GATEWAY_ALL: The pseudo-right for all (current and future) gateway rights.\n - RIGHT_ORGANIZATION_INFO: The right to view organization information.\n - RIGHT_ORGANIZATION_SETTINGS_BASIC: The right to edit basic organization settings.\n - RIGHT_ORGANIZATION_SETTINGS_API_KEYS: The right to view and edit organization API keys.\n - RIGHT_ORGANIZATION_SETTINGS_MEMBERS: The right to view and edit organization members.\n - RIGHT_ORGANIZATION_DELETE: The right to delete organization.\n - RIGHT_ORGANIZATION_APPLICATIONS_LIST: The right to list the applications the organization is a collaborator of.\n - RIGHT_ORGANIZATION_APPLICATIONS_CREATE: The right to create an application under the organization.\n - RIGHT_ORGANIZATION_GATEWAYS_LIST: The right to list the gateways the organization is a collaborator of.\n - RIGHT_ORGANIZATION_GATEWAYS_CREATE: The right to create a gateway under the organization.\n - RIGHT_ORGANIZATION_CLIENTS_LIST: The right to list the OAuth clients the organization is a collaborator of.\n - RIGHT_ORGANIZATION_CLIENTS_CREATE: The right to create an OAuth client under the organization.\n - RIGHT_ORGANIZATION_ADD_AS_COLLABORATOR: The right to add the organization as a collaborator on an existing entity.\n - RIGHT_ORGANIZATION_ALL: The pseudo-right for all (current and future) organization rights.\n - RIGHT_SEND_INVITES: The right to send invites to new users.\nNote that this is not prefixed with \"USER_\"; it is not a right on the user entity.\n - RIGHT_ALL: The pseudo-right for all (current and future) possible rights.", + "description": " - RIGHT_USER_INFO: The right to view user information.\n - RIGHT_USER_SETTINGS_BASIC: The right to edit basic user settings.\n - RIGHT_USER_SETTINGS_API_KEYS: The right to view and edit user API keys.\n - RIGHT_USER_DELETE: The right to delete user account.\n - RIGHT_USER_AUTHORIZED_CLIENTS: The right to view and edit authorized OAuth clients of the user.\n - RIGHT_USER_APPLICATIONS_LIST: The right to list applications the user is a collaborator of.\n - RIGHT_USER_APPLICATIONS_CREATE: The right to create an application under the user account.\n - RIGHT_USER_GATEWAYS_LIST: The right to list gateways the user is a collaborator of.\n - RIGHT_USER_GATEWAYS_CREATE: The right to create a gateway under the account of the user.\n - RIGHT_USER_CLIENTS_LIST: The right to list OAuth clients the user is a collaborator of.\n - RIGHT_USER_CLIENTS_CREATE: The right to create an OAuth client under the account of the user.\n - RIGHT_USER_ORGANIZATIONS_LIST: The right to list organizations the user is a member of.\n - RIGHT_USER_ORGANIZATIONS_CREATE: The right to create an organization under the user account.\n - RIGHT_USER_NOTIFICATIONS_READ: The right to read notifications sent to the user.\n - RIGHT_USER_ALL: The pseudo-right for all (current and future) user rights.\n - RIGHT_APPLICATION_INFO: The right to view application information.\n - RIGHT_APPLICATION_SETTINGS_BASIC: The right to edit basic application settings.\n - RIGHT_APPLICATION_SETTINGS_API_KEYS: The right to view and edit application API keys.\n - RIGHT_APPLICATION_SETTINGS_COLLABORATORS: The right to view and edit application collaborators.\n - RIGHT_APPLICATION_SETTINGS_PACKAGES: The right to view and edit application packages and associations.\n - RIGHT_APPLICATION_DELETE: The right to delete application.\n - RIGHT_APPLICATION_PURGE: The right to purge application.\n - RIGHT_APPLICATION_DEVICES_READ: The right to view devices in application.\n - RIGHT_APPLICATION_DEVICES_WRITE: The right to create devices in application.\n - RIGHT_APPLICATION_DEVICES_READ_KEYS: The right to view device keys in application.\nNote that keys may not be stored in a way that supports viewing them.\n - RIGHT_APPLICATION_DEVICES_WRITE_KEYS: The right to edit device keys in application.\n - RIGHT_APPLICATION_TRAFFIC_READ: The right to read application traffic (uplink and downlink).\n - RIGHT_APPLICATION_TRAFFIC_UP_WRITE: The right to write uplink application traffic.\n - RIGHT_APPLICATION_TRAFFIC_DOWN_WRITE: The right to write downlink application traffic.\n - RIGHT_APPLICATION_LINK: The right to link as Application to a Network Server for traffic exchange,\ni.e. read uplink and write downlink (API keys only).\nThis right is typically only given to an Application Server.\nThis right implies RIGHT_APPLICATION_INFO, RIGHT_APPLICATION_TRAFFIC_READ,\nand RIGHT_APPLICATION_TRAFFIC_DOWN_WRITE.\n - RIGHT_APPLICATION_ALL: The pseudo-right for all (current and future) application rights.\n - RIGHT_CLIENT_ALL: The pseudo-right for all (current and future) OAuth client rights.\n - RIGHT_CLIENT_INFO: The right to read client information.\n - RIGHT_CLIENT_SETTINGS_BASIC: The right to edit basic client settings.\n - RIGHT_CLIENT_SETTINGS_COLLABORATORS: The right to view and edit client collaborators.\n - RIGHT_CLIENT_DELETE: The right to delete a client.\n - RIGHT_GATEWAY_INFO: The right to view gateway information.\n - RIGHT_GATEWAY_SETTINGS_BASIC: The right to edit basic gateway settings.\n - RIGHT_GATEWAY_SETTINGS_API_KEYS: The right to view and edit gateway API keys.\n - RIGHT_GATEWAY_SETTINGS_COLLABORATORS: The right to view and edit gateway collaborators.\n - RIGHT_GATEWAY_DELETE: The right to delete gateway.\n - RIGHT_GATEWAY_TRAFFIC_READ: The right to read gateway traffic.\n - RIGHT_GATEWAY_TRAFFIC_DOWN_WRITE: The right to write downlink gateway traffic.\n - RIGHT_GATEWAY_LINK: The right to link as Gateway to a Gateway Server for traffic exchange,\ni.e. write uplink and read downlink (API keys only)\nThis right is typically only given to a gateway.\nThis right implies RIGHT_GATEWAY_INFO.\n - RIGHT_GATEWAY_STATUS_READ: The right to view gateway status.\n - RIGHT_GATEWAY_LOCATION_READ: The right to view view gateway location.\n - RIGHT_GATEWAY_WRITE_SECRETS: The right to store secrets associated with this gateway.\n - RIGHT_GATEWAY_READ_SECRETS: The right to retrieve secrets associated with this gateway.\n - RIGHT_GATEWAY_ALL: The pseudo-right for all (current and future) gateway rights.\n - RIGHT_ORGANIZATION_INFO: The right to view organization information.\n - RIGHT_ORGANIZATION_SETTINGS_BASIC: The right to edit basic organization settings.\n - RIGHT_ORGANIZATION_SETTINGS_API_KEYS: The right to view and edit organization API keys.\n - RIGHT_ORGANIZATION_SETTINGS_MEMBERS: The right to view and edit organization members.\n - RIGHT_ORGANIZATION_DELETE: The right to delete organization.\n - RIGHT_ORGANIZATION_APPLICATIONS_LIST: The right to list the applications the organization is a collaborator of.\n - RIGHT_ORGANIZATION_APPLICATIONS_CREATE: The right to create an application under the organization.\n - RIGHT_ORGANIZATION_GATEWAYS_LIST: The right to list the gateways the organization is a collaborator of.\n - RIGHT_ORGANIZATION_GATEWAYS_CREATE: The right to create a gateway under the organization.\n - RIGHT_ORGANIZATION_CLIENTS_LIST: The right to list the OAuth clients the organization is a collaborator of.\n - RIGHT_ORGANIZATION_CLIENTS_CREATE: The right to create an OAuth client under the organization.\n - RIGHT_ORGANIZATION_ADD_AS_COLLABORATOR: The right to add the organization as a collaborator on an existing entity.\n - RIGHT_ORGANIZATION_ALL: The pseudo-right for all (current and future) organization rights.\n - RIGHT_SEND_INVITES: The right to send invites to new users.\nNote that this is not prefixed with \"USER_\"; it is not a right on the user entity.\n - RIGHT_ALL: The pseudo-right for all (current and future) possible rights.", "in": "query", "required": false, "type": "array", @@ -6940,6 +6940,7 @@ "RIGHT_APPLICATION_SETTINGS_COLLABORATORS", "RIGHT_APPLICATION_SETTINGS_PACKAGES", "RIGHT_APPLICATION_DELETE", + "RIGHT_APPLICATION_PURGE", "RIGHT_APPLICATION_DEVICES_READ", "RIGHT_APPLICATION_DEVICES_WRITE", "RIGHT_APPLICATION_DEVICES_READ_KEYS", @@ -28981,6 +28982,7 @@ "RIGHT_APPLICATION_SETTINGS_COLLABORATORS", "RIGHT_APPLICATION_SETTINGS_PACKAGES", "RIGHT_APPLICATION_DELETE", + "RIGHT_APPLICATION_PURGE", "RIGHT_APPLICATION_DEVICES_READ", "RIGHT_APPLICATION_DEVICES_WRITE", "RIGHT_APPLICATION_DEVICES_READ_KEYS", @@ -29025,7 +29027,7 @@ "RIGHT_ALL" ], "default": "right_invalid", - "description": "Right is the enum that defines all the different rights to do something in the network.\n\n - RIGHT_USER_INFO: The right to view user information.\n - RIGHT_USER_SETTINGS_BASIC: The right to edit basic user settings.\n - RIGHT_USER_SETTINGS_API_KEYS: The right to view and edit user API keys.\n - RIGHT_USER_DELETE: The right to delete user account.\n - RIGHT_USER_AUTHORIZED_CLIENTS: The right to view and edit authorized OAuth clients of the user.\n - RIGHT_USER_APPLICATIONS_LIST: The right to list applications the user is a collaborator of.\n - RIGHT_USER_APPLICATIONS_CREATE: The right to create an application under the user account.\n - RIGHT_USER_GATEWAYS_LIST: The right to list gateways the user is a collaborator of.\n - RIGHT_USER_GATEWAYS_CREATE: The right to create a gateway under the account of the user.\n - RIGHT_USER_CLIENTS_LIST: The right to list OAuth clients the user is a collaborator of.\n - RIGHT_USER_CLIENTS_CREATE: The right to create an OAuth client under the account of the user.\n - RIGHT_USER_ORGANIZATIONS_LIST: The right to list organizations the user is a member of.\n - RIGHT_USER_ORGANIZATIONS_CREATE: The right to create an organization under the user account.\n - RIGHT_USER_NOTIFICATIONS_READ: The right to read notifications sent to the user.\n - RIGHT_USER_ALL: The pseudo-right for all (current and future) user rights.\n - RIGHT_APPLICATION_INFO: The right to view application information.\n - RIGHT_APPLICATION_SETTINGS_BASIC: The right to edit basic application settings.\n - RIGHT_APPLICATION_SETTINGS_API_KEYS: The right to view and edit application API keys.\n - RIGHT_APPLICATION_SETTINGS_COLLABORATORS: The right to view and edit application collaborators.\n - RIGHT_APPLICATION_SETTINGS_PACKAGES: The right to view and edit application packages and associations.\n - RIGHT_APPLICATION_DELETE: The right to delete application.\n - RIGHT_APPLICATION_DEVICES_READ: The right to view devices in application.\n - RIGHT_APPLICATION_DEVICES_WRITE: The right to create devices in application.\n - RIGHT_APPLICATION_DEVICES_READ_KEYS: The right to view device keys in application.\nNote that keys may not be stored in a way that supports viewing them.\n - RIGHT_APPLICATION_DEVICES_WRITE_KEYS: The right to edit device keys in application.\n - RIGHT_APPLICATION_TRAFFIC_READ: The right to read application traffic (uplink and downlink).\n - RIGHT_APPLICATION_TRAFFIC_UP_WRITE: The right to write uplink application traffic.\n - RIGHT_APPLICATION_TRAFFIC_DOWN_WRITE: The right to write downlink application traffic.\n - RIGHT_APPLICATION_LINK: The right to link as Application to a Network Server for traffic exchange,\ni.e. read uplink and write downlink (API keys only).\nThis right is typically only given to an Application Server.\nThis right implies RIGHT_APPLICATION_INFO, RIGHT_APPLICATION_TRAFFIC_READ,\nand RIGHT_APPLICATION_TRAFFIC_DOWN_WRITE.\n - RIGHT_APPLICATION_ALL: The pseudo-right for all (current and future) application rights.\n - RIGHT_CLIENT_ALL: The pseudo-right for all (current and future) OAuth client rights.\n - RIGHT_CLIENT_INFO: The right to read client information.\n - RIGHT_CLIENT_SETTINGS_BASIC: The right to edit basic client settings.\n - RIGHT_CLIENT_SETTINGS_COLLABORATORS: The right to view and edit client collaborators.\n - RIGHT_CLIENT_DELETE: The right to delete a client.\n - RIGHT_GATEWAY_INFO: The right to view gateway information.\n - RIGHT_GATEWAY_SETTINGS_BASIC: The right to edit basic gateway settings.\n - RIGHT_GATEWAY_SETTINGS_API_KEYS: The right to view and edit gateway API keys.\n - RIGHT_GATEWAY_SETTINGS_COLLABORATORS: The right to view and edit gateway collaborators.\n - RIGHT_GATEWAY_DELETE: The right to delete gateway.\n - RIGHT_GATEWAY_TRAFFIC_READ: The right to read gateway traffic.\n - RIGHT_GATEWAY_TRAFFIC_DOWN_WRITE: The right to write downlink gateway traffic.\n - RIGHT_GATEWAY_LINK: The right to link as Gateway to a Gateway Server for traffic exchange,\ni.e. write uplink and read downlink (API keys only)\nThis right is typically only given to a gateway.\nThis right implies RIGHT_GATEWAY_INFO.\n - RIGHT_GATEWAY_STATUS_READ: The right to view gateway status.\n - RIGHT_GATEWAY_LOCATION_READ: The right to view view gateway location.\n - RIGHT_GATEWAY_WRITE_SECRETS: The right to store secrets associated with this gateway.\n - RIGHT_GATEWAY_READ_SECRETS: The right to retrieve secrets associated with this gateway.\n - RIGHT_GATEWAY_ALL: The pseudo-right for all (current and future) gateway rights.\n - RIGHT_ORGANIZATION_INFO: The right to view organization information.\n - RIGHT_ORGANIZATION_SETTINGS_BASIC: The right to edit basic organization settings.\n - RIGHT_ORGANIZATION_SETTINGS_API_KEYS: The right to view and edit organization API keys.\n - RIGHT_ORGANIZATION_SETTINGS_MEMBERS: The right to view and edit organization members.\n - RIGHT_ORGANIZATION_DELETE: The right to delete organization.\n - RIGHT_ORGANIZATION_APPLICATIONS_LIST: The right to list the applications the organization is a collaborator of.\n - RIGHT_ORGANIZATION_APPLICATIONS_CREATE: The right to create an application under the organization.\n - RIGHT_ORGANIZATION_GATEWAYS_LIST: The right to list the gateways the organization is a collaborator of.\n - RIGHT_ORGANIZATION_GATEWAYS_CREATE: The right to create a gateway under the organization.\n - RIGHT_ORGANIZATION_CLIENTS_LIST: The right to list the OAuth clients the organization is a collaborator of.\n - RIGHT_ORGANIZATION_CLIENTS_CREATE: The right to create an OAuth client under the organization.\n - RIGHT_ORGANIZATION_ADD_AS_COLLABORATOR: The right to add the organization as a collaborator on an existing entity.\n - RIGHT_ORGANIZATION_ALL: The pseudo-right for all (current and future) organization rights.\n - RIGHT_SEND_INVITES: The right to send invites to new users.\nNote that this is not prefixed with \"USER_\"; it is not a right on the user entity.\n - RIGHT_ALL: The pseudo-right for all (current and future) possible rights." + "description": "Right is the enum that defines all the different rights to do something in the network.\n\n - RIGHT_USER_INFO: The right to view user information.\n - RIGHT_USER_SETTINGS_BASIC: The right to edit basic user settings.\n - RIGHT_USER_SETTINGS_API_KEYS: The right to view and edit user API keys.\n - RIGHT_USER_DELETE: The right to delete user account.\n - RIGHT_USER_AUTHORIZED_CLIENTS: The right to view and edit authorized OAuth clients of the user.\n - RIGHT_USER_APPLICATIONS_LIST: The right to list applications the user is a collaborator of.\n - RIGHT_USER_APPLICATIONS_CREATE: The right to create an application under the user account.\n - RIGHT_USER_GATEWAYS_LIST: The right to list gateways the user is a collaborator of.\n - RIGHT_USER_GATEWAYS_CREATE: The right to create a gateway under the account of the user.\n - RIGHT_USER_CLIENTS_LIST: The right to list OAuth clients the user is a collaborator of.\n - RIGHT_USER_CLIENTS_CREATE: The right to create an OAuth client under the account of the user.\n - RIGHT_USER_ORGANIZATIONS_LIST: The right to list organizations the user is a member of.\n - RIGHT_USER_ORGANIZATIONS_CREATE: The right to create an organization under the user account.\n - RIGHT_USER_NOTIFICATIONS_READ: The right to read notifications sent to the user.\n - RIGHT_USER_ALL: The pseudo-right for all (current and future) user rights.\n - RIGHT_APPLICATION_INFO: The right to view application information.\n - RIGHT_APPLICATION_SETTINGS_BASIC: The right to edit basic application settings.\n - RIGHT_APPLICATION_SETTINGS_API_KEYS: The right to view and edit application API keys.\n - RIGHT_APPLICATION_SETTINGS_COLLABORATORS: The right to view and edit application collaborators.\n - RIGHT_APPLICATION_SETTINGS_PACKAGES: The right to view and edit application packages and associations.\n - RIGHT_APPLICATION_DELETE: The right to delete application.\n - RIGHT_APPLICATION_PURGE: The right to purge application.\n - RIGHT_APPLICATION_DEVICES_READ: The right to view devices in application.\n - RIGHT_APPLICATION_DEVICES_WRITE: The right to create devices in application.\n - RIGHT_APPLICATION_DEVICES_READ_KEYS: The right to view device keys in application.\nNote that keys may not be stored in a way that supports viewing them.\n - RIGHT_APPLICATION_DEVICES_WRITE_KEYS: The right to edit device keys in application.\n - RIGHT_APPLICATION_TRAFFIC_READ: The right to read application traffic (uplink and downlink).\n - RIGHT_APPLICATION_TRAFFIC_UP_WRITE: The right to write uplink application traffic.\n - RIGHT_APPLICATION_TRAFFIC_DOWN_WRITE: The right to write downlink application traffic.\n - RIGHT_APPLICATION_LINK: The right to link as Application to a Network Server for traffic exchange,\ni.e. read uplink and write downlink (API keys only).\nThis right is typically only given to an Application Server.\nThis right implies RIGHT_APPLICATION_INFO, RIGHT_APPLICATION_TRAFFIC_READ,\nand RIGHT_APPLICATION_TRAFFIC_DOWN_WRITE.\n - RIGHT_APPLICATION_ALL: The pseudo-right for all (current and future) application rights.\n - RIGHT_CLIENT_ALL: The pseudo-right for all (current and future) OAuth client rights.\n - RIGHT_CLIENT_INFO: The right to read client information.\n - RIGHT_CLIENT_SETTINGS_BASIC: The right to edit basic client settings.\n - RIGHT_CLIENT_SETTINGS_COLLABORATORS: The right to view and edit client collaborators.\n - RIGHT_CLIENT_DELETE: The right to delete a client.\n - RIGHT_GATEWAY_INFO: The right to view gateway information.\n - RIGHT_GATEWAY_SETTINGS_BASIC: The right to edit basic gateway settings.\n - RIGHT_GATEWAY_SETTINGS_API_KEYS: The right to view and edit gateway API keys.\n - RIGHT_GATEWAY_SETTINGS_COLLABORATORS: The right to view and edit gateway collaborators.\n - RIGHT_GATEWAY_DELETE: The right to delete gateway.\n - RIGHT_GATEWAY_TRAFFIC_READ: The right to read gateway traffic.\n - RIGHT_GATEWAY_TRAFFIC_DOWN_WRITE: The right to write downlink gateway traffic.\n - RIGHT_GATEWAY_LINK: The right to link as Gateway to a Gateway Server for traffic exchange,\ni.e. write uplink and read downlink (API keys only)\nThis right is typically only given to a gateway.\nThis right implies RIGHT_GATEWAY_INFO.\n - RIGHT_GATEWAY_STATUS_READ: The right to view gateway status.\n - RIGHT_GATEWAY_LOCATION_READ: The right to view view gateway location.\n - RIGHT_GATEWAY_WRITE_SECRETS: The right to store secrets associated with this gateway.\n - RIGHT_GATEWAY_READ_SECRETS: The right to retrieve secrets associated with this gateway.\n - RIGHT_GATEWAY_ALL: The pseudo-right for all (current and future) gateway rights.\n - RIGHT_ORGANIZATION_INFO: The right to view organization information.\n - RIGHT_ORGANIZATION_SETTINGS_BASIC: The right to edit basic organization settings.\n - RIGHT_ORGANIZATION_SETTINGS_API_KEYS: The right to view and edit organization API keys.\n - RIGHT_ORGANIZATION_SETTINGS_MEMBERS: The right to view and edit organization members.\n - RIGHT_ORGANIZATION_DELETE: The right to delete organization.\n - RIGHT_ORGANIZATION_APPLICATIONS_LIST: The right to list the applications the organization is a collaborator of.\n - RIGHT_ORGANIZATION_APPLICATIONS_CREATE: The right to create an application under the organization.\n - RIGHT_ORGANIZATION_GATEWAYS_LIST: The right to list the gateways the organization is a collaborator of.\n - RIGHT_ORGANIZATION_GATEWAYS_CREATE: The right to create a gateway under the organization.\n - RIGHT_ORGANIZATION_CLIENTS_LIST: The right to list the OAuth clients the organization is a collaborator of.\n - RIGHT_ORGANIZATION_CLIENTS_CREATE: The right to create an OAuth client under the organization.\n - RIGHT_ORGANIZATION_ADD_AS_COLLABORATOR: The right to add the organization as a collaborator on an existing entity.\n - RIGHT_ORGANIZATION_ALL: The pseudo-right for all (current and future) organization rights.\n - RIGHT_SEND_INVITES: The right to send invites to new users.\nNote that this is not prefixed with \"USER_\"; it is not a right on the user entity.\n - RIGHT_ALL: The pseudo-right for all (current and future) possible rights." }, "v3Rights": { "type": "object", diff --git a/api/ttn/lorawan/v3/rights.proto b/api/ttn/lorawan/v3/rights.proto index 6a3096c48f..a6f7eb569b 100644 --- a/api/ttn/lorawan/v3/rights.proto +++ b/api/ttn/lorawan/v3/rights.proto @@ -76,6 +76,8 @@ enum Right { RIGHT_APPLICATION_SETTINGS_PACKAGES = 56; // The right to delete application. RIGHT_APPLICATION_DELETE = 19; + // The right to purge application. + RIGHT_APPLICATION_PURGE = 64; // The right to view devices in application. RIGHT_APPLICATION_DEVICES_READ = 20; // The right to create devices in application. @@ -175,7 +177,7 @@ enum Right { // The pseudo-right for all (current and future) possible rights. RIGHT_ALL = 55; - // Next value: 64 + // Next value: 65 } message Rights { diff --git a/pkg/ttnpb/rights.pb.go b/pkg/ttnpb/rights.pb.go index 9583a7ef45..73d9f39e33 100644 --- a/pkg/ttnpb/rights.pb.go +++ b/pkg/ttnpb/rights.pb.go @@ -85,6 +85,8 @@ const ( Right_RIGHT_APPLICATION_SETTINGS_PACKAGES Right = 56 // The right to delete application. Right_RIGHT_APPLICATION_DELETE Right = 19 + // The right to purge application. + Right_RIGHT_APPLICATION_PURGE Right = 64 // The right to view devices in application. Right_RIGHT_APPLICATION_DEVICES_READ Right = 20 // The right to create devices in application. @@ -205,6 +207,7 @@ var ( 18: "RIGHT_APPLICATION_SETTINGS_COLLABORATORS", 56: "RIGHT_APPLICATION_SETTINGS_PACKAGES", 19: "RIGHT_APPLICATION_DELETE", + 64: "RIGHT_APPLICATION_PURGE", 20: "RIGHT_APPLICATION_DEVICES_READ", 21: "RIGHT_APPLICATION_DEVICES_WRITE", 22: "RIGHT_APPLICATION_DEVICES_READ_KEYS", @@ -271,6 +274,7 @@ var ( "RIGHT_APPLICATION_SETTINGS_COLLABORATORS": 18, "RIGHT_APPLICATION_SETTINGS_PACKAGES": 56, "RIGHT_APPLICATION_DELETE": 19, + "RIGHT_APPLICATION_PURGE": 64, "RIGHT_APPLICATION_DEVICES_READ": 20, "RIGHT_APPLICATION_DEVICES_WRITE": 21, "RIGHT_APPLICATION_DEVICES_READ_KEYS": 22, @@ -766,7 +770,7 @@ var file_ttn_lorawan_v3_rights_proto_rawDesc = []byte{ 0x61, 0x62, 0x6f, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x43, 0x6f, 0x6c, 0x6c, 0x61, 0x62, 0x6f, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x0d, 0x63, - 0x6f, 0x6c, 0x6c, 0x61, 0x62, 0x6f, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x2a, 0xdf, 0x10, 0x0a, + 0x6f, 0x6c, 0x6c, 0x61, 0x62, 0x6f, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x2a, 0xfc, 0x10, 0x0a, 0x05, 0x52, 0x69, 0x67, 0x68, 0x74, 0x12, 0x11, 0x0a, 0x0d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x5f, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x01, 0x12, 0x1d, @@ -811,100 +815,102 @@ var file_ttn_lorawan_v3_rights_proto_rawDesc = []byte{ 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x50, 0x41, 0x43, 0x4b, 0x41, 0x47, 0x45, 0x53, 0x10, 0x38, 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, - 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x13, 0x12, 0x22, 0x0a, 0x1e, 0x52, 0x49, 0x47, 0x48, - 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x45, - 0x56, 0x49, 0x43, 0x45, 0x53, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x10, 0x14, 0x12, 0x23, 0x0a, 0x1f, - 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, - 0x4e, 0x5f, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x53, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x10, - 0x15, 0x12, 0x27, 0x0a, 0x23, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, - 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x53, 0x5f, 0x52, - 0x45, 0x41, 0x44, 0x5f, 0x4b, 0x45, 0x59, 0x53, 0x10, 0x16, 0x12, 0x28, 0x0a, 0x24, 0x52, 0x49, - 0x47, 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, - 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x53, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x5f, 0x4b, 0x45, - 0x59, 0x53, 0x10, 0x17, 0x12, 0x22, 0x0a, 0x1e, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x50, - 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x54, 0x52, 0x41, 0x46, 0x46, 0x49, - 0x43, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x10, 0x18, 0x12, 0x26, 0x0a, 0x22, 0x52, 0x49, 0x47, 0x48, - 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x54, 0x52, - 0x41, 0x46, 0x46, 0x49, 0x43, 0x5f, 0x55, 0x50, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x10, 0x19, - 0x12, 0x28, 0x0a, 0x24, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, - 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x54, 0x52, 0x41, 0x46, 0x46, 0x49, 0x43, 0x5f, 0x44, 0x4f, - 0x57, 0x4e, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x10, 0x1a, 0x12, 0x1a, 0x0a, 0x16, 0x52, 0x49, - 0x47, 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, - 0x4c, 0x49, 0x4e, 0x4b, 0x10, 0x1b, 0x12, 0x19, 0x0a, 0x15, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, - 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x4c, 0x4c, 0x10, - 0x1c, 0x12, 0x14, 0x0a, 0x10, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, - 0x54, 0x5f, 0x41, 0x4c, 0x4c, 0x10, 0x1d, 0x12, 0x15, 0x0a, 0x11, 0x52, 0x49, 0x47, 0x48, 0x54, - 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x3c, 0x12, 0x1f, - 0x0a, 0x1b, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x53, - 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x42, 0x41, 0x53, 0x49, 0x43, 0x10, 0x3d, 0x12, - 0x27, 0x0a, 0x23, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, - 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x43, 0x4f, 0x4c, 0x4c, 0x41, 0x42, 0x4f, - 0x52, 0x41, 0x54, 0x4f, 0x52, 0x53, 0x10, 0x3e, 0x12, 0x17, 0x0a, 0x13, 0x52, 0x49, 0x47, 0x48, - 0x54, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, - 0x3f, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, - 0x41, 0x59, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x1e, 0x12, 0x20, 0x0a, 0x1c, 0x52, 0x49, 0x47, - 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, - 0x4e, 0x47, 0x53, 0x5f, 0x42, 0x41, 0x53, 0x49, 0x43, 0x10, 0x1f, 0x12, 0x23, 0x0a, 0x1f, 0x52, - 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x53, 0x45, 0x54, - 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x41, 0x50, 0x49, 0x5f, 0x4b, 0x45, 0x59, 0x53, 0x10, 0x20, - 0x12, 0x28, 0x0a, 0x24, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, - 0x59, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x43, 0x4f, 0x4c, 0x4c, 0x41, - 0x42, 0x4f, 0x52, 0x41, 0x54, 0x4f, 0x52, 0x53, 0x10, 0x21, 0x12, 0x18, 0x0a, 0x14, 0x52, 0x49, - 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x44, 0x45, 0x4c, 0x45, - 0x54, 0x45, 0x10, 0x22, 0x12, 0x1e, 0x0a, 0x1a, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, - 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x54, 0x52, 0x41, 0x46, 0x46, 0x49, 0x43, 0x5f, 0x52, 0x45, - 0x41, 0x44, 0x10, 0x23, 0x12, 0x24, 0x0a, 0x20, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, - 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x54, 0x52, 0x41, 0x46, 0x46, 0x49, 0x43, 0x5f, 0x44, 0x4f, - 0x57, 0x4e, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x10, 0x24, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x49, - 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x4c, 0x49, 0x4e, 0x4b, - 0x10, 0x25, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, - 0x57, 0x41, 0x59, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x10, - 0x26, 0x12, 0x1f, 0x0a, 0x1b, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, - 0x41, 0x59, 0x5f, 0x4c, 0x4f, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x52, 0x45, 0x41, 0x44, - 0x10, 0x27, 0x12, 0x1f, 0x0a, 0x1b, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, - 0x57, 0x41, 0x59, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x5f, 0x53, 0x45, 0x43, 0x52, 0x45, 0x54, - 0x53, 0x10, 0x39, 0x12, 0x1e, 0x0a, 0x1a, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, - 0x45, 0x57, 0x41, 0x59, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x53, 0x45, 0x43, 0x52, 0x45, 0x54, - 0x53, 0x10, 0x3a, 0x12, 0x15, 0x0a, 0x11, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, - 0x45, 0x57, 0x41, 0x59, 0x5f, 0x41, 0x4c, 0x4c, 0x10, 0x28, 0x12, 0x1b, 0x0a, 0x17, 0x52, 0x49, - 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, - 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x29, 0x12, 0x25, 0x0a, 0x21, 0x52, 0x49, 0x47, 0x48, 0x54, - 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x45, - 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x42, 0x41, 0x53, 0x49, 0x43, 0x10, 0x2a, 0x12, 0x28, - 0x0a, 0x24, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, - 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x41, 0x50, - 0x49, 0x5f, 0x4b, 0x45, 0x59, 0x53, 0x10, 0x2b, 0x12, 0x27, 0x0a, 0x23, 0x52, 0x49, 0x47, 0x48, - 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, - 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, 0x53, 0x10, - 0x2c, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, - 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x2d, - 0x12, 0x28, 0x0a, 0x24, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, - 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, - 0x4f, 0x4e, 0x53, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x2e, 0x12, 0x2a, 0x0a, 0x26, 0x52, 0x49, - 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, - 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x5f, 0x43, 0x52, - 0x45, 0x41, 0x54, 0x45, 0x10, 0x2f, 0x12, 0x24, 0x0a, 0x20, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, - 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x47, 0x41, 0x54, - 0x45, 0x57, 0x41, 0x59, 0x53, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x30, 0x12, 0x26, 0x0a, 0x22, - 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, - 0x4f, 0x4e, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x53, 0x5f, 0x43, 0x52, 0x45, 0x41, - 0x54, 0x45, 0x10, 0x31, 0x12, 0x23, 0x0a, 0x1f, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, - 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, - 0x54, 0x53, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x32, 0x12, 0x25, 0x0a, 0x21, 0x52, 0x49, 0x47, + 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x13, 0x12, 0x1b, 0x0a, 0x17, 0x52, 0x49, 0x47, 0x48, + 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x50, 0x55, + 0x52, 0x47, 0x45, 0x10, 0x40, 0x12, 0x22, 0x0a, 0x1e, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, + 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x56, 0x49, 0x43, + 0x45, 0x53, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x10, 0x14, 0x12, 0x23, 0x0a, 0x1f, 0x52, 0x49, 0x47, + 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x44, + 0x45, 0x56, 0x49, 0x43, 0x45, 0x53, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x10, 0x15, 0x12, 0x27, + 0x0a, 0x23, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, + 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x53, 0x5f, 0x52, 0x45, 0x41, 0x44, + 0x5f, 0x4b, 0x45, 0x59, 0x53, 0x10, 0x16, 0x12, 0x28, 0x0a, 0x24, 0x52, 0x49, 0x47, 0x48, 0x54, + 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x56, + 0x49, 0x43, 0x45, 0x53, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x5f, 0x4b, 0x45, 0x59, 0x53, 0x10, + 0x17, 0x12, 0x22, 0x0a, 0x1e, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, + 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x54, 0x52, 0x41, 0x46, 0x46, 0x49, 0x43, 0x5f, 0x52, + 0x45, 0x41, 0x44, 0x10, 0x18, 0x12, 0x26, 0x0a, 0x22, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, + 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x54, 0x52, 0x41, 0x46, 0x46, + 0x49, 0x43, 0x5f, 0x55, 0x50, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x10, 0x19, 0x12, 0x28, 0x0a, + 0x24, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, + 0x4f, 0x4e, 0x5f, 0x54, 0x52, 0x41, 0x46, 0x46, 0x49, 0x43, 0x5f, 0x44, 0x4f, 0x57, 0x4e, 0x5f, + 0x57, 0x52, 0x49, 0x54, 0x45, 0x10, 0x1a, 0x12, 0x1a, 0x0a, 0x16, 0x52, 0x49, 0x47, 0x48, 0x54, + 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4c, 0x49, 0x4e, + 0x4b, 0x10, 0x1b, 0x12, 0x19, 0x0a, 0x15, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, + 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x4c, 0x4c, 0x10, 0x1c, 0x12, 0x14, + 0x0a, 0x10, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x41, + 0x4c, 0x4c, 0x10, 0x1d, 0x12, 0x15, 0x0a, 0x11, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x43, 0x4c, + 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x3c, 0x12, 0x1f, 0x0a, 0x1b, 0x52, + 0x49, 0x47, 0x48, 0x54, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x53, 0x45, 0x54, 0x54, + 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x42, 0x41, 0x53, 0x49, 0x43, 0x10, 0x3d, 0x12, 0x27, 0x0a, 0x23, + 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x53, 0x45, 0x54, + 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x43, 0x4f, 0x4c, 0x4c, 0x41, 0x42, 0x4f, 0x52, 0x41, 0x54, + 0x4f, 0x52, 0x53, 0x10, 0x3e, 0x12, 0x17, 0x0a, 0x13, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x43, + 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x3f, 0x12, 0x16, + 0x0a, 0x12, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, + 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x1e, 0x12, 0x20, 0x0a, 0x1c, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, + 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, + 0x5f, 0x42, 0x41, 0x53, 0x49, 0x43, 0x10, 0x1f, 0x12, 0x23, 0x0a, 0x1f, 0x52, 0x49, 0x47, 0x48, + 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, + 0x47, 0x53, 0x5f, 0x41, 0x50, 0x49, 0x5f, 0x4b, 0x45, 0x59, 0x53, 0x10, 0x20, 0x12, 0x28, 0x0a, + 0x24, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x53, + 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x43, 0x4f, 0x4c, 0x4c, 0x41, 0x42, 0x4f, 0x52, + 0x41, 0x54, 0x4f, 0x52, 0x53, 0x10, 0x21, 0x12, 0x18, 0x0a, 0x14, 0x52, 0x49, 0x47, 0x48, 0x54, + 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, + 0x22, 0x12, 0x1e, 0x0a, 0x1a, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, + 0x41, 0x59, 0x5f, 0x54, 0x52, 0x41, 0x46, 0x46, 0x49, 0x43, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x10, + 0x23, 0x12, 0x24, 0x0a, 0x20, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, + 0x41, 0x59, 0x5f, 0x54, 0x52, 0x41, 0x46, 0x46, 0x49, 0x43, 0x5f, 0x44, 0x4f, 0x57, 0x4e, 0x5f, + 0x57, 0x52, 0x49, 0x54, 0x45, 0x10, 0x24, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x49, 0x47, 0x48, 0x54, + 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x4c, 0x49, 0x4e, 0x4b, 0x10, 0x25, 0x12, + 0x1d, 0x0a, 0x19, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, + 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x10, 0x26, 0x12, 0x1f, + 0x0a, 0x1b, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, + 0x4c, 0x4f, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x10, 0x27, 0x12, + 0x1f, 0x0a, 0x1b, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, + 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x5f, 0x53, 0x45, 0x43, 0x52, 0x45, 0x54, 0x53, 0x10, 0x39, + 0x12, 0x1e, 0x0a, 0x1a, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, + 0x59, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x53, 0x45, 0x43, 0x52, 0x45, 0x54, 0x53, 0x10, 0x3a, + 0x12, 0x15, 0x0a, 0x11, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, + 0x59, 0x5f, 0x41, 0x4c, 0x4c, 0x10, 0x28, 0x12, 0x1b, 0x0a, 0x17, 0x52, 0x49, 0x47, 0x48, 0x54, + 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x49, 0x4e, + 0x46, 0x4f, 0x10, 0x29, 0x12, 0x25, 0x0a, 0x21, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, + 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, + 0x4e, 0x47, 0x53, 0x5f, 0x42, 0x41, 0x53, 0x49, 0x43, 0x10, 0x2a, 0x12, 0x28, 0x0a, 0x24, 0x52, + 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, + 0x4e, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x41, 0x50, 0x49, 0x5f, 0x4b, + 0x45, 0x59, 0x53, 0x10, 0x2b, 0x12, 0x27, 0x0a, 0x23, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, + 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x45, 0x54, 0x54, + 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, 0x53, 0x10, 0x2c, 0x12, 0x1d, + 0x0a, 0x19, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, + 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x2d, 0x12, 0x28, 0x0a, + 0x24, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, + 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x53, + 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x2e, 0x12, 0x2a, 0x0a, 0x26, 0x52, 0x49, 0x47, 0x48, 0x54, + 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x50, + 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, + 0x45, 0x10, 0x2f, 0x12, 0x24, 0x0a, 0x20, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, + 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, + 0x59, 0x53, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x30, 0x12, 0x26, 0x0a, 0x22, 0x52, 0x49, 0x47, + 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, + 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x53, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, + 0x31, 0x12, 0x23, 0x0a, 0x1f, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, + 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x53, 0x5f, + 0x4c, 0x49, 0x53, 0x54, 0x10, 0x32, 0x12, 0x25, 0x0a, 0x21, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, + 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x43, 0x4c, 0x49, + 0x45, 0x4e, 0x54, 0x53, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, 0x33, 0x12, 0x2a, 0x0a, + 0x26, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, + 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x44, 0x44, 0x5f, 0x41, 0x53, 0x5f, 0x43, 0x4f, 0x4c, 0x4c, 0x41, + 0x42, 0x4f, 0x52, 0x41, 0x54, 0x4f, 0x52, 0x10, 0x34, 0x12, 0x1a, 0x0a, 0x16, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, - 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x53, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, 0x33, - 0x12, 0x2a, 0x0a, 0x26, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, - 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x44, 0x44, 0x5f, 0x41, 0x53, 0x5f, 0x43, 0x4f, - 0x4c, 0x4c, 0x41, 0x42, 0x4f, 0x52, 0x41, 0x54, 0x4f, 0x52, 0x10, 0x34, 0x12, 0x1a, 0x0a, 0x16, - 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, - 0x4f, 0x4e, 0x5f, 0x41, 0x4c, 0x4c, 0x10, 0x35, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x49, 0x47, 0x48, - 0x54, 0x5f, 0x53, 0x45, 0x4e, 0x44, 0x5f, 0x49, 0x4e, 0x56, 0x49, 0x54, 0x45, 0x53, 0x10, 0x36, - 0x12, 0x0d, 0x0a, 0x09, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x4c, 0x4c, 0x10, 0x37, 0x1a, - 0x0d, 0xea, 0xaa, 0x19, 0x09, 0x18, 0x01, 0x2a, 0x05, 0x52, 0x49, 0x47, 0x48, 0x54, 0x42, 0x31, - 0x5a, 0x2f, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, - 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, - 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x74, 0x6e, 0x70, - 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x41, 0x4c, 0x4c, 0x10, 0x35, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x53, + 0x45, 0x4e, 0x44, 0x5f, 0x49, 0x4e, 0x56, 0x49, 0x54, 0x45, 0x53, 0x10, 0x36, 0x12, 0x0d, 0x0a, + 0x09, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x4c, 0x4c, 0x10, 0x37, 0x1a, 0x0d, 0xea, 0xaa, + 0x19, 0x09, 0x18, 0x01, 0x2a, 0x05, 0x52, 0x49, 0x47, 0x48, 0x54, 0x42, 0x31, 0x5a, 0x2f, 0x67, + 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, + 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63, + 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x74, 0x6e, 0x70, 0x62, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/pkg/ttnpb/rights_json.pb.go b/pkg/ttnpb/rights_json.pb.go index 1a1f1277af..95e98d5bba 100644 --- a/pkg/ttnpb/rights_json.pb.go +++ b/pkg/ttnpb/rights_json.pb.go @@ -49,6 +49,7 @@ var Right_customvalue = map[string]int32{ "APPLICATION_SETTINGS_COLLABORATORS": 18, "APPLICATION_SETTINGS_PACKAGES": 56, "APPLICATION_DELETE": 19, + "APPLICATION_PURGE": 64, "APPLICATION_DEVICES_READ": 20, "APPLICATION_DEVICES_WRITE": 21, "APPLICATION_DEVICES_READ_KEYS": 22, diff --git a/sdk/js/generated/api.json b/sdk/js/generated/api.json index e3ccb712e0..7f2ecbdd1b 100644 --- a/sdk/js/generated/api.json +++ b/sdk/js/generated/api.json @@ -49824,6 +49824,11 @@ "number": "19", "description": "The right to delete application." }, + { + "name": "RIGHT_APPLICATION_PURGE", + "number": "64", + "description": "The right to purge application." + }, { "name": "RIGHT_APPLICATION_DEVICES_READ", "number": "20", From bd7974847cf297628e44a0e573d107753cd20e0f Mon Sep 17 00:00:00 2001 From: Nicholas Cristofaro Date: Mon, 25 Nov 2024 10:04:11 -0300 Subject: [PATCH 09/40] is: Update purgeApplication to check rights --- pkg/identityserver/application_registry.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pkg/identityserver/application_registry.go b/pkg/identityserver/application_registry.go index 605810f675..e2c587c54b 100644 --- a/pkg/identityserver/application_registry.go +++ b/pkg/identityserver/application_registry.go @@ -422,6 +422,11 @@ func (is *IdentityServer) purgeApplication( if !is.IsAdmin(ctx) { return nil, errAdminsPurgeApplications.New() } + if err := rights.RequireApplication( + store.WithSoftDeleted(ctx, false), ids, ttnpb.Right_RIGHT_APPLICATION_PURGE, + ); err != nil { + return nil, err + } err := is.store.Transact(ctx, func(ctx context.Context, st store.Store) error { total, err := st.CountEndDevices(ctx, ids) if err != nil { From dddd0e753486055be98c96234e70c1dcf5348765 Mon Sep 17 00:00:00 2001 From: Nicholas Cristofaro Date: Mon, 25 Nov 2024 10:07:52 -0300 Subject: [PATCH 10/40] api: Add RIGHT_ORGANIZATION_PURGE --- api/ttn/lorawan/v3/api.md | 1 + api/ttn/lorawan/v3/api.swagger.json | 6 ++- api/ttn/lorawan/v3/rights.proto | 4 +- pkg/ttnpb/rights.pb.go | 64 ++++++++++++++++------------- pkg/ttnpb/rights_json.pb.go | 1 + sdk/js/generated/api.json | 5 +++ 6 files changed, 49 insertions(+), 32 deletions(-) diff --git a/api/ttn/lorawan/v3/api.md b/api/ttn/lorawan/v3/api.md index 6d13d53819..7d7d8b0de4 100644 --- a/api/ttn/lorawan/v3/api.md +++ b/api/ttn/lorawan/v3/api.md @@ -11026,6 +11026,7 @@ Right is the enum that defines all the different rights to do something in the n | `RIGHT_ORGANIZATION_SETTINGS_API_KEYS` | 43 | The right to view and edit organization API keys. | | `RIGHT_ORGANIZATION_SETTINGS_MEMBERS` | 44 | The right to view and edit organization members. | | `RIGHT_ORGANIZATION_DELETE` | 45 | The right to delete organization. | +| `RIGHT_ORGANIZATION_PURGE` | 65 | The right to purge organization. | | `RIGHT_ORGANIZATION_APPLICATIONS_LIST` | 46 | The right to list the applications the organization is a collaborator of. | | `RIGHT_ORGANIZATION_APPLICATIONS_CREATE` | 47 | The right to create an application under the organization. | | `RIGHT_ORGANIZATION_GATEWAYS_LIST` | 48 | The right to list the gateways the organization is a collaborator of. | diff --git a/api/ttn/lorawan/v3/api.swagger.json b/api/ttn/lorawan/v3/api.swagger.json index 35bba8cf1f..7439b06c9a 100644 --- a/api/ttn/lorawan/v3/api.swagger.json +++ b/api/ttn/lorawan/v3/api.swagger.json @@ -6911,7 +6911,7 @@ "parameters": [ { "name": "required.rights", - "description": " - RIGHT_USER_INFO: The right to view user information.\n - RIGHT_USER_SETTINGS_BASIC: The right to edit basic user settings.\n - RIGHT_USER_SETTINGS_API_KEYS: The right to view and edit user API keys.\n - RIGHT_USER_DELETE: The right to delete user account.\n - RIGHT_USER_AUTHORIZED_CLIENTS: The right to view and edit authorized OAuth clients of the user.\n - RIGHT_USER_APPLICATIONS_LIST: The right to list applications the user is a collaborator of.\n - RIGHT_USER_APPLICATIONS_CREATE: The right to create an application under the user account.\n - RIGHT_USER_GATEWAYS_LIST: The right to list gateways the user is a collaborator of.\n - RIGHT_USER_GATEWAYS_CREATE: The right to create a gateway under the account of the user.\n - RIGHT_USER_CLIENTS_LIST: The right to list OAuth clients the user is a collaborator of.\n - RIGHT_USER_CLIENTS_CREATE: The right to create an OAuth client under the account of the user.\n - RIGHT_USER_ORGANIZATIONS_LIST: The right to list organizations the user is a member of.\n - RIGHT_USER_ORGANIZATIONS_CREATE: The right to create an organization under the user account.\n - RIGHT_USER_NOTIFICATIONS_READ: The right to read notifications sent to the user.\n - RIGHT_USER_ALL: The pseudo-right for all (current and future) user rights.\n - RIGHT_APPLICATION_INFO: The right to view application information.\n - RIGHT_APPLICATION_SETTINGS_BASIC: The right to edit basic application settings.\n - RIGHT_APPLICATION_SETTINGS_API_KEYS: The right to view and edit application API keys.\n - RIGHT_APPLICATION_SETTINGS_COLLABORATORS: The right to view and edit application collaborators.\n - RIGHT_APPLICATION_SETTINGS_PACKAGES: The right to view and edit application packages and associations.\n - RIGHT_APPLICATION_DELETE: The right to delete application.\n - RIGHT_APPLICATION_PURGE: The right to purge application.\n - RIGHT_APPLICATION_DEVICES_READ: The right to view devices in application.\n - RIGHT_APPLICATION_DEVICES_WRITE: The right to create devices in application.\n - RIGHT_APPLICATION_DEVICES_READ_KEYS: The right to view device keys in application.\nNote that keys may not be stored in a way that supports viewing them.\n - RIGHT_APPLICATION_DEVICES_WRITE_KEYS: The right to edit device keys in application.\n - RIGHT_APPLICATION_TRAFFIC_READ: The right to read application traffic (uplink and downlink).\n - RIGHT_APPLICATION_TRAFFIC_UP_WRITE: The right to write uplink application traffic.\n - RIGHT_APPLICATION_TRAFFIC_DOWN_WRITE: The right to write downlink application traffic.\n - RIGHT_APPLICATION_LINK: The right to link as Application to a Network Server for traffic exchange,\ni.e. read uplink and write downlink (API keys only).\nThis right is typically only given to an Application Server.\nThis right implies RIGHT_APPLICATION_INFO, RIGHT_APPLICATION_TRAFFIC_READ,\nand RIGHT_APPLICATION_TRAFFIC_DOWN_WRITE.\n - RIGHT_APPLICATION_ALL: The pseudo-right for all (current and future) application rights.\n - RIGHT_CLIENT_ALL: The pseudo-right for all (current and future) OAuth client rights.\n - RIGHT_CLIENT_INFO: The right to read client information.\n - RIGHT_CLIENT_SETTINGS_BASIC: The right to edit basic client settings.\n - RIGHT_CLIENT_SETTINGS_COLLABORATORS: The right to view and edit client collaborators.\n - RIGHT_CLIENT_DELETE: The right to delete a client.\n - RIGHT_GATEWAY_INFO: The right to view gateway information.\n - RIGHT_GATEWAY_SETTINGS_BASIC: The right to edit basic gateway settings.\n - RIGHT_GATEWAY_SETTINGS_API_KEYS: The right to view and edit gateway API keys.\n - RIGHT_GATEWAY_SETTINGS_COLLABORATORS: The right to view and edit gateway collaborators.\n - RIGHT_GATEWAY_DELETE: The right to delete gateway.\n - RIGHT_GATEWAY_TRAFFIC_READ: The right to read gateway traffic.\n - RIGHT_GATEWAY_TRAFFIC_DOWN_WRITE: The right to write downlink gateway traffic.\n - RIGHT_GATEWAY_LINK: The right to link as Gateway to a Gateway Server for traffic exchange,\ni.e. write uplink and read downlink (API keys only)\nThis right is typically only given to a gateway.\nThis right implies RIGHT_GATEWAY_INFO.\n - RIGHT_GATEWAY_STATUS_READ: The right to view gateway status.\n - RIGHT_GATEWAY_LOCATION_READ: The right to view view gateway location.\n - RIGHT_GATEWAY_WRITE_SECRETS: The right to store secrets associated with this gateway.\n - RIGHT_GATEWAY_READ_SECRETS: The right to retrieve secrets associated with this gateway.\n - RIGHT_GATEWAY_ALL: The pseudo-right for all (current and future) gateway rights.\n - RIGHT_ORGANIZATION_INFO: The right to view organization information.\n - RIGHT_ORGANIZATION_SETTINGS_BASIC: The right to edit basic organization settings.\n - RIGHT_ORGANIZATION_SETTINGS_API_KEYS: The right to view and edit organization API keys.\n - RIGHT_ORGANIZATION_SETTINGS_MEMBERS: The right to view and edit organization members.\n - RIGHT_ORGANIZATION_DELETE: The right to delete organization.\n - RIGHT_ORGANIZATION_APPLICATIONS_LIST: The right to list the applications the organization is a collaborator of.\n - RIGHT_ORGANIZATION_APPLICATIONS_CREATE: The right to create an application under the organization.\n - RIGHT_ORGANIZATION_GATEWAYS_LIST: The right to list the gateways the organization is a collaborator of.\n - RIGHT_ORGANIZATION_GATEWAYS_CREATE: The right to create a gateway under the organization.\n - RIGHT_ORGANIZATION_CLIENTS_LIST: The right to list the OAuth clients the organization is a collaborator of.\n - RIGHT_ORGANIZATION_CLIENTS_CREATE: The right to create an OAuth client under the organization.\n - RIGHT_ORGANIZATION_ADD_AS_COLLABORATOR: The right to add the organization as a collaborator on an existing entity.\n - RIGHT_ORGANIZATION_ALL: The pseudo-right for all (current and future) organization rights.\n - RIGHT_SEND_INVITES: The right to send invites to new users.\nNote that this is not prefixed with \"USER_\"; it is not a right on the user entity.\n - RIGHT_ALL: The pseudo-right for all (current and future) possible rights.", + "description": " - RIGHT_USER_INFO: The right to view user information.\n - RIGHT_USER_SETTINGS_BASIC: The right to edit basic user settings.\n - RIGHT_USER_SETTINGS_API_KEYS: The right to view and edit user API keys.\n - RIGHT_USER_DELETE: The right to delete user account.\n - RIGHT_USER_AUTHORIZED_CLIENTS: The right to view and edit authorized OAuth clients of the user.\n - RIGHT_USER_APPLICATIONS_LIST: The right to list applications the user is a collaborator of.\n - RIGHT_USER_APPLICATIONS_CREATE: The right to create an application under the user account.\n - RIGHT_USER_GATEWAYS_LIST: The right to list gateways the user is a collaborator of.\n - RIGHT_USER_GATEWAYS_CREATE: The right to create a gateway under the account of the user.\n - RIGHT_USER_CLIENTS_LIST: The right to list OAuth clients the user is a collaborator of.\n - RIGHT_USER_CLIENTS_CREATE: The right to create an OAuth client under the account of the user.\n - RIGHT_USER_ORGANIZATIONS_LIST: The right to list organizations the user is a member of.\n - RIGHT_USER_ORGANIZATIONS_CREATE: The right to create an organization under the user account.\n - RIGHT_USER_NOTIFICATIONS_READ: The right to read notifications sent to the user.\n - RIGHT_USER_ALL: The pseudo-right for all (current and future) user rights.\n - RIGHT_APPLICATION_INFO: The right to view application information.\n - RIGHT_APPLICATION_SETTINGS_BASIC: The right to edit basic application settings.\n - RIGHT_APPLICATION_SETTINGS_API_KEYS: The right to view and edit application API keys.\n - RIGHT_APPLICATION_SETTINGS_COLLABORATORS: The right to view and edit application collaborators.\n - RIGHT_APPLICATION_SETTINGS_PACKAGES: The right to view and edit application packages and associations.\n - RIGHT_APPLICATION_DELETE: The right to delete application.\n - RIGHT_APPLICATION_PURGE: The right to purge application.\n - RIGHT_APPLICATION_DEVICES_READ: The right to view devices in application.\n - RIGHT_APPLICATION_DEVICES_WRITE: The right to create devices in application.\n - RIGHT_APPLICATION_DEVICES_READ_KEYS: The right to view device keys in application.\nNote that keys may not be stored in a way that supports viewing them.\n - RIGHT_APPLICATION_DEVICES_WRITE_KEYS: The right to edit device keys in application.\n - RIGHT_APPLICATION_TRAFFIC_READ: The right to read application traffic (uplink and downlink).\n - RIGHT_APPLICATION_TRAFFIC_UP_WRITE: The right to write uplink application traffic.\n - RIGHT_APPLICATION_TRAFFIC_DOWN_WRITE: The right to write downlink application traffic.\n - RIGHT_APPLICATION_LINK: The right to link as Application to a Network Server for traffic exchange,\ni.e. read uplink and write downlink (API keys only).\nThis right is typically only given to an Application Server.\nThis right implies RIGHT_APPLICATION_INFO, RIGHT_APPLICATION_TRAFFIC_READ,\nand RIGHT_APPLICATION_TRAFFIC_DOWN_WRITE.\n - RIGHT_APPLICATION_ALL: The pseudo-right for all (current and future) application rights.\n - RIGHT_CLIENT_ALL: The pseudo-right for all (current and future) OAuth client rights.\n - RIGHT_CLIENT_INFO: The right to read client information.\n - RIGHT_CLIENT_SETTINGS_BASIC: The right to edit basic client settings.\n - RIGHT_CLIENT_SETTINGS_COLLABORATORS: The right to view and edit client collaborators.\n - RIGHT_CLIENT_DELETE: The right to delete a client.\n - RIGHT_GATEWAY_INFO: The right to view gateway information.\n - RIGHT_GATEWAY_SETTINGS_BASIC: The right to edit basic gateway settings.\n - RIGHT_GATEWAY_SETTINGS_API_KEYS: The right to view and edit gateway API keys.\n - RIGHT_GATEWAY_SETTINGS_COLLABORATORS: The right to view and edit gateway collaborators.\n - RIGHT_GATEWAY_DELETE: The right to delete gateway.\n - RIGHT_GATEWAY_TRAFFIC_READ: The right to read gateway traffic.\n - RIGHT_GATEWAY_TRAFFIC_DOWN_WRITE: The right to write downlink gateway traffic.\n - RIGHT_GATEWAY_LINK: The right to link as Gateway to a Gateway Server for traffic exchange,\ni.e. write uplink and read downlink (API keys only)\nThis right is typically only given to a gateway.\nThis right implies RIGHT_GATEWAY_INFO.\n - RIGHT_GATEWAY_STATUS_READ: The right to view gateway status.\n - RIGHT_GATEWAY_LOCATION_READ: The right to view view gateway location.\n - RIGHT_GATEWAY_WRITE_SECRETS: The right to store secrets associated with this gateway.\n - RIGHT_GATEWAY_READ_SECRETS: The right to retrieve secrets associated with this gateway.\n - RIGHT_GATEWAY_ALL: The pseudo-right for all (current and future) gateway rights.\n - RIGHT_ORGANIZATION_INFO: The right to view organization information.\n - RIGHT_ORGANIZATION_SETTINGS_BASIC: The right to edit basic organization settings.\n - RIGHT_ORGANIZATION_SETTINGS_API_KEYS: The right to view and edit organization API keys.\n - RIGHT_ORGANIZATION_SETTINGS_MEMBERS: The right to view and edit organization members.\n - RIGHT_ORGANIZATION_DELETE: The right to delete organization.\n - RIGHT_ORGANIZATION_PURGE: The right to purge organization.\n - RIGHT_ORGANIZATION_APPLICATIONS_LIST: The right to list the applications the organization is a collaborator of.\n - RIGHT_ORGANIZATION_APPLICATIONS_CREATE: The right to create an application under the organization.\n - RIGHT_ORGANIZATION_GATEWAYS_LIST: The right to list the gateways the organization is a collaborator of.\n - RIGHT_ORGANIZATION_GATEWAYS_CREATE: The right to create a gateway under the organization.\n - RIGHT_ORGANIZATION_CLIENTS_LIST: The right to list the OAuth clients the organization is a collaborator of.\n - RIGHT_ORGANIZATION_CLIENTS_CREATE: The right to create an OAuth client under the organization.\n - RIGHT_ORGANIZATION_ADD_AS_COLLABORATOR: The right to add the organization as a collaborator on an existing entity.\n - RIGHT_ORGANIZATION_ALL: The pseudo-right for all (current and future) organization rights.\n - RIGHT_SEND_INVITES: The right to send invites to new users.\nNote that this is not prefixed with \"USER_\"; it is not a right on the user entity.\n - RIGHT_ALL: The pseudo-right for all (current and future) possible rights.", "in": "query", "required": false, "type": "array", @@ -6973,6 +6973,7 @@ "RIGHT_ORGANIZATION_SETTINGS_API_KEYS", "RIGHT_ORGANIZATION_SETTINGS_MEMBERS", "RIGHT_ORGANIZATION_DELETE", + "RIGHT_ORGANIZATION_PURGE", "RIGHT_ORGANIZATION_APPLICATIONS_LIST", "RIGHT_ORGANIZATION_APPLICATIONS_CREATE", "RIGHT_ORGANIZATION_GATEWAYS_LIST", @@ -29015,6 +29016,7 @@ "RIGHT_ORGANIZATION_SETTINGS_API_KEYS", "RIGHT_ORGANIZATION_SETTINGS_MEMBERS", "RIGHT_ORGANIZATION_DELETE", + "RIGHT_ORGANIZATION_PURGE", "RIGHT_ORGANIZATION_APPLICATIONS_LIST", "RIGHT_ORGANIZATION_APPLICATIONS_CREATE", "RIGHT_ORGANIZATION_GATEWAYS_LIST", @@ -29027,7 +29029,7 @@ "RIGHT_ALL" ], "default": "right_invalid", - "description": "Right is the enum that defines all the different rights to do something in the network.\n\n - RIGHT_USER_INFO: The right to view user information.\n - RIGHT_USER_SETTINGS_BASIC: The right to edit basic user settings.\n - RIGHT_USER_SETTINGS_API_KEYS: The right to view and edit user API keys.\n - RIGHT_USER_DELETE: The right to delete user account.\n - RIGHT_USER_AUTHORIZED_CLIENTS: The right to view and edit authorized OAuth clients of the user.\n - RIGHT_USER_APPLICATIONS_LIST: The right to list applications the user is a collaborator of.\n - RIGHT_USER_APPLICATIONS_CREATE: The right to create an application under the user account.\n - RIGHT_USER_GATEWAYS_LIST: The right to list gateways the user is a collaborator of.\n - RIGHT_USER_GATEWAYS_CREATE: The right to create a gateway under the account of the user.\n - RIGHT_USER_CLIENTS_LIST: The right to list OAuth clients the user is a collaborator of.\n - RIGHT_USER_CLIENTS_CREATE: The right to create an OAuth client under the account of the user.\n - RIGHT_USER_ORGANIZATIONS_LIST: The right to list organizations the user is a member of.\n - RIGHT_USER_ORGANIZATIONS_CREATE: The right to create an organization under the user account.\n - RIGHT_USER_NOTIFICATIONS_READ: The right to read notifications sent to the user.\n - RIGHT_USER_ALL: The pseudo-right for all (current and future) user rights.\n - RIGHT_APPLICATION_INFO: The right to view application information.\n - RIGHT_APPLICATION_SETTINGS_BASIC: The right to edit basic application settings.\n - RIGHT_APPLICATION_SETTINGS_API_KEYS: The right to view and edit application API keys.\n - RIGHT_APPLICATION_SETTINGS_COLLABORATORS: The right to view and edit application collaborators.\n - RIGHT_APPLICATION_SETTINGS_PACKAGES: The right to view and edit application packages and associations.\n - RIGHT_APPLICATION_DELETE: The right to delete application.\n - RIGHT_APPLICATION_PURGE: The right to purge application.\n - RIGHT_APPLICATION_DEVICES_READ: The right to view devices in application.\n - RIGHT_APPLICATION_DEVICES_WRITE: The right to create devices in application.\n - RIGHT_APPLICATION_DEVICES_READ_KEYS: The right to view device keys in application.\nNote that keys may not be stored in a way that supports viewing them.\n - RIGHT_APPLICATION_DEVICES_WRITE_KEYS: The right to edit device keys in application.\n - RIGHT_APPLICATION_TRAFFIC_READ: The right to read application traffic (uplink and downlink).\n - RIGHT_APPLICATION_TRAFFIC_UP_WRITE: The right to write uplink application traffic.\n - RIGHT_APPLICATION_TRAFFIC_DOWN_WRITE: The right to write downlink application traffic.\n - RIGHT_APPLICATION_LINK: The right to link as Application to a Network Server for traffic exchange,\ni.e. read uplink and write downlink (API keys only).\nThis right is typically only given to an Application Server.\nThis right implies RIGHT_APPLICATION_INFO, RIGHT_APPLICATION_TRAFFIC_READ,\nand RIGHT_APPLICATION_TRAFFIC_DOWN_WRITE.\n - RIGHT_APPLICATION_ALL: The pseudo-right for all (current and future) application rights.\n - RIGHT_CLIENT_ALL: The pseudo-right for all (current and future) OAuth client rights.\n - RIGHT_CLIENT_INFO: The right to read client information.\n - RIGHT_CLIENT_SETTINGS_BASIC: The right to edit basic client settings.\n - RIGHT_CLIENT_SETTINGS_COLLABORATORS: The right to view and edit client collaborators.\n - RIGHT_CLIENT_DELETE: The right to delete a client.\n - RIGHT_GATEWAY_INFO: The right to view gateway information.\n - RIGHT_GATEWAY_SETTINGS_BASIC: The right to edit basic gateway settings.\n - RIGHT_GATEWAY_SETTINGS_API_KEYS: The right to view and edit gateway API keys.\n - RIGHT_GATEWAY_SETTINGS_COLLABORATORS: The right to view and edit gateway collaborators.\n - RIGHT_GATEWAY_DELETE: The right to delete gateway.\n - RIGHT_GATEWAY_TRAFFIC_READ: The right to read gateway traffic.\n - RIGHT_GATEWAY_TRAFFIC_DOWN_WRITE: The right to write downlink gateway traffic.\n - RIGHT_GATEWAY_LINK: The right to link as Gateway to a Gateway Server for traffic exchange,\ni.e. write uplink and read downlink (API keys only)\nThis right is typically only given to a gateway.\nThis right implies RIGHT_GATEWAY_INFO.\n - RIGHT_GATEWAY_STATUS_READ: The right to view gateway status.\n - RIGHT_GATEWAY_LOCATION_READ: The right to view view gateway location.\n - RIGHT_GATEWAY_WRITE_SECRETS: The right to store secrets associated with this gateway.\n - RIGHT_GATEWAY_READ_SECRETS: The right to retrieve secrets associated with this gateway.\n - RIGHT_GATEWAY_ALL: The pseudo-right for all (current and future) gateway rights.\n - RIGHT_ORGANIZATION_INFO: The right to view organization information.\n - RIGHT_ORGANIZATION_SETTINGS_BASIC: The right to edit basic organization settings.\n - RIGHT_ORGANIZATION_SETTINGS_API_KEYS: The right to view and edit organization API keys.\n - RIGHT_ORGANIZATION_SETTINGS_MEMBERS: The right to view and edit organization members.\n - RIGHT_ORGANIZATION_DELETE: The right to delete organization.\n - RIGHT_ORGANIZATION_APPLICATIONS_LIST: The right to list the applications the organization is a collaborator of.\n - RIGHT_ORGANIZATION_APPLICATIONS_CREATE: The right to create an application under the organization.\n - RIGHT_ORGANIZATION_GATEWAYS_LIST: The right to list the gateways the organization is a collaborator of.\n - RIGHT_ORGANIZATION_GATEWAYS_CREATE: The right to create a gateway under the organization.\n - RIGHT_ORGANIZATION_CLIENTS_LIST: The right to list the OAuth clients the organization is a collaborator of.\n - RIGHT_ORGANIZATION_CLIENTS_CREATE: The right to create an OAuth client under the organization.\n - RIGHT_ORGANIZATION_ADD_AS_COLLABORATOR: The right to add the organization as a collaborator on an existing entity.\n - RIGHT_ORGANIZATION_ALL: The pseudo-right for all (current and future) organization rights.\n - RIGHT_SEND_INVITES: The right to send invites to new users.\nNote that this is not prefixed with \"USER_\"; it is not a right on the user entity.\n - RIGHT_ALL: The pseudo-right for all (current and future) possible rights." + "description": "Right is the enum that defines all the different rights to do something in the network.\n\n - RIGHT_USER_INFO: The right to view user information.\n - RIGHT_USER_SETTINGS_BASIC: The right to edit basic user settings.\n - RIGHT_USER_SETTINGS_API_KEYS: The right to view and edit user API keys.\n - RIGHT_USER_DELETE: The right to delete user account.\n - RIGHT_USER_AUTHORIZED_CLIENTS: The right to view and edit authorized OAuth clients of the user.\n - RIGHT_USER_APPLICATIONS_LIST: The right to list applications the user is a collaborator of.\n - RIGHT_USER_APPLICATIONS_CREATE: The right to create an application under the user account.\n - RIGHT_USER_GATEWAYS_LIST: The right to list gateways the user is a collaborator of.\n - RIGHT_USER_GATEWAYS_CREATE: The right to create a gateway under the account of the user.\n - RIGHT_USER_CLIENTS_LIST: The right to list OAuth clients the user is a collaborator of.\n - RIGHT_USER_CLIENTS_CREATE: The right to create an OAuth client under the account of the user.\n - RIGHT_USER_ORGANIZATIONS_LIST: The right to list organizations the user is a member of.\n - RIGHT_USER_ORGANIZATIONS_CREATE: The right to create an organization under the user account.\n - RIGHT_USER_NOTIFICATIONS_READ: The right to read notifications sent to the user.\n - RIGHT_USER_ALL: The pseudo-right for all (current and future) user rights.\n - RIGHT_APPLICATION_INFO: The right to view application information.\n - RIGHT_APPLICATION_SETTINGS_BASIC: The right to edit basic application settings.\n - RIGHT_APPLICATION_SETTINGS_API_KEYS: The right to view and edit application API keys.\n - RIGHT_APPLICATION_SETTINGS_COLLABORATORS: The right to view and edit application collaborators.\n - RIGHT_APPLICATION_SETTINGS_PACKAGES: The right to view and edit application packages and associations.\n - RIGHT_APPLICATION_DELETE: The right to delete application.\n - RIGHT_APPLICATION_PURGE: The right to purge application.\n - RIGHT_APPLICATION_DEVICES_READ: The right to view devices in application.\n - RIGHT_APPLICATION_DEVICES_WRITE: The right to create devices in application.\n - RIGHT_APPLICATION_DEVICES_READ_KEYS: The right to view device keys in application.\nNote that keys may not be stored in a way that supports viewing them.\n - RIGHT_APPLICATION_DEVICES_WRITE_KEYS: The right to edit device keys in application.\n - RIGHT_APPLICATION_TRAFFIC_READ: The right to read application traffic (uplink and downlink).\n - RIGHT_APPLICATION_TRAFFIC_UP_WRITE: The right to write uplink application traffic.\n - RIGHT_APPLICATION_TRAFFIC_DOWN_WRITE: The right to write downlink application traffic.\n - RIGHT_APPLICATION_LINK: The right to link as Application to a Network Server for traffic exchange,\ni.e. read uplink and write downlink (API keys only).\nThis right is typically only given to an Application Server.\nThis right implies RIGHT_APPLICATION_INFO, RIGHT_APPLICATION_TRAFFIC_READ,\nand RIGHT_APPLICATION_TRAFFIC_DOWN_WRITE.\n - RIGHT_APPLICATION_ALL: The pseudo-right for all (current and future) application rights.\n - RIGHT_CLIENT_ALL: The pseudo-right for all (current and future) OAuth client rights.\n - RIGHT_CLIENT_INFO: The right to read client information.\n - RIGHT_CLIENT_SETTINGS_BASIC: The right to edit basic client settings.\n - RIGHT_CLIENT_SETTINGS_COLLABORATORS: The right to view and edit client collaborators.\n - RIGHT_CLIENT_DELETE: The right to delete a client.\n - RIGHT_GATEWAY_INFO: The right to view gateway information.\n - RIGHT_GATEWAY_SETTINGS_BASIC: The right to edit basic gateway settings.\n - RIGHT_GATEWAY_SETTINGS_API_KEYS: The right to view and edit gateway API keys.\n - RIGHT_GATEWAY_SETTINGS_COLLABORATORS: The right to view and edit gateway collaborators.\n - RIGHT_GATEWAY_DELETE: The right to delete gateway.\n - RIGHT_GATEWAY_TRAFFIC_READ: The right to read gateway traffic.\n - RIGHT_GATEWAY_TRAFFIC_DOWN_WRITE: The right to write downlink gateway traffic.\n - RIGHT_GATEWAY_LINK: The right to link as Gateway to a Gateway Server for traffic exchange,\ni.e. write uplink and read downlink (API keys only)\nThis right is typically only given to a gateway.\nThis right implies RIGHT_GATEWAY_INFO.\n - RIGHT_GATEWAY_STATUS_READ: The right to view gateway status.\n - RIGHT_GATEWAY_LOCATION_READ: The right to view view gateway location.\n - RIGHT_GATEWAY_WRITE_SECRETS: The right to store secrets associated with this gateway.\n - RIGHT_GATEWAY_READ_SECRETS: The right to retrieve secrets associated with this gateway.\n - RIGHT_GATEWAY_ALL: The pseudo-right for all (current and future) gateway rights.\n - RIGHT_ORGANIZATION_INFO: The right to view organization information.\n - RIGHT_ORGANIZATION_SETTINGS_BASIC: The right to edit basic organization settings.\n - RIGHT_ORGANIZATION_SETTINGS_API_KEYS: The right to view and edit organization API keys.\n - RIGHT_ORGANIZATION_SETTINGS_MEMBERS: The right to view and edit organization members.\n - RIGHT_ORGANIZATION_DELETE: The right to delete organization.\n - RIGHT_ORGANIZATION_PURGE: The right to purge organization.\n - RIGHT_ORGANIZATION_APPLICATIONS_LIST: The right to list the applications the organization is a collaborator of.\n - RIGHT_ORGANIZATION_APPLICATIONS_CREATE: The right to create an application under the organization.\n - RIGHT_ORGANIZATION_GATEWAYS_LIST: The right to list the gateways the organization is a collaborator of.\n - RIGHT_ORGANIZATION_GATEWAYS_CREATE: The right to create a gateway under the organization.\n - RIGHT_ORGANIZATION_CLIENTS_LIST: The right to list the OAuth clients the organization is a collaborator of.\n - RIGHT_ORGANIZATION_CLIENTS_CREATE: The right to create an OAuth client under the organization.\n - RIGHT_ORGANIZATION_ADD_AS_COLLABORATOR: The right to add the organization as a collaborator on an existing entity.\n - RIGHT_ORGANIZATION_ALL: The pseudo-right for all (current and future) organization rights.\n - RIGHT_SEND_INVITES: The right to send invites to new users.\nNote that this is not prefixed with \"USER_\"; it is not a right on the user entity.\n - RIGHT_ALL: The pseudo-right for all (current and future) possible rights." }, "v3Rights": { "type": "object", diff --git a/api/ttn/lorawan/v3/rights.proto b/api/ttn/lorawan/v3/rights.proto index a6f7eb569b..bc5bb06c39 100644 --- a/api/ttn/lorawan/v3/rights.proto +++ b/api/ttn/lorawan/v3/rights.proto @@ -153,6 +153,8 @@ enum Right { RIGHT_ORGANIZATION_SETTINGS_MEMBERS = 44; // The right to delete organization. RIGHT_ORGANIZATION_DELETE = 45; + // The right to purge organization. + RIGHT_ORGANIZATION_PURGE = 65; // The right to list the applications the organization is a collaborator of. RIGHT_ORGANIZATION_APPLICATIONS_LIST = 46; // The right to create an application under the organization. @@ -177,7 +179,7 @@ enum Right { // The pseudo-right for all (current and future) possible rights. RIGHT_ALL = 55; - // Next value: 65 + // Next value: 66 } message Rights { diff --git a/pkg/ttnpb/rights.pb.go b/pkg/ttnpb/rights.pb.go index 73d9f39e33..11d2b2d8a7 100644 --- a/pkg/ttnpb/rights.pb.go +++ b/pkg/ttnpb/rights.pb.go @@ -159,6 +159,8 @@ const ( Right_RIGHT_ORGANIZATION_SETTINGS_MEMBERS Right = 44 // The right to delete organization. Right_RIGHT_ORGANIZATION_DELETE Right = 45 + // The right to purge organization. + Right_RIGHT_ORGANIZATION_PURGE Right = 65 // The right to list the applications the organization is a collaborator of. Right_RIGHT_ORGANIZATION_APPLICATIONS_LIST Right = 46 // The right to create an application under the organization. @@ -240,6 +242,7 @@ var ( 43: "RIGHT_ORGANIZATION_SETTINGS_API_KEYS", 44: "RIGHT_ORGANIZATION_SETTINGS_MEMBERS", 45: "RIGHT_ORGANIZATION_DELETE", + 65: "RIGHT_ORGANIZATION_PURGE", 46: "RIGHT_ORGANIZATION_APPLICATIONS_LIST", 47: "RIGHT_ORGANIZATION_APPLICATIONS_CREATE", 48: "RIGHT_ORGANIZATION_GATEWAYS_LIST", @@ -307,6 +310,7 @@ var ( "RIGHT_ORGANIZATION_SETTINGS_API_KEYS": 43, "RIGHT_ORGANIZATION_SETTINGS_MEMBERS": 44, "RIGHT_ORGANIZATION_DELETE": 45, + "RIGHT_ORGANIZATION_PURGE": 65, "RIGHT_ORGANIZATION_APPLICATIONS_LIST": 46, "RIGHT_ORGANIZATION_APPLICATIONS_CREATE": 47, "RIGHT_ORGANIZATION_GATEWAYS_LIST": 48, @@ -770,7 +774,7 @@ var file_ttn_lorawan_v3_rights_proto_rawDesc = []byte{ 0x61, 0x62, 0x6f, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x43, 0x6f, 0x6c, 0x6c, 0x61, 0x62, 0x6f, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x0d, 0x63, - 0x6f, 0x6c, 0x6c, 0x61, 0x62, 0x6f, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x2a, 0xfc, 0x10, 0x0a, + 0x6f, 0x6c, 0x6c, 0x61, 0x62, 0x6f, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x2a, 0x9a, 0x11, 0x0a, 0x05, 0x52, 0x69, 0x67, 0x68, 0x74, 0x12, 0x11, 0x0a, 0x0d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x5f, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x01, 0x12, 0x1d, @@ -883,34 +887,36 @@ var file_ttn_lorawan_v3_rights_proto_rawDesc = []byte{ 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, 0x53, 0x10, 0x2c, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, - 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x2d, 0x12, 0x28, 0x0a, - 0x24, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, - 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x53, - 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x2e, 0x12, 0x2a, 0x0a, 0x26, 0x52, 0x49, 0x47, 0x48, 0x54, - 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x50, - 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, - 0x45, 0x10, 0x2f, 0x12, 0x24, 0x0a, 0x20, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, - 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, - 0x59, 0x53, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x30, 0x12, 0x26, 0x0a, 0x22, 0x52, 0x49, 0x47, - 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, - 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x53, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, - 0x31, 0x12, 0x23, 0x0a, 0x1f, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, - 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x53, 0x5f, - 0x4c, 0x49, 0x53, 0x54, 0x10, 0x32, 0x12, 0x25, 0x0a, 0x21, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, - 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x43, 0x4c, 0x49, - 0x45, 0x4e, 0x54, 0x53, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, 0x33, 0x12, 0x2a, 0x0a, - 0x26, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, - 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x44, 0x44, 0x5f, 0x41, 0x53, 0x5f, 0x43, 0x4f, 0x4c, 0x4c, 0x41, - 0x42, 0x4f, 0x52, 0x41, 0x54, 0x4f, 0x52, 0x10, 0x34, 0x12, 0x1a, 0x0a, 0x16, 0x52, 0x49, 0x47, - 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, - 0x41, 0x4c, 0x4c, 0x10, 0x35, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x53, - 0x45, 0x4e, 0x44, 0x5f, 0x49, 0x4e, 0x56, 0x49, 0x54, 0x45, 0x53, 0x10, 0x36, 0x12, 0x0d, 0x0a, - 0x09, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x4c, 0x4c, 0x10, 0x37, 0x1a, 0x0d, 0xea, 0xaa, - 0x19, 0x09, 0x18, 0x01, 0x2a, 0x05, 0x52, 0x49, 0x47, 0x48, 0x54, 0x42, 0x31, 0x5a, 0x2f, 0x67, - 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, - 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63, - 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x74, 0x6e, 0x70, 0x62, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x2d, 0x12, 0x1c, 0x0a, + 0x18, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, + 0x49, 0x4f, 0x4e, 0x5f, 0x50, 0x55, 0x52, 0x47, 0x45, 0x10, 0x41, 0x12, 0x28, 0x0a, 0x24, 0x52, + 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, + 0x4e, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x5f, 0x4c, + 0x49, 0x53, 0x54, 0x10, 0x2e, 0x12, 0x2a, 0x0a, 0x26, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, + 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x50, 0x50, 0x4c, + 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, + 0x2f, 0x12, 0x24, 0x0a, 0x20, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, + 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x53, + 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x30, 0x12, 0x26, 0x0a, 0x22, 0x52, 0x49, 0x47, 0x48, 0x54, + 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x47, 0x41, + 0x54, 0x45, 0x57, 0x41, 0x59, 0x53, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, 0x31, 0x12, + 0x23, 0x0a, 0x1f, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, + 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x53, 0x5f, 0x4c, 0x49, + 0x53, 0x54, 0x10, 0x32, 0x12, 0x25, 0x0a, 0x21, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, + 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, + 0x54, 0x53, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, 0x33, 0x12, 0x2a, 0x0a, 0x26, 0x52, + 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, + 0x4e, 0x5f, 0x41, 0x44, 0x44, 0x5f, 0x41, 0x53, 0x5f, 0x43, 0x4f, 0x4c, 0x4c, 0x41, 0x42, 0x4f, + 0x52, 0x41, 0x54, 0x4f, 0x52, 0x10, 0x34, 0x12, 0x1a, 0x0a, 0x16, 0x52, 0x49, 0x47, 0x48, 0x54, + 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x4c, + 0x4c, 0x10, 0x35, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x53, 0x45, 0x4e, + 0x44, 0x5f, 0x49, 0x4e, 0x56, 0x49, 0x54, 0x45, 0x53, 0x10, 0x36, 0x12, 0x0d, 0x0a, 0x09, 0x52, + 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x4c, 0x4c, 0x10, 0x37, 0x1a, 0x0d, 0xea, 0xaa, 0x19, 0x09, + 0x18, 0x01, 0x2a, 0x05, 0x52, 0x49, 0x47, 0x48, 0x54, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x6f, 0x2e, + 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, + 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, + 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x74, 0x6e, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/pkg/ttnpb/rights_json.pb.go b/pkg/ttnpb/rights_json.pb.go index 95e98d5bba..1ab2998752 100644 --- a/pkg/ttnpb/rights_json.pb.go +++ b/pkg/ttnpb/rights_json.pb.go @@ -82,6 +82,7 @@ var Right_customvalue = map[string]int32{ "ORGANIZATION_SETTINGS_API_KEYS": 43, "ORGANIZATION_SETTINGS_MEMBERS": 44, "ORGANIZATION_DELETE": 45, + "ORGANIZATION_PURGE": 65, "ORGANIZATION_APPLICATIONS_LIST": 46, "ORGANIZATION_APPLICATIONS_CREATE": 47, "ORGANIZATION_GATEWAYS_LIST": 48, diff --git a/sdk/js/generated/api.json b/sdk/js/generated/api.json index 7f2ecbdd1b..07961b1885 100644 --- a/sdk/js/generated/api.json +++ b/sdk/js/generated/api.json @@ -49989,6 +49989,11 @@ "number": "45", "description": "The right to delete organization." }, + { + "name": "RIGHT_ORGANIZATION_PURGE", + "number": "65", + "description": "The right to purge organization." + }, { "name": "RIGHT_ORGANIZATION_APPLICATIONS_LIST", "number": "46", From d425a3f707421fe318f84cd9198a615dcae71521 Mon Sep 17 00:00:00 2001 From: Nicholas Cristofaro Date: Mon, 25 Nov 2024 10:18:09 -0300 Subject: [PATCH 11/40] api: Add RIGHT_USER_PURGE --- api/ttn/lorawan/v3/api.md | 1 + api/ttn/lorawan/v3/api.swagger.json | 6 +- api/ttn/lorawan/v3/rights.proto | 4 +- pkg/identityserver/organization_registry.go | 5 + pkg/ttnpb/rights.pb.go | 265 ++++++++++---------- pkg/ttnpb/rights_json.pb.go | 1 + sdk/js/generated/api.json | 5 + 7 files changed, 154 insertions(+), 133 deletions(-) diff --git a/api/ttn/lorawan/v3/api.md b/api/ttn/lorawan/v3/api.md index 7d7d8b0de4..aac20cb240 100644 --- a/api/ttn/lorawan/v3/api.md +++ b/api/ttn/lorawan/v3/api.md @@ -10976,6 +10976,7 @@ Right is the enum that defines all the different rights to do something in the n | `RIGHT_USER_SETTINGS_BASIC` | 2 | The right to edit basic user settings. | | `RIGHT_USER_SETTINGS_API_KEYS` | 3 | The right to view and edit user API keys. | | `RIGHT_USER_DELETE` | 4 | The right to delete user account. | +| `RIGHT_USER_PURGE` | 66 | The right to delete user account. | | `RIGHT_USER_AUTHORIZED_CLIENTS` | 5 | The right to view and edit authorized OAuth clients of the user. | | `RIGHT_USER_APPLICATIONS_LIST` | 6 | The right to list applications the user is a collaborator of. | | `RIGHT_USER_APPLICATIONS_CREATE` | 7 | The right to create an application under the user account. | diff --git a/api/ttn/lorawan/v3/api.swagger.json b/api/ttn/lorawan/v3/api.swagger.json index 7439b06c9a..9e22a00a38 100644 --- a/api/ttn/lorawan/v3/api.swagger.json +++ b/api/ttn/lorawan/v3/api.swagger.json @@ -6911,7 +6911,7 @@ "parameters": [ { "name": "required.rights", - "description": " - RIGHT_USER_INFO: The right to view user information.\n - RIGHT_USER_SETTINGS_BASIC: The right to edit basic user settings.\n - RIGHT_USER_SETTINGS_API_KEYS: The right to view and edit user API keys.\n - RIGHT_USER_DELETE: The right to delete user account.\n - RIGHT_USER_AUTHORIZED_CLIENTS: The right to view and edit authorized OAuth clients of the user.\n - RIGHT_USER_APPLICATIONS_LIST: The right to list applications the user is a collaborator of.\n - RIGHT_USER_APPLICATIONS_CREATE: The right to create an application under the user account.\n - RIGHT_USER_GATEWAYS_LIST: The right to list gateways the user is a collaborator of.\n - RIGHT_USER_GATEWAYS_CREATE: The right to create a gateway under the account of the user.\n - RIGHT_USER_CLIENTS_LIST: The right to list OAuth clients the user is a collaborator of.\n - RIGHT_USER_CLIENTS_CREATE: The right to create an OAuth client under the account of the user.\n - RIGHT_USER_ORGANIZATIONS_LIST: The right to list organizations the user is a member of.\n - RIGHT_USER_ORGANIZATIONS_CREATE: The right to create an organization under the user account.\n - RIGHT_USER_NOTIFICATIONS_READ: The right to read notifications sent to the user.\n - RIGHT_USER_ALL: The pseudo-right for all (current and future) user rights.\n - RIGHT_APPLICATION_INFO: The right to view application information.\n - RIGHT_APPLICATION_SETTINGS_BASIC: The right to edit basic application settings.\n - RIGHT_APPLICATION_SETTINGS_API_KEYS: The right to view and edit application API keys.\n - RIGHT_APPLICATION_SETTINGS_COLLABORATORS: The right to view and edit application collaborators.\n - RIGHT_APPLICATION_SETTINGS_PACKAGES: The right to view and edit application packages and associations.\n - RIGHT_APPLICATION_DELETE: The right to delete application.\n - RIGHT_APPLICATION_PURGE: The right to purge application.\n - RIGHT_APPLICATION_DEVICES_READ: The right to view devices in application.\n - RIGHT_APPLICATION_DEVICES_WRITE: The right to create devices in application.\n - RIGHT_APPLICATION_DEVICES_READ_KEYS: The right to view device keys in application.\nNote that keys may not be stored in a way that supports viewing them.\n - RIGHT_APPLICATION_DEVICES_WRITE_KEYS: The right to edit device keys in application.\n - RIGHT_APPLICATION_TRAFFIC_READ: The right to read application traffic (uplink and downlink).\n - RIGHT_APPLICATION_TRAFFIC_UP_WRITE: The right to write uplink application traffic.\n - RIGHT_APPLICATION_TRAFFIC_DOWN_WRITE: The right to write downlink application traffic.\n - RIGHT_APPLICATION_LINK: The right to link as Application to a Network Server for traffic exchange,\ni.e. read uplink and write downlink (API keys only).\nThis right is typically only given to an Application Server.\nThis right implies RIGHT_APPLICATION_INFO, RIGHT_APPLICATION_TRAFFIC_READ,\nand RIGHT_APPLICATION_TRAFFIC_DOWN_WRITE.\n - RIGHT_APPLICATION_ALL: The pseudo-right for all (current and future) application rights.\n - RIGHT_CLIENT_ALL: The pseudo-right for all (current and future) OAuth client rights.\n - RIGHT_CLIENT_INFO: The right to read client information.\n - RIGHT_CLIENT_SETTINGS_BASIC: The right to edit basic client settings.\n - RIGHT_CLIENT_SETTINGS_COLLABORATORS: The right to view and edit client collaborators.\n - RIGHT_CLIENT_DELETE: The right to delete a client.\n - RIGHT_GATEWAY_INFO: The right to view gateway information.\n - RIGHT_GATEWAY_SETTINGS_BASIC: The right to edit basic gateway settings.\n - RIGHT_GATEWAY_SETTINGS_API_KEYS: The right to view and edit gateway API keys.\n - RIGHT_GATEWAY_SETTINGS_COLLABORATORS: The right to view and edit gateway collaborators.\n - RIGHT_GATEWAY_DELETE: The right to delete gateway.\n - RIGHT_GATEWAY_TRAFFIC_READ: The right to read gateway traffic.\n - RIGHT_GATEWAY_TRAFFIC_DOWN_WRITE: The right to write downlink gateway traffic.\n - RIGHT_GATEWAY_LINK: The right to link as Gateway to a Gateway Server for traffic exchange,\ni.e. write uplink and read downlink (API keys only)\nThis right is typically only given to a gateway.\nThis right implies RIGHT_GATEWAY_INFO.\n - RIGHT_GATEWAY_STATUS_READ: The right to view gateway status.\n - RIGHT_GATEWAY_LOCATION_READ: The right to view view gateway location.\n - RIGHT_GATEWAY_WRITE_SECRETS: The right to store secrets associated with this gateway.\n - RIGHT_GATEWAY_READ_SECRETS: The right to retrieve secrets associated with this gateway.\n - RIGHT_GATEWAY_ALL: The pseudo-right for all (current and future) gateway rights.\n - RIGHT_ORGANIZATION_INFO: The right to view organization information.\n - RIGHT_ORGANIZATION_SETTINGS_BASIC: The right to edit basic organization settings.\n - RIGHT_ORGANIZATION_SETTINGS_API_KEYS: The right to view and edit organization API keys.\n - RIGHT_ORGANIZATION_SETTINGS_MEMBERS: The right to view and edit organization members.\n - RIGHT_ORGANIZATION_DELETE: The right to delete organization.\n - RIGHT_ORGANIZATION_PURGE: The right to purge organization.\n - RIGHT_ORGANIZATION_APPLICATIONS_LIST: The right to list the applications the organization is a collaborator of.\n - RIGHT_ORGANIZATION_APPLICATIONS_CREATE: The right to create an application under the organization.\n - RIGHT_ORGANIZATION_GATEWAYS_LIST: The right to list the gateways the organization is a collaborator of.\n - RIGHT_ORGANIZATION_GATEWAYS_CREATE: The right to create a gateway under the organization.\n - RIGHT_ORGANIZATION_CLIENTS_LIST: The right to list the OAuth clients the organization is a collaborator of.\n - RIGHT_ORGANIZATION_CLIENTS_CREATE: The right to create an OAuth client under the organization.\n - RIGHT_ORGANIZATION_ADD_AS_COLLABORATOR: The right to add the organization as a collaborator on an existing entity.\n - RIGHT_ORGANIZATION_ALL: The pseudo-right for all (current and future) organization rights.\n - RIGHT_SEND_INVITES: The right to send invites to new users.\nNote that this is not prefixed with \"USER_\"; it is not a right on the user entity.\n - RIGHT_ALL: The pseudo-right for all (current and future) possible rights.", + "description": " - RIGHT_USER_INFO: The right to view user information.\n - RIGHT_USER_SETTINGS_BASIC: The right to edit basic user settings.\n - RIGHT_USER_SETTINGS_API_KEYS: The right to view and edit user API keys.\n - RIGHT_USER_DELETE: The right to delete user account.\n - RIGHT_USER_PURGE: The right to delete user account.\n - RIGHT_USER_AUTHORIZED_CLIENTS: The right to view and edit authorized OAuth clients of the user.\n - RIGHT_USER_APPLICATIONS_LIST: The right to list applications the user is a collaborator of.\n - RIGHT_USER_APPLICATIONS_CREATE: The right to create an application under the user account.\n - RIGHT_USER_GATEWAYS_LIST: The right to list gateways the user is a collaborator of.\n - RIGHT_USER_GATEWAYS_CREATE: The right to create a gateway under the account of the user.\n - RIGHT_USER_CLIENTS_LIST: The right to list OAuth clients the user is a collaborator of.\n - RIGHT_USER_CLIENTS_CREATE: The right to create an OAuth client under the account of the user.\n - RIGHT_USER_ORGANIZATIONS_LIST: The right to list organizations the user is a member of.\n - RIGHT_USER_ORGANIZATIONS_CREATE: The right to create an organization under the user account.\n - RIGHT_USER_NOTIFICATIONS_READ: The right to read notifications sent to the user.\n - RIGHT_USER_ALL: The pseudo-right for all (current and future) user rights.\n - RIGHT_APPLICATION_INFO: The right to view application information.\n - RIGHT_APPLICATION_SETTINGS_BASIC: The right to edit basic application settings.\n - RIGHT_APPLICATION_SETTINGS_API_KEYS: The right to view and edit application API keys.\n - RIGHT_APPLICATION_SETTINGS_COLLABORATORS: The right to view and edit application collaborators.\n - RIGHT_APPLICATION_SETTINGS_PACKAGES: The right to view and edit application packages and associations.\n - RIGHT_APPLICATION_DELETE: The right to delete application.\n - RIGHT_APPLICATION_PURGE: The right to purge application.\n - RIGHT_APPLICATION_DEVICES_READ: The right to view devices in application.\n - RIGHT_APPLICATION_DEVICES_WRITE: The right to create devices in application.\n - RIGHT_APPLICATION_DEVICES_READ_KEYS: The right to view device keys in application.\nNote that keys may not be stored in a way that supports viewing them.\n - RIGHT_APPLICATION_DEVICES_WRITE_KEYS: The right to edit device keys in application.\n - RIGHT_APPLICATION_TRAFFIC_READ: The right to read application traffic (uplink and downlink).\n - RIGHT_APPLICATION_TRAFFIC_UP_WRITE: The right to write uplink application traffic.\n - RIGHT_APPLICATION_TRAFFIC_DOWN_WRITE: The right to write downlink application traffic.\n - RIGHT_APPLICATION_LINK: The right to link as Application to a Network Server for traffic exchange,\ni.e. read uplink and write downlink (API keys only).\nThis right is typically only given to an Application Server.\nThis right implies RIGHT_APPLICATION_INFO, RIGHT_APPLICATION_TRAFFIC_READ,\nand RIGHT_APPLICATION_TRAFFIC_DOWN_WRITE.\n - RIGHT_APPLICATION_ALL: The pseudo-right for all (current and future) application rights.\n - RIGHT_CLIENT_ALL: The pseudo-right for all (current and future) OAuth client rights.\n - RIGHT_CLIENT_INFO: The right to read client information.\n - RIGHT_CLIENT_SETTINGS_BASIC: The right to edit basic client settings.\n - RIGHT_CLIENT_SETTINGS_COLLABORATORS: The right to view and edit client collaborators.\n - RIGHT_CLIENT_DELETE: The right to delete a client.\n - RIGHT_GATEWAY_INFO: The right to view gateway information.\n - RIGHT_GATEWAY_SETTINGS_BASIC: The right to edit basic gateway settings.\n - RIGHT_GATEWAY_SETTINGS_API_KEYS: The right to view and edit gateway API keys.\n - RIGHT_GATEWAY_SETTINGS_COLLABORATORS: The right to view and edit gateway collaborators.\n - RIGHT_GATEWAY_DELETE: The right to delete gateway.\n - RIGHT_GATEWAY_TRAFFIC_READ: The right to read gateway traffic.\n - RIGHT_GATEWAY_TRAFFIC_DOWN_WRITE: The right to write downlink gateway traffic.\n - RIGHT_GATEWAY_LINK: The right to link as Gateway to a Gateway Server for traffic exchange,\ni.e. write uplink and read downlink (API keys only)\nThis right is typically only given to a gateway.\nThis right implies RIGHT_GATEWAY_INFO.\n - RIGHT_GATEWAY_STATUS_READ: The right to view gateway status.\n - RIGHT_GATEWAY_LOCATION_READ: The right to view view gateway location.\n - RIGHT_GATEWAY_WRITE_SECRETS: The right to store secrets associated with this gateway.\n - RIGHT_GATEWAY_READ_SECRETS: The right to retrieve secrets associated with this gateway.\n - RIGHT_GATEWAY_ALL: The pseudo-right for all (current and future) gateway rights.\n - RIGHT_ORGANIZATION_INFO: The right to view organization information.\n - RIGHT_ORGANIZATION_SETTINGS_BASIC: The right to edit basic organization settings.\n - RIGHT_ORGANIZATION_SETTINGS_API_KEYS: The right to view and edit organization API keys.\n - RIGHT_ORGANIZATION_SETTINGS_MEMBERS: The right to view and edit organization members.\n - RIGHT_ORGANIZATION_DELETE: The right to delete organization.\n - RIGHT_ORGANIZATION_PURGE: The right to purge organization.\n - RIGHT_ORGANIZATION_APPLICATIONS_LIST: The right to list the applications the organization is a collaborator of.\n - RIGHT_ORGANIZATION_APPLICATIONS_CREATE: The right to create an application under the organization.\n - RIGHT_ORGANIZATION_GATEWAYS_LIST: The right to list the gateways the organization is a collaborator of.\n - RIGHT_ORGANIZATION_GATEWAYS_CREATE: The right to create a gateway under the organization.\n - RIGHT_ORGANIZATION_CLIENTS_LIST: The right to list the OAuth clients the organization is a collaborator of.\n - RIGHT_ORGANIZATION_CLIENTS_CREATE: The right to create an OAuth client under the organization.\n - RIGHT_ORGANIZATION_ADD_AS_COLLABORATOR: The right to add the organization as a collaborator on an existing entity.\n - RIGHT_ORGANIZATION_ALL: The pseudo-right for all (current and future) organization rights.\n - RIGHT_SEND_INVITES: The right to send invites to new users.\nNote that this is not prefixed with \"USER_\"; it is not a right on the user entity.\n - RIGHT_ALL: The pseudo-right for all (current and future) possible rights.", "in": "query", "required": false, "type": "array", @@ -6923,6 +6923,7 @@ "RIGHT_USER_SETTINGS_BASIC", "RIGHT_USER_SETTINGS_API_KEYS", "RIGHT_USER_DELETE", + "RIGHT_USER_PURGE", "RIGHT_USER_AUTHORIZED_CLIENTS", "RIGHT_USER_APPLICATIONS_LIST", "RIGHT_USER_APPLICATIONS_CREATE", @@ -28966,6 +28967,7 @@ "RIGHT_USER_SETTINGS_BASIC", "RIGHT_USER_SETTINGS_API_KEYS", "RIGHT_USER_DELETE", + "RIGHT_USER_PURGE", "RIGHT_USER_AUTHORIZED_CLIENTS", "RIGHT_USER_APPLICATIONS_LIST", "RIGHT_USER_APPLICATIONS_CREATE", @@ -29029,7 +29031,7 @@ "RIGHT_ALL" ], "default": "right_invalid", - "description": "Right is the enum that defines all the different rights to do something in the network.\n\n - RIGHT_USER_INFO: The right to view user information.\n - RIGHT_USER_SETTINGS_BASIC: The right to edit basic user settings.\n - RIGHT_USER_SETTINGS_API_KEYS: The right to view and edit user API keys.\n - RIGHT_USER_DELETE: The right to delete user account.\n - RIGHT_USER_AUTHORIZED_CLIENTS: The right to view and edit authorized OAuth clients of the user.\n - RIGHT_USER_APPLICATIONS_LIST: The right to list applications the user is a collaborator of.\n - RIGHT_USER_APPLICATIONS_CREATE: The right to create an application under the user account.\n - RIGHT_USER_GATEWAYS_LIST: The right to list gateways the user is a collaborator of.\n - RIGHT_USER_GATEWAYS_CREATE: The right to create a gateway under the account of the user.\n - RIGHT_USER_CLIENTS_LIST: The right to list OAuth clients the user is a collaborator of.\n - RIGHT_USER_CLIENTS_CREATE: The right to create an OAuth client under the account of the user.\n - RIGHT_USER_ORGANIZATIONS_LIST: The right to list organizations the user is a member of.\n - RIGHT_USER_ORGANIZATIONS_CREATE: The right to create an organization under the user account.\n - RIGHT_USER_NOTIFICATIONS_READ: The right to read notifications sent to the user.\n - RIGHT_USER_ALL: The pseudo-right for all (current and future) user rights.\n - RIGHT_APPLICATION_INFO: The right to view application information.\n - RIGHT_APPLICATION_SETTINGS_BASIC: The right to edit basic application settings.\n - RIGHT_APPLICATION_SETTINGS_API_KEYS: The right to view and edit application API keys.\n - RIGHT_APPLICATION_SETTINGS_COLLABORATORS: The right to view and edit application collaborators.\n - RIGHT_APPLICATION_SETTINGS_PACKAGES: The right to view and edit application packages and associations.\n - RIGHT_APPLICATION_DELETE: The right to delete application.\n - RIGHT_APPLICATION_PURGE: The right to purge application.\n - RIGHT_APPLICATION_DEVICES_READ: The right to view devices in application.\n - RIGHT_APPLICATION_DEVICES_WRITE: The right to create devices in application.\n - RIGHT_APPLICATION_DEVICES_READ_KEYS: The right to view device keys in application.\nNote that keys may not be stored in a way that supports viewing them.\n - RIGHT_APPLICATION_DEVICES_WRITE_KEYS: The right to edit device keys in application.\n - RIGHT_APPLICATION_TRAFFIC_READ: The right to read application traffic (uplink and downlink).\n - RIGHT_APPLICATION_TRAFFIC_UP_WRITE: The right to write uplink application traffic.\n - RIGHT_APPLICATION_TRAFFIC_DOWN_WRITE: The right to write downlink application traffic.\n - RIGHT_APPLICATION_LINK: The right to link as Application to a Network Server for traffic exchange,\ni.e. read uplink and write downlink (API keys only).\nThis right is typically only given to an Application Server.\nThis right implies RIGHT_APPLICATION_INFO, RIGHT_APPLICATION_TRAFFIC_READ,\nand RIGHT_APPLICATION_TRAFFIC_DOWN_WRITE.\n - RIGHT_APPLICATION_ALL: The pseudo-right for all (current and future) application rights.\n - RIGHT_CLIENT_ALL: The pseudo-right for all (current and future) OAuth client rights.\n - RIGHT_CLIENT_INFO: The right to read client information.\n - RIGHT_CLIENT_SETTINGS_BASIC: The right to edit basic client settings.\n - RIGHT_CLIENT_SETTINGS_COLLABORATORS: The right to view and edit client collaborators.\n - RIGHT_CLIENT_DELETE: The right to delete a client.\n - RIGHT_GATEWAY_INFO: The right to view gateway information.\n - RIGHT_GATEWAY_SETTINGS_BASIC: The right to edit basic gateway settings.\n - RIGHT_GATEWAY_SETTINGS_API_KEYS: The right to view and edit gateway API keys.\n - RIGHT_GATEWAY_SETTINGS_COLLABORATORS: The right to view and edit gateway collaborators.\n - RIGHT_GATEWAY_DELETE: The right to delete gateway.\n - RIGHT_GATEWAY_TRAFFIC_READ: The right to read gateway traffic.\n - RIGHT_GATEWAY_TRAFFIC_DOWN_WRITE: The right to write downlink gateway traffic.\n - RIGHT_GATEWAY_LINK: The right to link as Gateway to a Gateway Server for traffic exchange,\ni.e. write uplink and read downlink (API keys only)\nThis right is typically only given to a gateway.\nThis right implies RIGHT_GATEWAY_INFO.\n - RIGHT_GATEWAY_STATUS_READ: The right to view gateway status.\n - RIGHT_GATEWAY_LOCATION_READ: The right to view view gateway location.\n - RIGHT_GATEWAY_WRITE_SECRETS: The right to store secrets associated with this gateway.\n - RIGHT_GATEWAY_READ_SECRETS: The right to retrieve secrets associated with this gateway.\n - RIGHT_GATEWAY_ALL: The pseudo-right for all (current and future) gateway rights.\n - RIGHT_ORGANIZATION_INFO: The right to view organization information.\n - RIGHT_ORGANIZATION_SETTINGS_BASIC: The right to edit basic organization settings.\n - RIGHT_ORGANIZATION_SETTINGS_API_KEYS: The right to view and edit organization API keys.\n - RIGHT_ORGANIZATION_SETTINGS_MEMBERS: The right to view and edit organization members.\n - RIGHT_ORGANIZATION_DELETE: The right to delete organization.\n - RIGHT_ORGANIZATION_PURGE: The right to purge organization.\n - RIGHT_ORGANIZATION_APPLICATIONS_LIST: The right to list the applications the organization is a collaborator of.\n - RIGHT_ORGANIZATION_APPLICATIONS_CREATE: The right to create an application under the organization.\n - RIGHT_ORGANIZATION_GATEWAYS_LIST: The right to list the gateways the organization is a collaborator of.\n - RIGHT_ORGANIZATION_GATEWAYS_CREATE: The right to create a gateway under the organization.\n - RIGHT_ORGANIZATION_CLIENTS_LIST: The right to list the OAuth clients the organization is a collaborator of.\n - RIGHT_ORGANIZATION_CLIENTS_CREATE: The right to create an OAuth client under the organization.\n - RIGHT_ORGANIZATION_ADD_AS_COLLABORATOR: The right to add the organization as a collaborator on an existing entity.\n - RIGHT_ORGANIZATION_ALL: The pseudo-right for all (current and future) organization rights.\n - RIGHT_SEND_INVITES: The right to send invites to new users.\nNote that this is not prefixed with \"USER_\"; it is not a right on the user entity.\n - RIGHT_ALL: The pseudo-right for all (current and future) possible rights." + "description": "Right is the enum that defines all the different rights to do something in the network.\n\n - RIGHT_USER_INFO: The right to view user information.\n - RIGHT_USER_SETTINGS_BASIC: The right to edit basic user settings.\n - RIGHT_USER_SETTINGS_API_KEYS: The right to view and edit user API keys.\n - RIGHT_USER_DELETE: The right to delete user account.\n - RIGHT_USER_PURGE: The right to delete user account.\n - RIGHT_USER_AUTHORIZED_CLIENTS: The right to view and edit authorized OAuth clients of the user.\n - RIGHT_USER_APPLICATIONS_LIST: The right to list applications the user is a collaborator of.\n - RIGHT_USER_APPLICATIONS_CREATE: The right to create an application under the user account.\n - RIGHT_USER_GATEWAYS_LIST: The right to list gateways the user is a collaborator of.\n - RIGHT_USER_GATEWAYS_CREATE: The right to create a gateway under the account of the user.\n - RIGHT_USER_CLIENTS_LIST: The right to list OAuth clients the user is a collaborator of.\n - RIGHT_USER_CLIENTS_CREATE: The right to create an OAuth client under the account of the user.\n - RIGHT_USER_ORGANIZATIONS_LIST: The right to list organizations the user is a member of.\n - RIGHT_USER_ORGANIZATIONS_CREATE: The right to create an organization under the user account.\n - RIGHT_USER_NOTIFICATIONS_READ: The right to read notifications sent to the user.\n - RIGHT_USER_ALL: The pseudo-right for all (current and future) user rights.\n - RIGHT_APPLICATION_INFO: The right to view application information.\n - RIGHT_APPLICATION_SETTINGS_BASIC: The right to edit basic application settings.\n - RIGHT_APPLICATION_SETTINGS_API_KEYS: The right to view and edit application API keys.\n - RIGHT_APPLICATION_SETTINGS_COLLABORATORS: The right to view and edit application collaborators.\n - RIGHT_APPLICATION_SETTINGS_PACKAGES: The right to view and edit application packages and associations.\n - RIGHT_APPLICATION_DELETE: The right to delete application.\n - RIGHT_APPLICATION_PURGE: The right to purge application.\n - RIGHT_APPLICATION_DEVICES_READ: The right to view devices in application.\n - RIGHT_APPLICATION_DEVICES_WRITE: The right to create devices in application.\n - RIGHT_APPLICATION_DEVICES_READ_KEYS: The right to view device keys in application.\nNote that keys may not be stored in a way that supports viewing them.\n - RIGHT_APPLICATION_DEVICES_WRITE_KEYS: The right to edit device keys in application.\n - RIGHT_APPLICATION_TRAFFIC_READ: The right to read application traffic (uplink and downlink).\n - RIGHT_APPLICATION_TRAFFIC_UP_WRITE: The right to write uplink application traffic.\n - RIGHT_APPLICATION_TRAFFIC_DOWN_WRITE: The right to write downlink application traffic.\n - RIGHT_APPLICATION_LINK: The right to link as Application to a Network Server for traffic exchange,\ni.e. read uplink and write downlink (API keys only).\nThis right is typically only given to an Application Server.\nThis right implies RIGHT_APPLICATION_INFO, RIGHT_APPLICATION_TRAFFIC_READ,\nand RIGHT_APPLICATION_TRAFFIC_DOWN_WRITE.\n - RIGHT_APPLICATION_ALL: The pseudo-right for all (current and future) application rights.\n - RIGHT_CLIENT_ALL: The pseudo-right for all (current and future) OAuth client rights.\n - RIGHT_CLIENT_INFO: The right to read client information.\n - RIGHT_CLIENT_SETTINGS_BASIC: The right to edit basic client settings.\n - RIGHT_CLIENT_SETTINGS_COLLABORATORS: The right to view and edit client collaborators.\n - RIGHT_CLIENT_DELETE: The right to delete a client.\n - RIGHT_GATEWAY_INFO: The right to view gateway information.\n - RIGHT_GATEWAY_SETTINGS_BASIC: The right to edit basic gateway settings.\n - RIGHT_GATEWAY_SETTINGS_API_KEYS: The right to view and edit gateway API keys.\n - RIGHT_GATEWAY_SETTINGS_COLLABORATORS: The right to view and edit gateway collaborators.\n - RIGHT_GATEWAY_DELETE: The right to delete gateway.\n - RIGHT_GATEWAY_TRAFFIC_READ: The right to read gateway traffic.\n - RIGHT_GATEWAY_TRAFFIC_DOWN_WRITE: The right to write downlink gateway traffic.\n - RIGHT_GATEWAY_LINK: The right to link as Gateway to a Gateway Server for traffic exchange,\ni.e. write uplink and read downlink (API keys only)\nThis right is typically only given to a gateway.\nThis right implies RIGHT_GATEWAY_INFO.\n - RIGHT_GATEWAY_STATUS_READ: The right to view gateway status.\n - RIGHT_GATEWAY_LOCATION_READ: The right to view view gateway location.\n - RIGHT_GATEWAY_WRITE_SECRETS: The right to store secrets associated with this gateway.\n - RIGHT_GATEWAY_READ_SECRETS: The right to retrieve secrets associated with this gateway.\n - RIGHT_GATEWAY_ALL: The pseudo-right for all (current and future) gateway rights.\n - RIGHT_ORGANIZATION_INFO: The right to view organization information.\n - RIGHT_ORGANIZATION_SETTINGS_BASIC: The right to edit basic organization settings.\n - RIGHT_ORGANIZATION_SETTINGS_API_KEYS: The right to view and edit organization API keys.\n - RIGHT_ORGANIZATION_SETTINGS_MEMBERS: The right to view and edit organization members.\n - RIGHT_ORGANIZATION_DELETE: The right to delete organization.\n - RIGHT_ORGANIZATION_PURGE: The right to purge organization.\n - RIGHT_ORGANIZATION_APPLICATIONS_LIST: The right to list the applications the organization is a collaborator of.\n - RIGHT_ORGANIZATION_APPLICATIONS_CREATE: The right to create an application under the organization.\n - RIGHT_ORGANIZATION_GATEWAYS_LIST: The right to list the gateways the organization is a collaborator of.\n - RIGHT_ORGANIZATION_GATEWAYS_CREATE: The right to create a gateway under the organization.\n - RIGHT_ORGANIZATION_CLIENTS_LIST: The right to list the OAuth clients the organization is a collaborator of.\n - RIGHT_ORGANIZATION_CLIENTS_CREATE: The right to create an OAuth client under the organization.\n - RIGHT_ORGANIZATION_ADD_AS_COLLABORATOR: The right to add the organization as a collaborator on an existing entity.\n - RIGHT_ORGANIZATION_ALL: The pseudo-right for all (current and future) organization rights.\n - RIGHT_SEND_INVITES: The right to send invites to new users.\nNote that this is not prefixed with \"USER_\"; it is not a right on the user entity.\n - RIGHT_ALL: The pseudo-right for all (current and future) possible rights." }, "v3Rights": { "type": "object", diff --git a/api/ttn/lorawan/v3/rights.proto b/api/ttn/lorawan/v3/rights.proto index bc5bb06c39..5eb1825d8c 100644 --- a/api/ttn/lorawan/v3/rights.proto +++ b/api/ttn/lorawan/v3/rights.proto @@ -41,6 +41,8 @@ enum Right { RIGHT_USER_SETTINGS_API_KEYS = 3; // The right to delete user account. RIGHT_USER_DELETE = 4; + // The right to delete user account. + RIGHT_USER_PURGE = 66; // The right to view and edit authorized OAuth clients of the user. RIGHT_USER_AUTHORIZED_CLIENTS = 5; // The right to list applications the user is a collaborator of. @@ -179,7 +181,7 @@ enum Right { // The pseudo-right for all (current and future) possible rights. RIGHT_ALL = 55; - // Next value: 66 + // Next value: 67 } message Rights { diff --git a/pkg/identityserver/organization_registry.go b/pkg/identityserver/organization_registry.go index 6387e0a08a..47b6fb6cca 100644 --- a/pkg/identityserver/organization_registry.go +++ b/pkg/identityserver/organization_registry.go @@ -378,6 +378,11 @@ func (is *IdentityServer) purgeOrganization( if !is.IsAdmin(ctx) { return nil, errAdminsPurgeOrganizations.New() } + if err := rights.RequireOrganization( + store.WithSoftDeleted(ctx, false), ids, ttnpb.Right_RIGHT_ORGANIZATION_DELETE, + ); err != nil { + return nil, err + } err := is.store.Transact(ctx, func(ctx context.Context, st store.Store) error { // Delete related API keys before purging the organization. err := st.DeleteEntityAPIKeys(ctx, ids.GetEntityIdentifiers()) diff --git a/pkg/ttnpb/rights.pb.go b/pkg/ttnpb/rights.pb.go index 11d2b2d8a7..a2d777af5b 100644 --- a/pkg/ttnpb/rights.pb.go +++ b/pkg/ttnpb/rights.pb.go @@ -51,6 +51,8 @@ const ( Right_RIGHT_USER_SETTINGS_API_KEYS Right = 3 // The right to delete user account. Right_RIGHT_USER_DELETE Right = 4 + // The right to delete user account. + Right_RIGHT_USER_PURGE Right = 66 // The right to view and edit authorized OAuth clients of the user. Right_RIGHT_USER_AUTHORIZED_CLIENTS Right = 5 // The right to list applications the user is a collaborator of. @@ -192,6 +194,7 @@ var ( 2: "RIGHT_USER_SETTINGS_BASIC", 3: "RIGHT_USER_SETTINGS_API_KEYS", 4: "RIGHT_USER_DELETE", + 66: "RIGHT_USER_PURGE", 5: "RIGHT_USER_AUTHORIZED_CLIENTS", 6: "RIGHT_USER_APPLICATIONS_LIST", 7: "RIGHT_USER_APPLICATIONS_CREATE", @@ -260,6 +263,7 @@ var ( "RIGHT_USER_SETTINGS_BASIC": 2, "RIGHT_USER_SETTINGS_API_KEYS": 3, "RIGHT_USER_DELETE": 4, + "RIGHT_USER_PURGE": 66, "RIGHT_USER_AUTHORIZED_CLIENTS": 5, "RIGHT_USER_APPLICATIONS_LIST": 6, "RIGHT_USER_APPLICATIONS_CREATE": 7, @@ -774,7 +778,7 @@ var file_ttn_lorawan_v3_rights_proto_rawDesc = []byte{ 0x61, 0x62, 0x6f, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x43, 0x6f, 0x6c, 0x6c, 0x61, 0x62, 0x6f, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x0d, 0x63, - 0x6f, 0x6c, 0x6c, 0x61, 0x62, 0x6f, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x2a, 0x9a, 0x11, 0x0a, + 0x6f, 0x6c, 0x6c, 0x61, 0x62, 0x6f, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x2a, 0xb0, 0x11, 0x0a, 0x05, 0x52, 0x69, 0x67, 0x68, 0x74, 0x12, 0x11, 0x0a, 0x0d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x5f, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x01, 0x12, 0x1d, @@ -783,140 +787,141 @@ var file_ttn_lorawan_v3_rights_proto_rawDesc = []byte{ 0x1c, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x41, 0x50, 0x49, 0x5f, 0x4b, 0x45, 0x59, 0x53, 0x10, 0x03, 0x12, 0x15, 0x0a, 0x11, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x44, 0x45, - 0x4c, 0x45, 0x54, 0x45, 0x10, 0x04, 0x12, 0x21, 0x0a, 0x1d, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, - 0x55, 0x53, 0x45, 0x52, 0x5f, 0x41, 0x55, 0x54, 0x48, 0x4f, 0x52, 0x49, 0x5a, 0x45, 0x44, 0x5f, - 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x53, 0x10, 0x05, 0x12, 0x20, 0x0a, 0x1c, 0x52, 0x49, 0x47, - 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, - 0x49, 0x4f, 0x4e, 0x53, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x06, 0x12, 0x22, 0x0a, 0x1e, 0x52, - 0x49, 0x47, 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, - 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, 0x07, 0x12, - 0x1c, 0x0a, 0x18, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x47, 0x41, - 0x54, 0x45, 0x57, 0x41, 0x59, 0x53, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x08, 0x12, 0x1e, 0x0a, - 0x1a, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x47, 0x41, 0x54, 0x45, - 0x57, 0x41, 0x59, 0x53, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, 0x09, 0x12, 0x1b, 0x0a, - 0x17, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x43, 0x4c, 0x49, 0x45, - 0x4e, 0x54, 0x53, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x0a, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x49, - 0x47, 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x53, - 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, 0x0b, 0x12, 0x21, 0x0a, 0x1d, 0x52, 0x49, 0x47, - 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, - 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x0c, 0x12, 0x23, 0x0a, 0x1f, - 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, - 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, - 0x0d, 0x12, 0x21, 0x0a, 0x1d, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, - 0x4e, 0x4f, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x5f, 0x52, 0x45, - 0x41, 0x44, 0x10, 0x3b, 0x12, 0x12, 0x0a, 0x0e, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x55, 0x53, - 0x45, 0x52, 0x5f, 0x41, 0x4c, 0x4c, 0x10, 0x0e, 0x12, 0x1a, 0x0a, 0x16, 0x52, 0x49, 0x47, 0x48, - 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x49, 0x4e, - 0x46, 0x4f, 0x10, 0x0f, 0x12, 0x24, 0x0a, 0x20, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x50, - 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, - 0x47, 0x53, 0x5f, 0x42, 0x41, 0x53, 0x49, 0x43, 0x10, 0x10, 0x12, 0x27, 0x0a, 0x23, 0x52, 0x49, - 0x47, 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, - 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x41, 0x50, 0x49, 0x5f, 0x4b, 0x45, 0x59, - 0x53, 0x10, 0x11, 0x12, 0x2c, 0x0a, 0x28, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, - 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, - 0x53, 0x5f, 0x43, 0x4f, 0x4c, 0x4c, 0x41, 0x42, 0x4f, 0x52, 0x41, 0x54, 0x4f, 0x52, 0x53, 0x10, - 0x12, 0x12, 0x27, 0x0a, 0x23, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, - 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, - 0x50, 0x41, 0x43, 0x4b, 0x41, 0x47, 0x45, 0x53, 0x10, 0x38, 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x49, + 0x4c, 0x45, 0x54, 0x45, 0x10, 0x04, 0x12, 0x14, 0x0a, 0x10, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, + 0x55, 0x53, 0x45, 0x52, 0x5f, 0x50, 0x55, 0x52, 0x47, 0x45, 0x10, 0x42, 0x12, 0x21, 0x0a, 0x1d, + 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x41, 0x55, 0x54, 0x48, 0x4f, + 0x52, 0x49, 0x5a, 0x45, 0x44, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x53, 0x10, 0x05, 0x12, + 0x20, 0x0a, 0x1c, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x41, 0x50, + 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, + 0x06, 0x12, 0x22, 0x0a, 0x1e, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, + 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x5f, 0x43, 0x52, 0x45, + 0x41, 0x54, 0x45, 0x10, 0x07, 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x55, + 0x53, 0x45, 0x52, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x53, 0x5f, 0x4c, 0x49, 0x53, + 0x54, 0x10, 0x08, 0x12, 0x1e, 0x0a, 0x1a, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, + 0x52, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x53, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, + 0x45, 0x10, 0x09, 0x12, 0x1b, 0x0a, 0x17, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, + 0x52, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x53, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x0a, + 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x43, + 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x53, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, 0x0b, 0x12, + 0x21, 0x0a, 0x1d, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x4f, 0x52, + 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x5f, 0x4c, 0x49, 0x53, 0x54, + 0x10, 0x0c, 0x12, 0x23, 0x0a, 0x1f, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x52, + 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x5f, 0x43, + 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, 0x0d, 0x12, 0x21, 0x0a, 0x1d, 0x52, 0x49, 0x47, 0x48, 0x54, + 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x4e, 0x4f, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x49, + 0x4f, 0x4e, 0x53, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x10, 0x3b, 0x12, 0x12, 0x0a, 0x0e, 0x52, 0x49, + 0x47, 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x41, 0x4c, 0x4c, 0x10, 0x0e, 0x12, 0x1a, + 0x0a, 0x16, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, + 0x49, 0x4f, 0x4e, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x0f, 0x12, 0x24, 0x0a, 0x20, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, - 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x13, 0x12, 0x1b, 0x0a, 0x17, 0x52, 0x49, 0x47, 0x48, - 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x50, 0x55, - 0x52, 0x47, 0x45, 0x10, 0x40, 0x12, 0x22, 0x0a, 0x1e, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, - 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x56, 0x49, 0x43, - 0x45, 0x53, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x10, 0x14, 0x12, 0x23, 0x0a, 0x1f, 0x52, 0x49, 0x47, - 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x44, - 0x45, 0x56, 0x49, 0x43, 0x45, 0x53, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x10, 0x15, 0x12, 0x27, - 0x0a, 0x23, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, - 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x53, 0x5f, 0x52, 0x45, 0x41, 0x44, - 0x5f, 0x4b, 0x45, 0x59, 0x53, 0x10, 0x16, 0x12, 0x28, 0x0a, 0x24, 0x52, 0x49, 0x47, 0x48, 0x54, - 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x56, - 0x49, 0x43, 0x45, 0x53, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x5f, 0x4b, 0x45, 0x59, 0x53, 0x10, - 0x17, 0x12, 0x22, 0x0a, 0x1e, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, - 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x54, 0x52, 0x41, 0x46, 0x46, 0x49, 0x43, 0x5f, 0x52, - 0x45, 0x41, 0x44, 0x10, 0x18, 0x12, 0x26, 0x0a, 0x22, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, - 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x54, 0x52, 0x41, 0x46, 0x46, - 0x49, 0x43, 0x5f, 0x55, 0x50, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x10, 0x19, 0x12, 0x28, 0x0a, - 0x24, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, - 0x4f, 0x4e, 0x5f, 0x54, 0x52, 0x41, 0x46, 0x46, 0x49, 0x43, 0x5f, 0x44, 0x4f, 0x57, 0x4e, 0x5f, - 0x57, 0x52, 0x49, 0x54, 0x45, 0x10, 0x1a, 0x12, 0x1a, 0x0a, 0x16, 0x52, 0x49, 0x47, 0x48, 0x54, - 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4c, 0x49, 0x4e, - 0x4b, 0x10, 0x1b, 0x12, 0x19, 0x0a, 0x15, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, - 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x4c, 0x4c, 0x10, 0x1c, 0x12, 0x14, - 0x0a, 0x10, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x41, - 0x4c, 0x4c, 0x10, 0x1d, 0x12, 0x15, 0x0a, 0x11, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x43, 0x4c, - 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x3c, 0x12, 0x1f, 0x0a, 0x1b, 0x52, - 0x49, 0x47, 0x48, 0x54, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x53, 0x45, 0x54, 0x54, - 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x42, 0x41, 0x53, 0x49, 0x43, 0x10, 0x3d, 0x12, 0x27, 0x0a, 0x23, - 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x53, 0x45, 0x54, - 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x43, 0x4f, 0x4c, 0x4c, 0x41, 0x42, 0x4f, 0x52, 0x41, 0x54, - 0x4f, 0x52, 0x53, 0x10, 0x3e, 0x12, 0x17, 0x0a, 0x13, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x43, - 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x3f, 0x12, 0x16, - 0x0a, 0x12, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, - 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x1e, 0x12, 0x20, 0x0a, 0x1c, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, - 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, - 0x5f, 0x42, 0x41, 0x53, 0x49, 0x43, 0x10, 0x1f, 0x12, 0x23, 0x0a, 0x1f, 0x52, 0x49, 0x47, 0x48, - 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, - 0x47, 0x53, 0x5f, 0x41, 0x50, 0x49, 0x5f, 0x4b, 0x45, 0x59, 0x53, 0x10, 0x20, 0x12, 0x28, 0x0a, - 0x24, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x53, + 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x42, 0x41, 0x53, 0x49, 0x43, 0x10, 0x10, + 0x12, 0x27, 0x0a, 0x23, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, + 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x41, + 0x50, 0x49, 0x5f, 0x4b, 0x45, 0x59, 0x53, 0x10, 0x11, 0x12, 0x2c, 0x0a, 0x28, 0x52, 0x49, 0x47, + 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x43, 0x4f, 0x4c, 0x4c, 0x41, 0x42, 0x4f, 0x52, - 0x41, 0x54, 0x4f, 0x52, 0x53, 0x10, 0x21, 0x12, 0x18, 0x0a, 0x14, 0x52, 0x49, 0x47, 0x48, 0x54, - 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, - 0x22, 0x12, 0x1e, 0x0a, 0x1a, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, - 0x41, 0x59, 0x5f, 0x54, 0x52, 0x41, 0x46, 0x46, 0x49, 0x43, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x10, - 0x23, 0x12, 0x24, 0x0a, 0x20, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, - 0x41, 0x59, 0x5f, 0x54, 0x52, 0x41, 0x46, 0x46, 0x49, 0x43, 0x5f, 0x44, 0x4f, 0x57, 0x4e, 0x5f, - 0x57, 0x52, 0x49, 0x54, 0x45, 0x10, 0x24, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x49, 0x47, 0x48, 0x54, - 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x4c, 0x49, 0x4e, 0x4b, 0x10, 0x25, 0x12, - 0x1d, 0x0a, 0x19, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, - 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x10, 0x26, 0x12, 0x1f, - 0x0a, 0x1b, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, - 0x4c, 0x4f, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x10, 0x27, 0x12, - 0x1f, 0x0a, 0x1b, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, - 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x5f, 0x53, 0x45, 0x43, 0x52, 0x45, 0x54, 0x53, 0x10, 0x39, - 0x12, 0x1e, 0x0a, 0x1a, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, - 0x59, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x53, 0x45, 0x43, 0x52, 0x45, 0x54, 0x53, 0x10, 0x3a, - 0x12, 0x15, 0x0a, 0x11, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, - 0x59, 0x5f, 0x41, 0x4c, 0x4c, 0x10, 0x28, 0x12, 0x1b, 0x0a, 0x17, 0x52, 0x49, 0x47, 0x48, 0x54, - 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x49, 0x4e, - 0x46, 0x4f, 0x10, 0x29, 0x12, 0x25, 0x0a, 0x21, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, - 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, - 0x4e, 0x47, 0x53, 0x5f, 0x42, 0x41, 0x53, 0x49, 0x43, 0x10, 0x2a, 0x12, 0x28, 0x0a, 0x24, 0x52, + 0x41, 0x54, 0x4f, 0x52, 0x53, 0x10, 0x12, 0x12, 0x27, 0x0a, 0x23, 0x52, 0x49, 0x47, 0x48, 0x54, + 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x45, 0x54, + 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x50, 0x41, 0x43, 0x4b, 0x41, 0x47, 0x45, 0x53, 0x10, 0x38, + 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, + 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x13, 0x12, 0x1b, + 0x0a, 0x17, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, + 0x49, 0x4f, 0x4e, 0x5f, 0x50, 0x55, 0x52, 0x47, 0x45, 0x10, 0x40, 0x12, 0x22, 0x0a, 0x1e, 0x52, + 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, + 0x5f, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x53, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x10, 0x14, 0x12, + 0x23, 0x0a, 0x1f, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, + 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x53, 0x5f, 0x57, 0x52, 0x49, + 0x54, 0x45, 0x10, 0x15, 0x12, 0x27, 0x0a, 0x23, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x50, + 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, + 0x53, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x4b, 0x45, 0x59, 0x53, 0x10, 0x16, 0x12, 0x28, 0x0a, + 0x24, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, + 0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x53, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, + 0x5f, 0x4b, 0x45, 0x59, 0x53, 0x10, 0x17, 0x12, 0x22, 0x0a, 0x1e, 0x52, 0x49, 0x47, 0x48, 0x54, + 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x54, 0x52, 0x41, + 0x46, 0x46, 0x49, 0x43, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x10, 0x18, 0x12, 0x26, 0x0a, 0x22, 0x52, + 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, + 0x5f, 0x54, 0x52, 0x41, 0x46, 0x46, 0x49, 0x43, 0x5f, 0x55, 0x50, 0x5f, 0x57, 0x52, 0x49, 0x54, + 0x45, 0x10, 0x19, 0x12, 0x28, 0x0a, 0x24, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, + 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x54, 0x52, 0x41, 0x46, 0x46, 0x49, 0x43, + 0x5f, 0x44, 0x4f, 0x57, 0x4e, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x10, 0x1a, 0x12, 0x1a, 0x0a, + 0x16, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, + 0x4f, 0x4e, 0x5f, 0x4c, 0x49, 0x4e, 0x4b, 0x10, 0x1b, 0x12, 0x19, 0x0a, 0x15, 0x52, 0x49, 0x47, + 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x41, + 0x4c, 0x4c, 0x10, 0x1c, 0x12, 0x14, 0x0a, 0x10, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x43, 0x4c, + 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x41, 0x4c, 0x4c, 0x10, 0x1d, 0x12, 0x15, 0x0a, 0x11, 0x52, 0x49, + 0x47, 0x48, 0x54, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x10, + 0x3c, 0x12, 0x1f, 0x0a, 0x1b, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, + 0x54, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x42, 0x41, 0x53, 0x49, 0x43, + 0x10, 0x3d, 0x12, 0x27, 0x0a, 0x23, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x43, 0x4c, 0x49, 0x45, + 0x4e, 0x54, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x43, 0x4f, 0x4c, 0x4c, + 0x41, 0x42, 0x4f, 0x52, 0x41, 0x54, 0x4f, 0x52, 0x53, 0x10, 0x3e, 0x12, 0x17, 0x0a, 0x13, 0x52, + 0x49, 0x47, 0x48, 0x54, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x44, 0x45, 0x4c, 0x45, + 0x54, 0x45, 0x10, 0x3f, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, + 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x1e, 0x12, 0x20, 0x0a, 0x1c, + 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x53, 0x45, + 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x42, 0x41, 0x53, 0x49, 0x43, 0x10, 0x1f, 0x12, 0x23, + 0x0a, 0x1f, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, + 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x41, 0x50, 0x49, 0x5f, 0x4b, 0x45, 0x59, + 0x53, 0x10, 0x20, 0x12, 0x28, 0x0a, 0x24, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, + 0x45, 0x57, 0x41, 0x59, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x43, 0x4f, + 0x4c, 0x4c, 0x41, 0x42, 0x4f, 0x52, 0x41, 0x54, 0x4f, 0x52, 0x53, 0x10, 0x21, 0x12, 0x18, 0x0a, + 0x14, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x44, + 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x22, 0x12, 0x1e, 0x0a, 0x1a, 0x52, 0x49, 0x47, 0x48, 0x54, + 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x54, 0x52, 0x41, 0x46, 0x46, 0x49, 0x43, + 0x5f, 0x52, 0x45, 0x41, 0x44, 0x10, 0x23, 0x12, 0x24, 0x0a, 0x20, 0x52, 0x49, 0x47, 0x48, 0x54, + 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x54, 0x52, 0x41, 0x46, 0x46, 0x49, 0x43, + 0x5f, 0x44, 0x4f, 0x57, 0x4e, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x10, 0x24, 0x12, 0x16, 0x0a, + 0x12, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x4c, + 0x49, 0x4e, 0x4b, 0x10, 0x25, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, + 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x45, + 0x41, 0x44, 0x10, 0x26, 0x12, 0x1f, 0x0a, 0x1b, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, + 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x4c, 0x4f, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x52, + 0x45, 0x41, 0x44, 0x10, 0x27, 0x12, 0x1f, 0x0a, 0x1b, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, + 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x5f, 0x53, 0x45, 0x43, + 0x52, 0x45, 0x54, 0x53, 0x10, 0x39, 0x12, 0x1e, 0x0a, 0x1a, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, + 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x53, 0x45, 0x43, + 0x52, 0x45, 0x54, 0x53, 0x10, 0x3a, 0x12, 0x15, 0x0a, 0x11, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, + 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x41, 0x4c, 0x4c, 0x10, 0x28, 0x12, 0x1b, 0x0a, + 0x17, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, + 0x49, 0x4f, 0x4e, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x29, 0x12, 0x25, 0x0a, 0x21, 0x52, 0x49, + 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, + 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x42, 0x41, 0x53, 0x49, 0x43, 0x10, + 0x2a, 0x12, 0x28, 0x0a, 0x24, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, + 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, + 0x5f, 0x41, 0x50, 0x49, 0x5f, 0x4b, 0x45, 0x59, 0x53, 0x10, 0x2b, 0x12, 0x27, 0x0a, 0x23, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, - 0x4e, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x41, 0x50, 0x49, 0x5f, 0x4b, - 0x45, 0x59, 0x53, 0x10, 0x2b, 0x12, 0x27, 0x0a, 0x23, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, - 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x45, 0x54, 0x54, - 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, 0x53, 0x10, 0x2c, 0x12, 0x1d, - 0x0a, 0x19, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, - 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x2d, 0x12, 0x1c, 0x0a, - 0x18, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, - 0x49, 0x4f, 0x4e, 0x5f, 0x50, 0x55, 0x52, 0x47, 0x45, 0x10, 0x41, 0x12, 0x28, 0x0a, 0x24, 0x52, + 0x4e, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x4d, 0x45, 0x4d, 0x42, 0x45, + 0x52, 0x53, 0x10, 0x2c, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, + 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, + 0x45, 0x10, 0x2d, 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, + 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x50, 0x55, 0x52, 0x47, 0x45, 0x10, + 0x41, 0x12, 0x28, 0x0a, 0x24, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, + 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, + 0x49, 0x4f, 0x4e, 0x53, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x2e, 0x12, 0x2a, 0x0a, 0x26, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, - 0x4e, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x5f, 0x4c, - 0x49, 0x53, 0x54, 0x10, 0x2e, 0x12, 0x2a, 0x0a, 0x26, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, - 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x50, 0x50, 0x4c, - 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, - 0x2f, 0x12, 0x24, 0x0a, 0x20, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, - 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x53, - 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x30, 0x12, 0x26, 0x0a, 0x22, 0x52, 0x49, 0x47, 0x48, 0x54, + 0x4e, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x5f, 0x43, + 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, 0x2f, 0x12, 0x24, 0x0a, 0x20, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x47, 0x41, - 0x54, 0x45, 0x57, 0x41, 0x59, 0x53, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, 0x31, 0x12, - 0x23, 0x0a, 0x1f, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, - 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x53, 0x5f, 0x4c, 0x49, - 0x53, 0x54, 0x10, 0x32, 0x12, 0x25, 0x0a, 0x21, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, - 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, - 0x54, 0x53, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, 0x33, 0x12, 0x2a, 0x0a, 0x26, 0x52, - 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, - 0x4e, 0x5f, 0x41, 0x44, 0x44, 0x5f, 0x41, 0x53, 0x5f, 0x43, 0x4f, 0x4c, 0x4c, 0x41, 0x42, 0x4f, - 0x52, 0x41, 0x54, 0x4f, 0x52, 0x10, 0x34, 0x12, 0x1a, 0x0a, 0x16, 0x52, 0x49, 0x47, 0x48, 0x54, - 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x4c, - 0x4c, 0x10, 0x35, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x53, 0x45, 0x4e, - 0x44, 0x5f, 0x49, 0x4e, 0x56, 0x49, 0x54, 0x45, 0x53, 0x10, 0x36, 0x12, 0x0d, 0x0a, 0x09, 0x52, - 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x4c, 0x4c, 0x10, 0x37, 0x1a, 0x0d, 0xea, 0xaa, 0x19, 0x09, - 0x18, 0x01, 0x2a, 0x05, 0x52, 0x49, 0x47, 0x48, 0x54, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x6f, 0x2e, - 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, - 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, - 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x74, 0x6e, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x54, 0x45, 0x57, 0x41, 0x59, 0x53, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x30, 0x12, 0x26, 0x0a, + 0x22, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, + 0x49, 0x4f, 0x4e, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x53, 0x5f, 0x43, 0x52, 0x45, + 0x41, 0x54, 0x45, 0x10, 0x31, 0x12, 0x23, 0x0a, 0x1f, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, + 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x43, 0x4c, 0x49, 0x45, + 0x4e, 0x54, 0x53, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x32, 0x12, 0x25, 0x0a, 0x21, 0x52, 0x49, + 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, + 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x53, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, + 0x33, 0x12, 0x2a, 0x0a, 0x26, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, + 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x44, 0x44, 0x5f, 0x41, 0x53, 0x5f, 0x43, + 0x4f, 0x4c, 0x4c, 0x41, 0x42, 0x4f, 0x52, 0x41, 0x54, 0x4f, 0x52, 0x10, 0x34, 0x12, 0x1a, 0x0a, + 0x16, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, + 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x4c, 0x4c, 0x10, 0x35, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x49, 0x47, + 0x48, 0x54, 0x5f, 0x53, 0x45, 0x4e, 0x44, 0x5f, 0x49, 0x4e, 0x56, 0x49, 0x54, 0x45, 0x53, 0x10, + 0x36, 0x12, 0x0d, 0x0a, 0x09, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x4c, 0x4c, 0x10, 0x37, + 0x1a, 0x0d, 0xea, 0xaa, 0x19, 0x09, 0x18, 0x01, 0x2a, 0x05, 0x52, 0x49, 0x47, 0x48, 0x54, 0x42, + 0x31, 0x5a, 0x2f, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, + 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, + 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x74, 0x6e, + 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/pkg/ttnpb/rights_json.pb.go b/pkg/ttnpb/rights_json.pb.go index 1ab2998752..b59648e27d 100644 --- a/pkg/ttnpb/rights_json.pb.go +++ b/pkg/ttnpb/rights_json.pb.go @@ -32,6 +32,7 @@ var Right_customvalue = map[string]int32{ "USER_SETTINGS_BASIC": 2, "USER_SETTINGS_API_KEYS": 3, "USER_DELETE": 4, + "USER_PURGE": 66, "USER_AUTHORIZED_CLIENTS": 5, "USER_APPLICATIONS_LIST": 6, "USER_APPLICATIONS_CREATE": 7, diff --git a/sdk/js/generated/api.json b/sdk/js/generated/api.json index 07961b1885..a46eeaa38d 100644 --- a/sdk/js/generated/api.json +++ b/sdk/js/generated/api.json @@ -49739,6 +49739,11 @@ "number": "4", "description": "The right to delete user account." }, + { + "name": "RIGHT_USER_PURGE", + "number": "66", + "description": "The right to delete user account." + }, { "name": "RIGHT_USER_AUTHORIZED_CLIENTS", "number": "5", From 493d96334d12adbac12abc1b5a61929bcde3ff1e Mon Sep 17 00:00:00 2001 From: Nicholas Cristofaro Date: Mon, 25 Nov 2024 10:18:55 -0300 Subject: [PATCH 12/40] is: Update purgeUser to check rights --- pkg/identityserver/user_registry.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pkg/identityserver/user_registry.go b/pkg/identityserver/user_registry.go index 3962e65056..22de9f7c98 100644 --- a/pkg/identityserver/user_registry.go +++ b/pkg/identityserver/user_registry.go @@ -751,6 +751,11 @@ func (is *IdentityServer) purgeUser(ctx context.Context, ids *ttnpb.UserIdentifi if !is.IsAdmin(ctx) { return nil, errAdminsPurgeUsers.New() } + if err := rights.RequireUser( + store.WithSoftDeleted(ctx, false), ids, ttnpb.Right_RIGHT_USER_PURGE, + ); err != nil { + return nil, err + } err := is.store.Transact(ctx, func(ctx context.Context, st store.Store) error { // Delete related API keys before purging the user. err := st.DeleteEntityAPIKeys(ctx, ids.GetEntityIdentifiers()) From 3a11d9604cb2a04efaa260f1caa2ff3e9f0a8f5e Mon Sep 17 00:00:00 2001 From: Nicholas Cristofaro Date: Mon, 25 Nov 2024 10:19:58 -0300 Subject: [PATCH 13/40] api: Add RIGHT_GATEWAY_PURGE --- api/ttn/lorawan/v3/api.md | 1 + api/ttn/lorawan/v3/api.swagger.json | 6 +- api/ttn/lorawan/v3/rights.proto | 4 +- pkg/ttnpb/rights.pb.go | 116 +++++++++++++++------------- pkg/ttnpb/rights_json.pb.go | 1 + sdk/js/generated/api.json | 5 ++ 6 files changed, 75 insertions(+), 58 deletions(-) diff --git a/api/ttn/lorawan/v3/api.md b/api/ttn/lorawan/v3/api.md index aac20cb240..4741b9aab0 100644 --- a/api/ttn/lorawan/v3/api.md +++ b/api/ttn/lorawan/v3/api.md @@ -11014,6 +11014,7 @@ Right is the enum that defines all the different rights to do something in the n | `RIGHT_GATEWAY_SETTINGS_API_KEYS` | 32 | The right to view and edit gateway API keys. | | `RIGHT_GATEWAY_SETTINGS_COLLABORATORS` | 33 | The right to view and edit gateway collaborators. | | `RIGHT_GATEWAY_DELETE` | 34 | The right to delete gateway. | +| `RIGHT_GATEWAY_PURGE` | 67 | The right to purge gateway. | | `RIGHT_GATEWAY_TRAFFIC_READ` | 35 | The right to read gateway traffic. | | `RIGHT_GATEWAY_TRAFFIC_DOWN_WRITE` | 36 | The right to write downlink gateway traffic. | | `RIGHT_GATEWAY_LINK` | 37 | The right to link as Gateway to a Gateway Server for traffic exchange, i.e. write uplink and read downlink (API keys only) This right is typically only given to a gateway. This right implies RIGHT_GATEWAY_INFO. | diff --git a/api/ttn/lorawan/v3/api.swagger.json b/api/ttn/lorawan/v3/api.swagger.json index 9e22a00a38..5dcf65c925 100644 --- a/api/ttn/lorawan/v3/api.swagger.json +++ b/api/ttn/lorawan/v3/api.swagger.json @@ -6911,7 +6911,7 @@ "parameters": [ { "name": "required.rights", - "description": " - RIGHT_USER_INFO: The right to view user information.\n - RIGHT_USER_SETTINGS_BASIC: The right to edit basic user settings.\n - RIGHT_USER_SETTINGS_API_KEYS: The right to view and edit user API keys.\n - RIGHT_USER_DELETE: The right to delete user account.\n - RIGHT_USER_PURGE: The right to delete user account.\n - RIGHT_USER_AUTHORIZED_CLIENTS: The right to view and edit authorized OAuth clients of the user.\n - RIGHT_USER_APPLICATIONS_LIST: The right to list applications the user is a collaborator of.\n - RIGHT_USER_APPLICATIONS_CREATE: The right to create an application under the user account.\n - RIGHT_USER_GATEWAYS_LIST: The right to list gateways the user is a collaborator of.\n - RIGHT_USER_GATEWAYS_CREATE: The right to create a gateway under the account of the user.\n - RIGHT_USER_CLIENTS_LIST: The right to list OAuth clients the user is a collaborator of.\n - RIGHT_USER_CLIENTS_CREATE: The right to create an OAuth client under the account of the user.\n - RIGHT_USER_ORGANIZATIONS_LIST: The right to list organizations the user is a member of.\n - RIGHT_USER_ORGANIZATIONS_CREATE: The right to create an organization under the user account.\n - RIGHT_USER_NOTIFICATIONS_READ: The right to read notifications sent to the user.\n - RIGHT_USER_ALL: The pseudo-right for all (current and future) user rights.\n - RIGHT_APPLICATION_INFO: The right to view application information.\n - RIGHT_APPLICATION_SETTINGS_BASIC: The right to edit basic application settings.\n - RIGHT_APPLICATION_SETTINGS_API_KEYS: The right to view and edit application API keys.\n - RIGHT_APPLICATION_SETTINGS_COLLABORATORS: The right to view and edit application collaborators.\n - RIGHT_APPLICATION_SETTINGS_PACKAGES: The right to view and edit application packages and associations.\n - RIGHT_APPLICATION_DELETE: The right to delete application.\n - RIGHT_APPLICATION_PURGE: The right to purge application.\n - RIGHT_APPLICATION_DEVICES_READ: The right to view devices in application.\n - RIGHT_APPLICATION_DEVICES_WRITE: The right to create devices in application.\n - RIGHT_APPLICATION_DEVICES_READ_KEYS: The right to view device keys in application.\nNote that keys may not be stored in a way that supports viewing them.\n - RIGHT_APPLICATION_DEVICES_WRITE_KEYS: The right to edit device keys in application.\n - RIGHT_APPLICATION_TRAFFIC_READ: The right to read application traffic (uplink and downlink).\n - RIGHT_APPLICATION_TRAFFIC_UP_WRITE: The right to write uplink application traffic.\n - RIGHT_APPLICATION_TRAFFIC_DOWN_WRITE: The right to write downlink application traffic.\n - RIGHT_APPLICATION_LINK: The right to link as Application to a Network Server for traffic exchange,\ni.e. read uplink and write downlink (API keys only).\nThis right is typically only given to an Application Server.\nThis right implies RIGHT_APPLICATION_INFO, RIGHT_APPLICATION_TRAFFIC_READ,\nand RIGHT_APPLICATION_TRAFFIC_DOWN_WRITE.\n - RIGHT_APPLICATION_ALL: The pseudo-right for all (current and future) application rights.\n - RIGHT_CLIENT_ALL: The pseudo-right for all (current and future) OAuth client rights.\n - RIGHT_CLIENT_INFO: The right to read client information.\n - RIGHT_CLIENT_SETTINGS_BASIC: The right to edit basic client settings.\n - RIGHT_CLIENT_SETTINGS_COLLABORATORS: The right to view and edit client collaborators.\n - RIGHT_CLIENT_DELETE: The right to delete a client.\n - RIGHT_GATEWAY_INFO: The right to view gateway information.\n - RIGHT_GATEWAY_SETTINGS_BASIC: The right to edit basic gateway settings.\n - RIGHT_GATEWAY_SETTINGS_API_KEYS: The right to view and edit gateway API keys.\n - RIGHT_GATEWAY_SETTINGS_COLLABORATORS: The right to view and edit gateway collaborators.\n - RIGHT_GATEWAY_DELETE: The right to delete gateway.\n - RIGHT_GATEWAY_TRAFFIC_READ: The right to read gateway traffic.\n - RIGHT_GATEWAY_TRAFFIC_DOWN_WRITE: The right to write downlink gateway traffic.\n - RIGHT_GATEWAY_LINK: The right to link as Gateway to a Gateway Server for traffic exchange,\ni.e. write uplink and read downlink (API keys only)\nThis right is typically only given to a gateway.\nThis right implies RIGHT_GATEWAY_INFO.\n - RIGHT_GATEWAY_STATUS_READ: The right to view gateway status.\n - RIGHT_GATEWAY_LOCATION_READ: The right to view view gateway location.\n - RIGHT_GATEWAY_WRITE_SECRETS: The right to store secrets associated with this gateway.\n - RIGHT_GATEWAY_READ_SECRETS: The right to retrieve secrets associated with this gateway.\n - RIGHT_GATEWAY_ALL: The pseudo-right for all (current and future) gateway rights.\n - RIGHT_ORGANIZATION_INFO: The right to view organization information.\n - RIGHT_ORGANIZATION_SETTINGS_BASIC: The right to edit basic organization settings.\n - RIGHT_ORGANIZATION_SETTINGS_API_KEYS: The right to view and edit organization API keys.\n - RIGHT_ORGANIZATION_SETTINGS_MEMBERS: The right to view and edit organization members.\n - RIGHT_ORGANIZATION_DELETE: The right to delete organization.\n - RIGHT_ORGANIZATION_PURGE: The right to purge organization.\n - RIGHT_ORGANIZATION_APPLICATIONS_LIST: The right to list the applications the organization is a collaborator of.\n - RIGHT_ORGANIZATION_APPLICATIONS_CREATE: The right to create an application under the organization.\n - RIGHT_ORGANIZATION_GATEWAYS_LIST: The right to list the gateways the organization is a collaborator of.\n - RIGHT_ORGANIZATION_GATEWAYS_CREATE: The right to create a gateway under the organization.\n - RIGHT_ORGANIZATION_CLIENTS_LIST: The right to list the OAuth clients the organization is a collaborator of.\n - RIGHT_ORGANIZATION_CLIENTS_CREATE: The right to create an OAuth client under the organization.\n - RIGHT_ORGANIZATION_ADD_AS_COLLABORATOR: The right to add the organization as a collaborator on an existing entity.\n - RIGHT_ORGANIZATION_ALL: The pseudo-right for all (current and future) organization rights.\n - RIGHT_SEND_INVITES: The right to send invites to new users.\nNote that this is not prefixed with \"USER_\"; it is not a right on the user entity.\n - RIGHT_ALL: The pseudo-right for all (current and future) possible rights.", + "description": " - RIGHT_USER_INFO: The right to view user information.\n - RIGHT_USER_SETTINGS_BASIC: The right to edit basic user settings.\n - RIGHT_USER_SETTINGS_API_KEYS: The right to view and edit user API keys.\n - RIGHT_USER_DELETE: The right to delete user account.\n - RIGHT_USER_PURGE: The right to delete user account.\n - RIGHT_USER_AUTHORIZED_CLIENTS: The right to view and edit authorized OAuth clients of the user.\n - RIGHT_USER_APPLICATIONS_LIST: The right to list applications the user is a collaborator of.\n - RIGHT_USER_APPLICATIONS_CREATE: The right to create an application under the user account.\n - RIGHT_USER_GATEWAYS_LIST: The right to list gateways the user is a collaborator of.\n - RIGHT_USER_GATEWAYS_CREATE: The right to create a gateway under the account of the user.\n - RIGHT_USER_CLIENTS_LIST: The right to list OAuth clients the user is a collaborator of.\n - RIGHT_USER_CLIENTS_CREATE: The right to create an OAuth client under the account of the user.\n - RIGHT_USER_ORGANIZATIONS_LIST: The right to list organizations the user is a member of.\n - RIGHT_USER_ORGANIZATIONS_CREATE: The right to create an organization under the user account.\n - RIGHT_USER_NOTIFICATIONS_READ: The right to read notifications sent to the user.\n - RIGHT_USER_ALL: The pseudo-right for all (current and future) user rights.\n - RIGHT_APPLICATION_INFO: The right to view application information.\n - RIGHT_APPLICATION_SETTINGS_BASIC: The right to edit basic application settings.\n - RIGHT_APPLICATION_SETTINGS_API_KEYS: The right to view and edit application API keys.\n - RIGHT_APPLICATION_SETTINGS_COLLABORATORS: The right to view and edit application collaborators.\n - RIGHT_APPLICATION_SETTINGS_PACKAGES: The right to view and edit application packages and associations.\n - RIGHT_APPLICATION_DELETE: The right to delete application.\n - RIGHT_APPLICATION_PURGE: The right to purge application.\n - RIGHT_APPLICATION_DEVICES_READ: The right to view devices in application.\n - RIGHT_APPLICATION_DEVICES_WRITE: The right to create devices in application.\n - RIGHT_APPLICATION_DEVICES_READ_KEYS: The right to view device keys in application.\nNote that keys may not be stored in a way that supports viewing them.\n - RIGHT_APPLICATION_DEVICES_WRITE_KEYS: The right to edit device keys in application.\n - RIGHT_APPLICATION_TRAFFIC_READ: The right to read application traffic (uplink and downlink).\n - RIGHT_APPLICATION_TRAFFIC_UP_WRITE: The right to write uplink application traffic.\n - RIGHT_APPLICATION_TRAFFIC_DOWN_WRITE: The right to write downlink application traffic.\n - RIGHT_APPLICATION_LINK: The right to link as Application to a Network Server for traffic exchange,\ni.e. read uplink and write downlink (API keys only).\nThis right is typically only given to an Application Server.\nThis right implies RIGHT_APPLICATION_INFO, RIGHT_APPLICATION_TRAFFIC_READ,\nand RIGHT_APPLICATION_TRAFFIC_DOWN_WRITE.\n - RIGHT_APPLICATION_ALL: The pseudo-right for all (current and future) application rights.\n - RIGHT_CLIENT_ALL: The pseudo-right for all (current and future) OAuth client rights.\n - RIGHT_CLIENT_INFO: The right to read client information.\n - RIGHT_CLIENT_SETTINGS_BASIC: The right to edit basic client settings.\n - RIGHT_CLIENT_SETTINGS_COLLABORATORS: The right to view and edit client collaborators.\n - RIGHT_CLIENT_DELETE: The right to delete a client.\n - RIGHT_GATEWAY_INFO: The right to view gateway information.\n - RIGHT_GATEWAY_SETTINGS_BASIC: The right to edit basic gateway settings.\n - RIGHT_GATEWAY_SETTINGS_API_KEYS: The right to view and edit gateway API keys.\n - RIGHT_GATEWAY_SETTINGS_COLLABORATORS: The right to view and edit gateway collaborators.\n - RIGHT_GATEWAY_DELETE: The right to delete gateway.\n - RIGHT_GATEWAY_PURGE: The right to purge gateway.\n - RIGHT_GATEWAY_TRAFFIC_READ: The right to read gateway traffic.\n - RIGHT_GATEWAY_TRAFFIC_DOWN_WRITE: The right to write downlink gateway traffic.\n - RIGHT_GATEWAY_LINK: The right to link as Gateway to a Gateway Server for traffic exchange,\ni.e. write uplink and read downlink (API keys only)\nThis right is typically only given to a gateway.\nThis right implies RIGHT_GATEWAY_INFO.\n - RIGHT_GATEWAY_STATUS_READ: The right to view gateway status.\n - RIGHT_GATEWAY_LOCATION_READ: The right to view view gateway location.\n - RIGHT_GATEWAY_WRITE_SECRETS: The right to store secrets associated with this gateway.\n - RIGHT_GATEWAY_READ_SECRETS: The right to retrieve secrets associated with this gateway.\n - RIGHT_GATEWAY_ALL: The pseudo-right for all (current and future) gateway rights.\n - RIGHT_ORGANIZATION_INFO: The right to view organization information.\n - RIGHT_ORGANIZATION_SETTINGS_BASIC: The right to edit basic organization settings.\n - RIGHT_ORGANIZATION_SETTINGS_API_KEYS: The right to view and edit organization API keys.\n - RIGHT_ORGANIZATION_SETTINGS_MEMBERS: The right to view and edit organization members.\n - RIGHT_ORGANIZATION_DELETE: The right to delete organization.\n - RIGHT_ORGANIZATION_PURGE: The right to purge organization.\n - RIGHT_ORGANIZATION_APPLICATIONS_LIST: The right to list the applications the organization is a collaborator of.\n - RIGHT_ORGANIZATION_APPLICATIONS_CREATE: The right to create an application under the organization.\n - RIGHT_ORGANIZATION_GATEWAYS_LIST: The right to list the gateways the organization is a collaborator of.\n - RIGHT_ORGANIZATION_GATEWAYS_CREATE: The right to create a gateway under the organization.\n - RIGHT_ORGANIZATION_CLIENTS_LIST: The right to list the OAuth clients the organization is a collaborator of.\n - RIGHT_ORGANIZATION_CLIENTS_CREATE: The right to create an OAuth client under the organization.\n - RIGHT_ORGANIZATION_ADD_AS_COLLABORATOR: The right to add the organization as a collaborator on an existing entity.\n - RIGHT_ORGANIZATION_ALL: The pseudo-right for all (current and future) organization rights.\n - RIGHT_SEND_INVITES: The right to send invites to new users.\nNote that this is not prefixed with \"USER_\"; it is not a right on the user entity.\n - RIGHT_ALL: The pseudo-right for all (current and future) possible rights.", "in": "query", "required": false, "type": "array", @@ -6961,6 +6961,7 @@ "RIGHT_GATEWAY_SETTINGS_API_KEYS", "RIGHT_GATEWAY_SETTINGS_COLLABORATORS", "RIGHT_GATEWAY_DELETE", + "RIGHT_GATEWAY_PURGE", "RIGHT_GATEWAY_TRAFFIC_READ", "RIGHT_GATEWAY_TRAFFIC_DOWN_WRITE", "RIGHT_GATEWAY_LINK", @@ -29005,6 +29006,7 @@ "RIGHT_GATEWAY_SETTINGS_API_KEYS", "RIGHT_GATEWAY_SETTINGS_COLLABORATORS", "RIGHT_GATEWAY_DELETE", + "RIGHT_GATEWAY_PURGE", "RIGHT_GATEWAY_TRAFFIC_READ", "RIGHT_GATEWAY_TRAFFIC_DOWN_WRITE", "RIGHT_GATEWAY_LINK", @@ -29031,7 +29033,7 @@ "RIGHT_ALL" ], "default": "right_invalid", - "description": "Right is the enum that defines all the different rights to do something in the network.\n\n - RIGHT_USER_INFO: The right to view user information.\n - RIGHT_USER_SETTINGS_BASIC: The right to edit basic user settings.\n - RIGHT_USER_SETTINGS_API_KEYS: The right to view and edit user API keys.\n - RIGHT_USER_DELETE: The right to delete user account.\n - RIGHT_USER_PURGE: The right to delete user account.\n - RIGHT_USER_AUTHORIZED_CLIENTS: The right to view and edit authorized OAuth clients of the user.\n - RIGHT_USER_APPLICATIONS_LIST: The right to list applications the user is a collaborator of.\n - RIGHT_USER_APPLICATIONS_CREATE: The right to create an application under the user account.\n - RIGHT_USER_GATEWAYS_LIST: The right to list gateways the user is a collaborator of.\n - RIGHT_USER_GATEWAYS_CREATE: The right to create a gateway under the account of the user.\n - RIGHT_USER_CLIENTS_LIST: The right to list OAuth clients the user is a collaborator of.\n - RIGHT_USER_CLIENTS_CREATE: The right to create an OAuth client under the account of the user.\n - RIGHT_USER_ORGANIZATIONS_LIST: The right to list organizations the user is a member of.\n - RIGHT_USER_ORGANIZATIONS_CREATE: The right to create an organization under the user account.\n - RIGHT_USER_NOTIFICATIONS_READ: The right to read notifications sent to the user.\n - RIGHT_USER_ALL: The pseudo-right for all (current and future) user rights.\n - RIGHT_APPLICATION_INFO: The right to view application information.\n - RIGHT_APPLICATION_SETTINGS_BASIC: The right to edit basic application settings.\n - RIGHT_APPLICATION_SETTINGS_API_KEYS: The right to view and edit application API keys.\n - RIGHT_APPLICATION_SETTINGS_COLLABORATORS: The right to view and edit application collaborators.\n - RIGHT_APPLICATION_SETTINGS_PACKAGES: The right to view and edit application packages and associations.\n - RIGHT_APPLICATION_DELETE: The right to delete application.\n - RIGHT_APPLICATION_PURGE: The right to purge application.\n - RIGHT_APPLICATION_DEVICES_READ: The right to view devices in application.\n - RIGHT_APPLICATION_DEVICES_WRITE: The right to create devices in application.\n - RIGHT_APPLICATION_DEVICES_READ_KEYS: The right to view device keys in application.\nNote that keys may not be stored in a way that supports viewing them.\n - RIGHT_APPLICATION_DEVICES_WRITE_KEYS: The right to edit device keys in application.\n - RIGHT_APPLICATION_TRAFFIC_READ: The right to read application traffic (uplink and downlink).\n - RIGHT_APPLICATION_TRAFFIC_UP_WRITE: The right to write uplink application traffic.\n - RIGHT_APPLICATION_TRAFFIC_DOWN_WRITE: The right to write downlink application traffic.\n - RIGHT_APPLICATION_LINK: The right to link as Application to a Network Server for traffic exchange,\ni.e. read uplink and write downlink (API keys only).\nThis right is typically only given to an Application Server.\nThis right implies RIGHT_APPLICATION_INFO, RIGHT_APPLICATION_TRAFFIC_READ,\nand RIGHT_APPLICATION_TRAFFIC_DOWN_WRITE.\n - RIGHT_APPLICATION_ALL: The pseudo-right for all (current and future) application rights.\n - RIGHT_CLIENT_ALL: The pseudo-right for all (current and future) OAuth client rights.\n - RIGHT_CLIENT_INFO: The right to read client information.\n - RIGHT_CLIENT_SETTINGS_BASIC: The right to edit basic client settings.\n - RIGHT_CLIENT_SETTINGS_COLLABORATORS: The right to view and edit client collaborators.\n - RIGHT_CLIENT_DELETE: The right to delete a client.\n - RIGHT_GATEWAY_INFO: The right to view gateway information.\n - RIGHT_GATEWAY_SETTINGS_BASIC: The right to edit basic gateway settings.\n - RIGHT_GATEWAY_SETTINGS_API_KEYS: The right to view and edit gateway API keys.\n - RIGHT_GATEWAY_SETTINGS_COLLABORATORS: The right to view and edit gateway collaborators.\n - RIGHT_GATEWAY_DELETE: The right to delete gateway.\n - RIGHT_GATEWAY_TRAFFIC_READ: The right to read gateway traffic.\n - RIGHT_GATEWAY_TRAFFIC_DOWN_WRITE: The right to write downlink gateway traffic.\n - RIGHT_GATEWAY_LINK: The right to link as Gateway to a Gateway Server for traffic exchange,\ni.e. write uplink and read downlink (API keys only)\nThis right is typically only given to a gateway.\nThis right implies RIGHT_GATEWAY_INFO.\n - RIGHT_GATEWAY_STATUS_READ: The right to view gateway status.\n - RIGHT_GATEWAY_LOCATION_READ: The right to view view gateway location.\n - RIGHT_GATEWAY_WRITE_SECRETS: The right to store secrets associated with this gateway.\n - RIGHT_GATEWAY_READ_SECRETS: The right to retrieve secrets associated with this gateway.\n - RIGHT_GATEWAY_ALL: The pseudo-right for all (current and future) gateway rights.\n - RIGHT_ORGANIZATION_INFO: The right to view organization information.\n - RIGHT_ORGANIZATION_SETTINGS_BASIC: The right to edit basic organization settings.\n - RIGHT_ORGANIZATION_SETTINGS_API_KEYS: The right to view and edit organization API keys.\n - RIGHT_ORGANIZATION_SETTINGS_MEMBERS: The right to view and edit organization members.\n - RIGHT_ORGANIZATION_DELETE: The right to delete organization.\n - RIGHT_ORGANIZATION_PURGE: The right to purge organization.\n - RIGHT_ORGANIZATION_APPLICATIONS_LIST: The right to list the applications the organization is a collaborator of.\n - RIGHT_ORGANIZATION_APPLICATIONS_CREATE: The right to create an application under the organization.\n - RIGHT_ORGANIZATION_GATEWAYS_LIST: The right to list the gateways the organization is a collaborator of.\n - RIGHT_ORGANIZATION_GATEWAYS_CREATE: The right to create a gateway under the organization.\n - RIGHT_ORGANIZATION_CLIENTS_LIST: The right to list the OAuth clients the organization is a collaborator of.\n - RIGHT_ORGANIZATION_CLIENTS_CREATE: The right to create an OAuth client under the organization.\n - RIGHT_ORGANIZATION_ADD_AS_COLLABORATOR: The right to add the organization as a collaborator on an existing entity.\n - RIGHT_ORGANIZATION_ALL: The pseudo-right for all (current and future) organization rights.\n - RIGHT_SEND_INVITES: The right to send invites to new users.\nNote that this is not prefixed with \"USER_\"; it is not a right on the user entity.\n - RIGHT_ALL: The pseudo-right for all (current and future) possible rights." + "description": "Right is the enum that defines all the different rights to do something in the network.\n\n - RIGHT_USER_INFO: The right to view user information.\n - RIGHT_USER_SETTINGS_BASIC: The right to edit basic user settings.\n - RIGHT_USER_SETTINGS_API_KEYS: The right to view and edit user API keys.\n - RIGHT_USER_DELETE: The right to delete user account.\n - RIGHT_USER_PURGE: The right to delete user account.\n - RIGHT_USER_AUTHORIZED_CLIENTS: The right to view and edit authorized OAuth clients of the user.\n - RIGHT_USER_APPLICATIONS_LIST: The right to list applications the user is a collaborator of.\n - RIGHT_USER_APPLICATIONS_CREATE: The right to create an application under the user account.\n - RIGHT_USER_GATEWAYS_LIST: The right to list gateways the user is a collaborator of.\n - RIGHT_USER_GATEWAYS_CREATE: The right to create a gateway under the account of the user.\n - RIGHT_USER_CLIENTS_LIST: The right to list OAuth clients the user is a collaborator of.\n - RIGHT_USER_CLIENTS_CREATE: The right to create an OAuth client under the account of the user.\n - RIGHT_USER_ORGANIZATIONS_LIST: The right to list organizations the user is a member of.\n - RIGHT_USER_ORGANIZATIONS_CREATE: The right to create an organization under the user account.\n - RIGHT_USER_NOTIFICATIONS_READ: The right to read notifications sent to the user.\n - RIGHT_USER_ALL: The pseudo-right for all (current and future) user rights.\n - RIGHT_APPLICATION_INFO: The right to view application information.\n - RIGHT_APPLICATION_SETTINGS_BASIC: The right to edit basic application settings.\n - RIGHT_APPLICATION_SETTINGS_API_KEYS: The right to view and edit application API keys.\n - RIGHT_APPLICATION_SETTINGS_COLLABORATORS: The right to view and edit application collaborators.\n - RIGHT_APPLICATION_SETTINGS_PACKAGES: The right to view and edit application packages and associations.\n - RIGHT_APPLICATION_DELETE: The right to delete application.\n - RIGHT_APPLICATION_PURGE: The right to purge application.\n - RIGHT_APPLICATION_DEVICES_READ: The right to view devices in application.\n - RIGHT_APPLICATION_DEVICES_WRITE: The right to create devices in application.\n - RIGHT_APPLICATION_DEVICES_READ_KEYS: The right to view device keys in application.\nNote that keys may not be stored in a way that supports viewing them.\n - RIGHT_APPLICATION_DEVICES_WRITE_KEYS: The right to edit device keys in application.\n - RIGHT_APPLICATION_TRAFFIC_READ: The right to read application traffic (uplink and downlink).\n - RIGHT_APPLICATION_TRAFFIC_UP_WRITE: The right to write uplink application traffic.\n - RIGHT_APPLICATION_TRAFFIC_DOWN_WRITE: The right to write downlink application traffic.\n - RIGHT_APPLICATION_LINK: The right to link as Application to a Network Server for traffic exchange,\ni.e. read uplink and write downlink (API keys only).\nThis right is typically only given to an Application Server.\nThis right implies RIGHT_APPLICATION_INFO, RIGHT_APPLICATION_TRAFFIC_READ,\nand RIGHT_APPLICATION_TRAFFIC_DOWN_WRITE.\n - RIGHT_APPLICATION_ALL: The pseudo-right for all (current and future) application rights.\n - RIGHT_CLIENT_ALL: The pseudo-right for all (current and future) OAuth client rights.\n - RIGHT_CLIENT_INFO: The right to read client information.\n - RIGHT_CLIENT_SETTINGS_BASIC: The right to edit basic client settings.\n - RIGHT_CLIENT_SETTINGS_COLLABORATORS: The right to view and edit client collaborators.\n - RIGHT_CLIENT_DELETE: The right to delete a client.\n - RIGHT_GATEWAY_INFO: The right to view gateway information.\n - RIGHT_GATEWAY_SETTINGS_BASIC: The right to edit basic gateway settings.\n - RIGHT_GATEWAY_SETTINGS_API_KEYS: The right to view and edit gateway API keys.\n - RIGHT_GATEWAY_SETTINGS_COLLABORATORS: The right to view and edit gateway collaborators.\n - RIGHT_GATEWAY_DELETE: The right to delete gateway.\n - RIGHT_GATEWAY_PURGE: The right to purge gateway.\n - RIGHT_GATEWAY_TRAFFIC_READ: The right to read gateway traffic.\n - RIGHT_GATEWAY_TRAFFIC_DOWN_WRITE: The right to write downlink gateway traffic.\n - RIGHT_GATEWAY_LINK: The right to link as Gateway to a Gateway Server for traffic exchange,\ni.e. write uplink and read downlink (API keys only)\nThis right is typically only given to a gateway.\nThis right implies RIGHT_GATEWAY_INFO.\n - RIGHT_GATEWAY_STATUS_READ: The right to view gateway status.\n - RIGHT_GATEWAY_LOCATION_READ: The right to view view gateway location.\n - RIGHT_GATEWAY_WRITE_SECRETS: The right to store secrets associated with this gateway.\n - RIGHT_GATEWAY_READ_SECRETS: The right to retrieve secrets associated with this gateway.\n - RIGHT_GATEWAY_ALL: The pseudo-right for all (current and future) gateway rights.\n - RIGHT_ORGANIZATION_INFO: The right to view organization information.\n - RIGHT_ORGANIZATION_SETTINGS_BASIC: The right to edit basic organization settings.\n - RIGHT_ORGANIZATION_SETTINGS_API_KEYS: The right to view and edit organization API keys.\n - RIGHT_ORGANIZATION_SETTINGS_MEMBERS: The right to view and edit organization members.\n - RIGHT_ORGANIZATION_DELETE: The right to delete organization.\n - RIGHT_ORGANIZATION_PURGE: The right to purge organization.\n - RIGHT_ORGANIZATION_APPLICATIONS_LIST: The right to list the applications the organization is a collaborator of.\n - RIGHT_ORGANIZATION_APPLICATIONS_CREATE: The right to create an application under the organization.\n - RIGHT_ORGANIZATION_GATEWAYS_LIST: The right to list the gateways the organization is a collaborator of.\n - RIGHT_ORGANIZATION_GATEWAYS_CREATE: The right to create a gateway under the organization.\n - RIGHT_ORGANIZATION_CLIENTS_LIST: The right to list the OAuth clients the organization is a collaborator of.\n - RIGHT_ORGANIZATION_CLIENTS_CREATE: The right to create an OAuth client under the organization.\n - RIGHT_ORGANIZATION_ADD_AS_COLLABORATOR: The right to add the organization as a collaborator on an existing entity.\n - RIGHT_ORGANIZATION_ALL: The pseudo-right for all (current and future) organization rights.\n - RIGHT_SEND_INVITES: The right to send invites to new users.\nNote that this is not prefixed with \"USER_\"; it is not a right on the user entity.\n - RIGHT_ALL: The pseudo-right for all (current and future) possible rights." }, "v3Rights": { "type": "object", diff --git a/api/ttn/lorawan/v3/rights.proto b/api/ttn/lorawan/v3/rights.proto index 5eb1825d8c..a6a30bab1d 100644 --- a/api/ttn/lorawan/v3/rights.proto +++ b/api/ttn/lorawan/v3/rights.proto @@ -125,6 +125,8 @@ enum Right { RIGHT_GATEWAY_SETTINGS_COLLABORATORS = 33; // The right to delete gateway. RIGHT_GATEWAY_DELETE = 34; + // The right to purge gateway. + RIGHT_GATEWAY_PURGE = 67; // The right to read gateway traffic. RIGHT_GATEWAY_TRAFFIC_READ = 35; // The right to write downlink gateway traffic. @@ -181,7 +183,7 @@ enum Right { // The pseudo-right for all (current and future) possible rights. RIGHT_ALL = 55; - // Next value: 67 + // Next value: 68 } message Rights { diff --git a/pkg/ttnpb/rights.pb.go b/pkg/ttnpb/rights.pb.go index a2d777af5b..fa17afe8f9 100644 --- a/pkg/ttnpb/rights.pb.go +++ b/pkg/ttnpb/rights.pb.go @@ -132,6 +132,8 @@ const ( Right_RIGHT_GATEWAY_SETTINGS_COLLABORATORS Right = 33 // The right to delete gateway. Right_RIGHT_GATEWAY_DELETE Right = 34 + // The right to purge gateway. + Right_RIGHT_GATEWAY_PURGE Right = 67 // The right to read gateway traffic. Right_RIGHT_GATEWAY_TRAFFIC_READ Right = 35 // The right to write downlink gateway traffic. @@ -232,6 +234,7 @@ var ( 32: "RIGHT_GATEWAY_SETTINGS_API_KEYS", 33: "RIGHT_GATEWAY_SETTINGS_COLLABORATORS", 34: "RIGHT_GATEWAY_DELETE", + 67: "RIGHT_GATEWAY_PURGE", 35: "RIGHT_GATEWAY_TRAFFIC_READ", 36: "RIGHT_GATEWAY_TRAFFIC_DOWN_WRITE", 37: "RIGHT_GATEWAY_LINK", @@ -301,6 +304,7 @@ var ( "RIGHT_GATEWAY_SETTINGS_API_KEYS": 32, "RIGHT_GATEWAY_SETTINGS_COLLABORATORS": 33, "RIGHT_GATEWAY_DELETE": 34, + "RIGHT_GATEWAY_PURGE": 67, "RIGHT_GATEWAY_TRAFFIC_READ": 35, "RIGHT_GATEWAY_TRAFFIC_DOWN_WRITE": 36, "RIGHT_GATEWAY_LINK": 37, @@ -778,7 +782,7 @@ var file_ttn_lorawan_v3_rights_proto_rawDesc = []byte{ 0x61, 0x62, 0x6f, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x43, 0x6f, 0x6c, 0x6c, 0x61, 0x62, 0x6f, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x0d, 0x63, - 0x6f, 0x6c, 0x6c, 0x61, 0x62, 0x6f, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x2a, 0xb0, 0x11, 0x0a, + 0x6f, 0x6c, 0x6c, 0x61, 0x62, 0x6f, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x2a, 0xc9, 0x11, 0x0a, 0x05, 0x52, 0x69, 0x67, 0x68, 0x74, 0x12, 0x11, 0x0a, 0x0d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x5f, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x01, 0x12, 0x1d, @@ -866,62 +870,64 @@ var file_ttn_lorawan_v3_rights_proto_rawDesc = []byte{ 0x45, 0x57, 0x41, 0x59, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x43, 0x4f, 0x4c, 0x4c, 0x41, 0x42, 0x4f, 0x52, 0x41, 0x54, 0x4f, 0x52, 0x53, 0x10, 0x21, 0x12, 0x18, 0x0a, 0x14, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x44, - 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x22, 0x12, 0x1e, 0x0a, 0x1a, 0x52, 0x49, 0x47, 0x48, 0x54, - 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x54, 0x52, 0x41, 0x46, 0x46, 0x49, 0x43, - 0x5f, 0x52, 0x45, 0x41, 0x44, 0x10, 0x23, 0x12, 0x24, 0x0a, 0x20, 0x52, 0x49, 0x47, 0x48, 0x54, - 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x54, 0x52, 0x41, 0x46, 0x46, 0x49, 0x43, - 0x5f, 0x44, 0x4f, 0x57, 0x4e, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x10, 0x24, 0x12, 0x16, 0x0a, - 0x12, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x4c, - 0x49, 0x4e, 0x4b, 0x10, 0x25, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, - 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x45, - 0x41, 0x44, 0x10, 0x26, 0x12, 0x1f, 0x0a, 0x1b, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, - 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x4c, 0x4f, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x52, - 0x45, 0x41, 0x44, 0x10, 0x27, 0x12, 0x1f, 0x0a, 0x1b, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, - 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x5f, 0x53, 0x45, 0x43, - 0x52, 0x45, 0x54, 0x53, 0x10, 0x39, 0x12, 0x1e, 0x0a, 0x1a, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, - 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x53, 0x45, 0x43, - 0x52, 0x45, 0x54, 0x53, 0x10, 0x3a, 0x12, 0x15, 0x0a, 0x11, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, - 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x41, 0x4c, 0x4c, 0x10, 0x28, 0x12, 0x1b, 0x0a, - 0x17, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, - 0x49, 0x4f, 0x4e, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x29, 0x12, 0x25, 0x0a, 0x21, 0x52, 0x49, + 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x22, 0x12, 0x17, 0x0a, 0x13, 0x52, 0x49, 0x47, 0x48, 0x54, + 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x50, 0x55, 0x52, 0x47, 0x45, 0x10, 0x43, + 0x12, 0x1e, 0x0a, 0x1a, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, + 0x59, 0x5f, 0x54, 0x52, 0x41, 0x46, 0x46, 0x49, 0x43, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x10, 0x23, + 0x12, 0x24, 0x0a, 0x20, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, + 0x59, 0x5f, 0x54, 0x52, 0x41, 0x46, 0x46, 0x49, 0x43, 0x5f, 0x44, 0x4f, 0x57, 0x4e, 0x5f, 0x57, + 0x52, 0x49, 0x54, 0x45, 0x10, 0x24, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, + 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x4c, 0x49, 0x4e, 0x4b, 0x10, 0x25, 0x12, 0x1d, + 0x0a, 0x19, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, + 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x10, 0x26, 0x12, 0x1f, 0x0a, + 0x1b, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x4c, + 0x4f, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x10, 0x27, 0x12, 0x1f, + 0x0a, 0x1b, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, + 0x57, 0x52, 0x49, 0x54, 0x45, 0x5f, 0x53, 0x45, 0x43, 0x52, 0x45, 0x54, 0x53, 0x10, 0x39, 0x12, + 0x1e, 0x0a, 0x1a, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, + 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x53, 0x45, 0x43, 0x52, 0x45, 0x54, 0x53, 0x10, 0x3a, 0x12, + 0x15, 0x0a, 0x11, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, + 0x5f, 0x41, 0x4c, 0x4c, 0x10, 0x28, 0x12, 0x1b, 0x0a, 0x17, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, + 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x49, 0x4e, 0x46, + 0x4f, 0x10, 0x29, 0x12, 0x25, 0x0a, 0x21, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, + 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, + 0x47, 0x53, 0x5f, 0x42, 0x41, 0x53, 0x49, 0x43, 0x10, 0x2a, 0x12, 0x28, 0x0a, 0x24, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, - 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x42, 0x41, 0x53, 0x49, 0x43, 0x10, - 0x2a, 0x12, 0x28, 0x0a, 0x24, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, - 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, - 0x5f, 0x41, 0x50, 0x49, 0x5f, 0x4b, 0x45, 0x59, 0x53, 0x10, 0x2b, 0x12, 0x27, 0x0a, 0x23, 0x52, - 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, - 0x4e, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x4d, 0x45, 0x4d, 0x42, 0x45, - 0x52, 0x53, 0x10, 0x2c, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, - 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, - 0x45, 0x10, 0x2d, 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, - 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x50, 0x55, 0x52, 0x47, 0x45, 0x10, - 0x41, 0x12, 0x28, 0x0a, 0x24, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, - 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, - 0x49, 0x4f, 0x4e, 0x53, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x2e, 0x12, 0x2a, 0x0a, 0x26, 0x52, - 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, - 0x4e, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x5f, 0x43, - 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, 0x2f, 0x12, 0x24, 0x0a, 0x20, 0x52, 0x49, 0x47, 0x48, 0x54, - 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x47, 0x41, - 0x54, 0x45, 0x57, 0x41, 0x59, 0x53, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x30, 0x12, 0x26, 0x0a, - 0x22, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, - 0x49, 0x4f, 0x4e, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x53, 0x5f, 0x43, 0x52, 0x45, - 0x41, 0x54, 0x45, 0x10, 0x31, 0x12, 0x23, 0x0a, 0x1f, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, - 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x43, 0x4c, 0x49, 0x45, - 0x4e, 0x54, 0x53, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x32, 0x12, 0x25, 0x0a, 0x21, 0x52, 0x49, + 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x41, 0x50, 0x49, 0x5f, 0x4b, 0x45, + 0x59, 0x53, 0x10, 0x2b, 0x12, 0x27, 0x0a, 0x23, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, + 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, + 0x4e, 0x47, 0x53, 0x5f, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, 0x53, 0x10, 0x2c, 0x12, 0x1d, 0x0a, + 0x19, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, + 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x2d, 0x12, 0x1c, 0x0a, 0x18, + 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, + 0x4f, 0x4e, 0x5f, 0x50, 0x55, 0x52, 0x47, 0x45, 0x10, 0x41, 0x12, 0x28, 0x0a, 0x24, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, - 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x53, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, - 0x33, 0x12, 0x2a, 0x0a, 0x26, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, - 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x44, 0x44, 0x5f, 0x41, 0x53, 0x5f, 0x43, - 0x4f, 0x4c, 0x4c, 0x41, 0x42, 0x4f, 0x52, 0x41, 0x54, 0x4f, 0x52, 0x10, 0x34, 0x12, 0x1a, 0x0a, - 0x16, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, - 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x4c, 0x4c, 0x10, 0x35, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x49, 0x47, - 0x48, 0x54, 0x5f, 0x53, 0x45, 0x4e, 0x44, 0x5f, 0x49, 0x4e, 0x56, 0x49, 0x54, 0x45, 0x53, 0x10, - 0x36, 0x12, 0x0d, 0x0a, 0x09, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x4c, 0x4c, 0x10, 0x37, - 0x1a, 0x0d, 0xea, 0xaa, 0x19, 0x09, 0x18, 0x01, 0x2a, 0x05, 0x52, 0x49, 0x47, 0x48, 0x54, 0x42, - 0x31, 0x5a, 0x2f, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, - 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, - 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x74, 0x6e, - 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x5f, 0x4c, 0x49, + 0x53, 0x54, 0x10, 0x2e, 0x12, 0x2a, 0x0a, 0x26, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, + 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, + 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, 0x2f, + 0x12, 0x24, 0x0a, 0x20, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, + 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x53, 0x5f, + 0x4c, 0x49, 0x53, 0x54, 0x10, 0x30, 0x12, 0x26, 0x0a, 0x22, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, + 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x47, 0x41, 0x54, + 0x45, 0x57, 0x41, 0x59, 0x53, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, 0x31, 0x12, 0x23, + 0x0a, 0x1f, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, + 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x53, 0x5f, 0x4c, 0x49, 0x53, + 0x54, 0x10, 0x32, 0x12, 0x25, 0x0a, 0x21, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, + 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, + 0x53, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, 0x33, 0x12, 0x2a, 0x0a, 0x26, 0x52, 0x49, + 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, + 0x5f, 0x41, 0x44, 0x44, 0x5f, 0x41, 0x53, 0x5f, 0x43, 0x4f, 0x4c, 0x4c, 0x41, 0x42, 0x4f, 0x52, + 0x41, 0x54, 0x4f, 0x52, 0x10, 0x34, 0x12, 0x1a, 0x0a, 0x16, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, + 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x4c, 0x4c, + 0x10, 0x35, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x53, 0x45, 0x4e, 0x44, + 0x5f, 0x49, 0x4e, 0x56, 0x49, 0x54, 0x45, 0x53, 0x10, 0x36, 0x12, 0x0d, 0x0a, 0x09, 0x52, 0x49, + 0x47, 0x48, 0x54, 0x5f, 0x41, 0x4c, 0x4c, 0x10, 0x37, 0x1a, 0x0d, 0xea, 0xaa, 0x19, 0x09, 0x18, + 0x01, 0x2a, 0x05, 0x52, 0x49, 0x47, 0x48, 0x54, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x6f, 0x2e, 0x74, + 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, + 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, + 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x74, 0x6e, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, } var ( diff --git a/pkg/ttnpb/rights_json.pb.go b/pkg/ttnpb/rights_json.pb.go index b59648e27d..ed9005800c 100644 --- a/pkg/ttnpb/rights_json.pb.go +++ b/pkg/ttnpb/rights_json.pb.go @@ -70,6 +70,7 @@ var Right_customvalue = map[string]int32{ "GATEWAY_SETTINGS_API_KEYS": 32, "GATEWAY_SETTINGS_COLLABORATORS": 33, "GATEWAY_DELETE": 34, + "GATEWAY_PURGE": 67, "GATEWAY_TRAFFIC_READ": 35, "GATEWAY_TRAFFIC_DOWN_WRITE": 36, "GATEWAY_LINK": 37, diff --git a/sdk/js/generated/api.json b/sdk/js/generated/api.json index a46eeaa38d..71ff36d188 100644 --- a/sdk/js/generated/api.json +++ b/sdk/js/generated/api.json @@ -49929,6 +49929,11 @@ "number": "34", "description": "The right to delete gateway." }, + { + "name": "RIGHT_GATEWAY_PURGE", + "number": "67", + "description": "The right to purge gateway." + }, { "name": "RIGHT_GATEWAY_TRAFFIC_READ", "number": "35", From b86356fb26815a29ad680bd6ecbbc7b1cc325054 Mon Sep 17 00:00:00 2001 From: Nicholas Cristofaro Date: Mon, 25 Nov 2024 11:15:17 -0300 Subject: [PATCH 14/40] is: Update purgeGateway to check rights --- pkg/identityserver/gateway_registry.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pkg/identityserver/gateway_registry.go b/pkg/identityserver/gateway_registry.go index 4d624cf3b3..acb6ce3fef 100644 --- a/pkg/identityserver/gateway_registry.go +++ b/pkg/identityserver/gateway_registry.go @@ -727,6 +727,11 @@ func (is *IdentityServer) purgeGateway(ctx context.Context, ids *ttnpb.GatewayId if !is.IsAdmin(ctx) { return nil, errAdminsPurgeGateways.New() } + if err := rights.RequireGateway( + store.WithSoftDeleted(ctx, false), ids, ttnpb.Right_RIGHT_GATEWAY_PURGE, + ); err != nil { + return nil, err + } err := is.store.Transact(ctx, func(ctx context.Context, st store.Store) error { // delete related API keys before purging the gateway err := st.DeleteEntityAPIKeys(ctx, ids.GetEntityIdentifiers()) From c265c63e1e4a36e4e5ff523c4cc5e126b0baa28d Mon Sep 17 00:00:00 2001 From: Nicholas Cristofaro Date: Mon, 25 Nov 2024 11:21:55 -0300 Subject: [PATCH 15/40] api: Add RIGHT_CLIENT_PURGE --- api/ttn/lorawan/v3/api.md | 1 + api/ttn/lorawan/v3/api.swagger.json | 6 +- api/ttn/lorawan/v3/rights.proto | 4 +- pkg/ttnpb/rights.pb.go | 141 ++++++++++++++-------------- pkg/ttnpb/rights_json.pb.go | 1 + sdk/js/generated/api.json | 5 + 6 files changed, 87 insertions(+), 71 deletions(-) diff --git a/api/ttn/lorawan/v3/api.md b/api/ttn/lorawan/v3/api.md index 4741b9aab0..56b3e62b74 100644 --- a/api/ttn/lorawan/v3/api.md +++ b/api/ttn/lorawan/v3/api.md @@ -11009,6 +11009,7 @@ Right is the enum that defines all the different rights to do something in the n | `RIGHT_CLIENT_SETTINGS_BASIC` | 61 | The right to edit basic client settings. | | `RIGHT_CLIENT_SETTINGS_COLLABORATORS` | 62 | The right to view and edit client collaborators. | | `RIGHT_CLIENT_DELETE` | 63 | The right to delete a client. | +| `RIGHT_CLIENT_PURGE` | 68 | The right to purge a client. | | `RIGHT_GATEWAY_INFO` | 30 | The right to view gateway information. | | `RIGHT_GATEWAY_SETTINGS_BASIC` | 31 | The right to edit basic gateway settings. | | `RIGHT_GATEWAY_SETTINGS_API_KEYS` | 32 | The right to view and edit gateway API keys. | diff --git a/api/ttn/lorawan/v3/api.swagger.json b/api/ttn/lorawan/v3/api.swagger.json index 5dcf65c925..4b1565a5ef 100644 --- a/api/ttn/lorawan/v3/api.swagger.json +++ b/api/ttn/lorawan/v3/api.swagger.json @@ -6911,7 +6911,7 @@ "parameters": [ { "name": "required.rights", - "description": " - RIGHT_USER_INFO: The right to view user information.\n - RIGHT_USER_SETTINGS_BASIC: The right to edit basic user settings.\n - RIGHT_USER_SETTINGS_API_KEYS: The right to view and edit user API keys.\n - RIGHT_USER_DELETE: The right to delete user account.\n - RIGHT_USER_PURGE: The right to delete user account.\n - RIGHT_USER_AUTHORIZED_CLIENTS: The right to view and edit authorized OAuth clients of the user.\n - RIGHT_USER_APPLICATIONS_LIST: The right to list applications the user is a collaborator of.\n - RIGHT_USER_APPLICATIONS_CREATE: The right to create an application under the user account.\n - RIGHT_USER_GATEWAYS_LIST: The right to list gateways the user is a collaborator of.\n - RIGHT_USER_GATEWAYS_CREATE: The right to create a gateway under the account of the user.\n - RIGHT_USER_CLIENTS_LIST: The right to list OAuth clients the user is a collaborator of.\n - RIGHT_USER_CLIENTS_CREATE: The right to create an OAuth client under the account of the user.\n - RIGHT_USER_ORGANIZATIONS_LIST: The right to list organizations the user is a member of.\n - RIGHT_USER_ORGANIZATIONS_CREATE: The right to create an organization under the user account.\n - RIGHT_USER_NOTIFICATIONS_READ: The right to read notifications sent to the user.\n - RIGHT_USER_ALL: The pseudo-right for all (current and future) user rights.\n - RIGHT_APPLICATION_INFO: The right to view application information.\n - RIGHT_APPLICATION_SETTINGS_BASIC: The right to edit basic application settings.\n - RIGHT_APPLICATION_SETTINGS_API_KEYS: The right to view and edit application API keys.\n - RIGHT_APPLICATION_SETTINGS_COLLABORATORS: The right to view and edit application collaborators.\n - RIGHT_APPLICATION_SETTINGS_PACKAGES: The right to view and edit application packages and associations.\n - RIGHT_APPLICATION_DELETE: The right to delete application.\n - RIGHT_APPLICATION_PURGE: The right to purge application.\n - RIGHT_APPLICATION_DEVICES_READ: The right to view devices in application.\n - RIGHT_APPLICATION_DEVICES_WRITE: The right to create devices in application.\n - RIGHT_APPLICATION_DEVICES_READ_KEYS: The right to view device keys in application.\nNote that keys may not be stored in a way that supports viewing them.\n - RIGHT_APPLICATION_DEVICES_WRITE_KEYS: The right to edit device keys in application.\n - RIGHT_APPLICATION_TRAFFIC_READ: The right to read application traffic (uplink and downlink).\n - RIGHT_APPLICATION_TRAFFIC_UP_WRITE: The right to write uplink application traffic.\n - RIGHT_APPLICATION_TRAFFIC_DOWN_WRITE: The right to write downlink application traffic.\n - RIGHT_APPLICATION_LINK: The right to link as Application to a Network Server for traffic exchange,\ni.e. read uplink and write downlink (API keys only).\nThis right is typically only given to an Application Server.\nThis right implies RIGHT_APPLICATION_INFO, RIGHT_APPLICATION_TRAFFIC_READ,\nand RIGHT_APPLICATION_TRAFFIC_DOWN_WRITE.\n - RIGHT_APPLICATION_ALL: The pseudo-right for all (current and future) application rights.\n - RIGHT_CLIENT_ALL: The pseudo-right for all (current and future) OAuth client rights.\n - RIGHT_CLIENT_INFO: The right to read client information.\n - RIGHT_CLIENT_SETTINGS_BASIC: The right to edit basic client settings.\n - RIGHT_CLIENT_SETTINGS_COLLABORATORS: The right to view and edit client collaborators.\n - RIGHT_CLIENT_DELETE: The right to delete a client.\n - RIGHT_GATEWAY_INFO: The right to view gateway information.\n - RIGHT_GATEWAY_SETTINGS_BASIC: The right to edit basic gateway settings.\n - RIGHT_GATEWAY_SETTINGS_API_KEYS: The right to view and edit gateway API keys.\n - RIGHT_GATEWAY_SETTINGS_COLLABORATORS: The right to view and edit gateway collaborators.\n - RIGHT_GATEWAY_DELETE: The right to delete gateway.\n - RIGHT_GATEWAY_PURGE: The right to purge gateway.\n - RIGHT_GATEWAY_TRAFFIC_READ: The right to read gateway traffic.\n - RIGHT_GATEWAY_TRAFFIC_DOWN_WRITE: The right to write downlink gateway traffic.\n - RIGHT_GATEWAY_LINK: The right to link as Gateway to a Gateway Server for traffic exchange,\ni.e. write uplink and read downlink (API keys only)\nThis right is typically only given to a gateway.\nThis right implies RIGHT_GATEWAY_INFO.\n - RIGHT_GATEWAY_STATUS_READ: The right to view gateway status.\n - RIGHT_GATEWAY_LOCATION_READ: The right to view view gateway location.\n - RIGHT_GATEWAY_WRITE_SECRETS: The right to store secrets associated with this gateway.\n - RIGHT_GATEWAY_READ_SECRETS: The right to retrieve secrets associated with this gateway.\n - RIGHT_GATEWAY_ALL: The pseudo-right for all (current and future) gateway rights.\n - RIGHT_ORGANIZATION_INFO: The right to view organization information.\n - RIGHT_ORGANIZATION_SETTINGS_BASIC: The right to edit basic organization settings.\n - RIGHT_ORGANIZATION_SETTINGS_API_KEYS: The right to view and edit organization API keys.\n - RIGHT_ORGANIZATION_SETTINGS_MEMBERS: The right to view and edit organization members.\n - RIGHT_ORGANIZATION_DELETE: The right to delete organization.\n - RIGHT_ORGANIZATION_PURGE: The right to purge organization.\n - RIGHT_ORGANIZATION_APPLICATIONS_LIST: The right to list the applications the organization is a collaborator of.\n - RIGHT_ORGANIZATION_APPLICATIONS_CREATE: The right to create an application under the organization.\n - RIGHT_ORGANIZATION_GATEWAYS_LIST: The right to list the gateways the organization is a collaborator of.\n - RIGHT_ORGANIZATION_GATEWAYS_CREATE: The right to create a gateway under the organization.\n - RIGHT_ORGANIZATION_CLIENTS_LIST: The right to list the OAuth clients the organization is a collaborator of.\n - RIGHT_ORGANIZATION_CLIENTS_CREATE: The right to create an OAuth client under the organization.\n - RIGHT_ORGANIZATION_ADD_AS_COLLABORATOR: The right to add the organization as a collaborator on an existing entity.\n - RIGHT_ORGANIZATION_ALL: The pseudo-right for all (current and future) organization rights.\n - RIGHT_SEND_INVITES: The right to send invites to new users.\nNote that this is not prefixed with \"USER_\"; it is not a right on the user entity.\n - RIGHT_ALL: The pseudo-right for all (current and future) possible rights.", + "description": " - RIGHT_USER_INFO: The right to view user information.\n - RIGHT_USER_SETTINGS_BASIC: The right to edit basic user settings.\n - RIGHT_USER_SETTINGS_API_KEYS: The right to view and edit user API keys.\n - RIGHT_USER_DELETE: The right to delete user account.\n - RIGHT_USER_PURGE: The right to delete user account.\n - RIGHT_USER_AUTHORIZED_CLIENTS: The right to view and edit authorized OAuth clients of the user.\n - RIGHT_USER_APPLICATIONS_LIST: The right to list applications the user is a collaborator of.\n - RIGHT_USER_APPLICATIONS_CREATE: The right to create an application under the user account.\n - RIGHT_USER_GATEWAYS_LIST: The right to list gateways the user is a collaborator of.\n - RIGHT_USER_GATEWAYS_CREATE: The right to create a gateway under the account of the user.\n - RIGHT_USER_CLIENTS_LIST: The right to list OAuth clients the user is a collaborator of.\n - RIGHT_USER_CLIENTS_CREATE: The right to create an OAuth client under the account of the user.\n - RIGHT_USER_ORGANIZATIONS_LIST: The right to list organizations the user is a member of.\n - RIGHT_USER_ORGANIZATIONS_CREATE: The right to create an organization under the user account.\n - RIGHT_USER_NOTIFICATIONS_READ: The right to read notifications sent to the user.\n - RIGHT_USER_ALL: The pseudo-right for all (current and future) user rights.\n - RIGHT_APPLICATION_INFO: The right to view application information.\n - RIGHT_APPLICATION_SETTINGS_BASIC: The right to edit basic application settings.\n - RIGHT_APPLICATION_SETTINGS_API_KEYS: The right to view and edit application API keys.\n - RIGHT_APPLICATION_SETTINGS_COLLABORATORS: The right to view and edit application collaborators.\n - RIGHT_APPLICATION_SETTINGS_PACKAGES: The right to view and edit application packages and associations.\n - RIGHT_APPLICATION_DELETE: The right to delete application.\n - RIGHT_APPLICATION_PURGE: The right to purge application.\n - RIGHT_APPLICATION_DEVICES_READ: The right to view devices in application.\n - RIGHT_APPLICATION_DEVICES_WRITE: The right to create devices in application.\n - RIGHT_APPLICATION_DEVICES_READ_KEYS: The right to view device keys in application.\nNote that keys may not be stored in a way that supports viewing them.\n - RIGHT_APPLICATION_DEVICES_WRITE_KEYS: The right to edit device keys in application.\n - RIGHT_APPLICATION_TRAFFIC_READ: The right to read application traffic (uplink and downlink).\n - RIGHT_APPLICATION_TRAFFIC_UP_WRITE: The right to write uplink application traffic.\n - RIGHT_APPLICATION_TRAFFIC_DOWN_WRITE: The right to write downlink application traffic.\n - RIGHT_APPLICATION_LINK: The right to link as Application to a Network Server for traffic exchange,\ni.e. read uplink and write downlink (API keys only).\nThis right is typically only given to an Application Server.\nThis right implies RIGHT_APPLICATION_INFO, RIGHT_APPLICATION_TRAFFIC_READ,\nand RIGHT_APPLICATION_TRAFFIC_DOWN_WRITE.\n - RIGHT_APPLICATION_ALL: The pseudo-right for all (current and future) application rights.\n - RIGHT_CLIENT_ALL: The pseudo-right for all (current and future) OAuth client rights.\n - RIGHT_CLIENT_INFO: The right to read client information.\n - RIGHT_CLIENT_SETTINGS_BASIC: The right to edit basic client settings.\n - RIGHT_CLIENT_SETTINGS_COLLABORATORS: The right to view and edit client collaborators.\n - RIGHT_CLIENT_DELETE: The right to delete a client.\n - RIGHT_CLIENT_PURGE: The right to purge a client.\n - RIGHT_GATEWAY_INFO: The right to view gateway information.\n - RIGHT_GATEWAY_SETTINGS_BASIC: The right to edit basic gateway settings.\n - RIGHT_GATEWAY_SETTINGS_API_KEYS: The right to view and edit gateway API keys.\n - RIGHT_GATEWAY_SETTINGS_COLLABORATORS: The right to view and edit gateway collaborators.\n - RIGHT_GATEWAY_DELETE: The right to delete gateway.\n - RIGHT_GATEWAY_PURGE: The right to purge gateway.\n - RIGHT_GATEWAY_TRAFFIC_READ: The right to read gateway traffic.\n - RIGHT_GATEWAY_TRAFFIC_DOWN_WRITE: The right to write downlink gateway traffic.\n - RIGHT_GATEWAY_LINK: The right to link as Gateway to a Gateway Server for traffic exchange,\ni.e. write uplink and read downlink (API keys only)\nThis right is typically only given to a gateway.\nThis right implies RIGHT_GATEWAY_INFO.\n - RIGHT_GATEWAY_STATUS_READ: The right to view gateway status.\n - RIGHT_GATEWAY_LOCATION_READ: The right to view view gateway location.\n - RIGHT_GATEWAY_WRITE_SECRETS: The right to store secrets associated with this gateway.\n - RIGHT_GATEWAY_READ_SECRETS: The right to retrieve secrets associated with this gateway.\n - RIGHT_GATEWAY_ALL: The pseudo-right for all (current and future) gateway rights.\n - RIGHT_ORGANIZATION_INFO: The right to view organization information.\n - RIGHT_ORGANIZATION_SETTINGS_BASIC: The right to edit basic organization settings.\n - RIGHT_ORGANIZATION_SETTINGS_API_KEYS: The right to view and edit organization API keys.\n - RIGHT_ORGANIZATION_SETTINGS_MEMBERS: The right to view and edit organization members.\n - RIGHT_ORGANIZATION_DELETE: The right to delete organization.\n - RIGHT_ORGANIZATION_PURGE: The right to purge organization.\n - RIGHT_ORGANIZATION_APPLICATIONS_LIST: The right to list the applications the organization is a collaborator of.\n - RIGHT_ORGANIZATION_APPLICATIONS_CREATE: The right to create an application under the organization.\n - RIGHT_ORGANIZATION_GATEWAYS_LIST: The right to list the gateways the organization is a collaborator of.\n - RIGHT_ORGANIZATION_GATEWAYS_CREATE: The right to create a gateway under the organization.\n - RIGHT_ORGANIZATION_CLIENTS_LIST: The right to list the OAuth clients the organization is a collaborator of.\n - RIGHT_ORGANIZATION_CLIENTS_CREATE: The right to create an OAuth client under the organization.\n - RIGHT_ORGANIZATION_ADD_AS_COLLABORATOR: The right to add the organization as a collaborator on an existing entity.\n - RIGHT_ORGANIZATION_ALL: The pseudo-right for all (current and future) organization rights.\n - RIGHT_SEND_INVITES: The right to send invites to new users.\nNote that this is not prefixed with \"USER_\"; it is not a right on the user entity.\n - RIGHT_ALL: The pseudo-right for all (current and future) possible rights.", "in": "query", "required": false, "type": "array", @@ -6956,6 +6956,7 @@ "RIGHT_CLIENT_SETTINGS_BASIC", "RIGHT_CLIENT_SETTINGS_COLLABORATORS", "RIGHT_CLIENT_DELETE", + "RIGHT_CLIENT_PURGE", "RIGHT_GATEWAY_INFO", "RIGHT_GATEWAY_SETTINGS_BASIC", "RIGHT_GATEWAY_SETTINGS_API_KEYS", @@ -29001,6 +29002,7 @@ "RIGHT_CLIENT_SETTINGS_BASIC", "RIGHT_CLIENT_SETTINGS_COLLABORATORS", "RIGHT_CLIENT_DELETE", + "RIGHT_CLIENT_PURGE", "RIGHT_GATEWAY_INFO", "RIGHT_GATEWAY_SETTINGS_BASIC", "RIGHT_GATEWAY_SETTINGS_API_KEYS", @@ -29033,7 +29035,7 @@ "RIGHT_ALL" ], "default": "right_invalid", - "description": "Right is the enum that defines all the different rights to do something in the network.\n\n - RIGHT_USER_INFO: The right to view user information.\n - RIGHT_USER_SETTINGS_BASIC: The right to edit basic user settings.\n - RIGHT_USER_SETTINGS_API_KEYS: The right to view and edit user API keys.\n - RIGHT_USER_DELETE: The right to delete user account.\n - RIGHT_USER_PURGE: The right to delete user account.\n - RIGHT_USER_AUTHORIZED_CLIENTS: The right to view and edit authorized OAuth clients of the user.\n - RIGHT_USER_APPLICATIONS_LIST: The right to list applications the user is a collaborator of.\n - RIGHT_USER_APPLICATIONS_CREATE: The right to create an application under the user account.\n - RIGHT_USER_GATEWAYS_LIST: The right to list gateways the user is a collaborator of.\n - RIGHT_USER_GATEWAYS_CREATE: The right to create a gateway under the account of the user.\n - RIGHT_USER_CLIENTS_LIST: The right to list OAuth clients the user is a collaborator of.\n - RIGHT_USER_CLIENTS_CREATE: The right to create an OAuth client under the account of the user.\n - RIGHT_USER_ORGANIZATIONS_LIST: The right to list organizations the user is a member of.\n - RIGHT_USER_ORGANIZATIONS_CREATE: The right to create an organization under the user account.\n - RIGHT_USER_NOTIFICATIONS_READ: The right to read notifications sent to the user.\n - RIGHT_USER_ALL: The pseudo-right for all (current and future) user rights.\n - RIGHT_APPLICATION_INFO: The right to view application information.\n - RIGHT_APPLICATION_SETTINGS_BASIC: The right to edit basic application settings.\n - RIGHT_APPLICATION_SETTINGS_API_KEYS: The right to view and edit application API keys.\n - RIGHT_APPLICATION_SETTINGS_COLLABORATORS: The right to view and edit application collaborators.\n - RIGHT_APPLICATION_SETTINGS_PACKAGES: The right to view and edit application packages and associations.\n - RIGHT_APPLICATION_DELETE: The right to delete application.\n - RIGHT_APPLICATION_PURGE: The right to purge application.\n - RIGHT_APPLICATION_DEVICES_READ: The right to view devices in application.\n - RIGHT_APPLICATION_DEVICES_WRITE: The right to create devices in application.\n - RIGHT_APPLICATION_DEVICES_READ_KEYS: The right to view device keys in application.\nNote that keys may not be stored in a way that supports viewing them.\n - RIGHT_APPLICATION_DEVICES_WRITE_KEYS: The right to edit device keys in application.\n - RIGHT_APPLICATION_TRAFFIC_READ: The right to read application traffic (uplink and downlink).\n - RIGHT_APPLICATION_TRAFFIC_UP_WRITE: The right to write uplink application traffic.\n - RIGHT_APPLICATION_TRAFFIC_DOWN_WRITE: The right to write downlink application traffic.\n - RIGHT_APPLICATION_LINK: The right to link as Application to a Network Server for traffic exchange,\ni.e. read uplink and write downlink (API keys only).\nThis right is typically only given to an Application Server.\nThis right implies RIGHT_APPLICATION_INFO, RIGHT_APPLICATION_TRAFFIC_READ,\nand RIGHT_APPLICATION_TRAFFIC_DOWN_WRITE.\n - RIGHT_APPLICATION_ALL: The pseudo-right for all (current and future) application rights.\n - RIGHT_CLIENT_ALL: The pseudo-right for all (current and future) OAuth client rights.\n - RIGHT_CLIENT_INFO: The right to read client information.\n - RIGHT_CLIENT_SETTINGS_BASIC: The right to edit basic client settings.\n - RIGHT_CLIENT_SETTINGS_COLLABORATORS: The right to view and edit client collaborators.\n - RIGHT_CLIENT_DELETE: The right to delete a client.\n - RIGHT_GATEWAY_INFO: The right to view gateway information.\n - RIGHT_GATEWAY_SETTINGS_BASIC: The right to edit basic gateway settings.\n - RIGHT_GATEWAY_SETTINGS_API_KEYS: The right to view and edit gateway API keys.\n - RIGHT_GATEWAY_SETTINGS_COLLABORATORS: The right to view and edit gateway collaborators.\n - RIGHT_GATEWAY_DELETE: The right to delete gateway.\n - RIGHT_GATEWAY_PURGE: The right to purge gateway.\n - RIGHT_GATEWAY_TRAFFIC_READ: The right to read gateway traffic.\n - RIGHT_GATEWAY_TRAFFIC_DOWN_WRITE: The right to write downlink gateway traffic.\n - RIGHT_GATEWAY_LINK: The right to link as Gateway to a Gateway Server for traffic exchange,\ni.e. write uplink and read downlink (API keys only)\nThis right is typically only given to a gateway.\nThis right implies RIGHT_GATEWAY_INFO.\n - RIGHT_GATEWAY_STATUS_READ: The right to view gateway status.\n - RIGHT_GATEWAY_LOCATION_READ: The right to view view gateway location.\n - RIGHT_GATEWAY_WRITE_SECRETS: The right to store secrets associated with this gateway.\n - RIGHT_GATEWAY_READ_SECRETS: The right to retrieve secrets associated with this gateway.\n - RIGHT_GATEWAY_ALL: The pseudo-right for all (current and future) gateway rights.\n - RIGHT_ORGANIZATION_INFO: The right to view organization information.\n - RIGHT_ORGANIZATION_SETTINGS_BASIC: The right to edit basic organization settings.\n - RIGHT_ORGANIZATION_SETTINGS_API_KEYS: The right to view and edit organization API keys.\n - RIGHT_ORGANIZATION_SETTINGS_MEMBERS: The right to view and edit organization members.\n - RIGHT_ORGANIZATION_DELETE: The right to delete organization.\n - RIGHT_ORGANIZATION_PURGE: The right to purge organization.\n - RIGHT_ORGANIZATION_APPLICATIONS_LIST: The right to list the applications the organization is a collaborator of.\n - RIGHT_ORGANIZATION_APPLICATIONS_CREATE: The right to create an application under the organization.\n - RIGHT_ORGANIZATION_GATEWAYS_LIST: The right to list the gateways the organization is a collaborator of.\n - RIGHT_ORGANIZATION_GATEWAYS_CREATE: The right to create a gateway under the organization.\n - RIGHT_ORGANIZATION_CLIENTS_LIST: The right to list the OAuth clients the organization is a collaborator of.\n - RIGHT_ORGANIZATION_CLIENTS_CREATE: The right to create an OAuth client under the organization.\n - RIGHT_ORGANIZATION_ADD_AS_COLLABORATOR: The right to add the organization as a collaborator on an existing entity.\n - RIGHT_ORGANIZATION_ALL: The pseudo-right for all (current and future) organization rights.\n - RIGHT_SEND_INVITES: The right to send invites to new users.\nNote that this is not prefixed with \"USER_\"; it is not a right on the user entity.\n - RIGHT_ALL: The pseudo-right for all (current and future) possible rights." + "description": "Right is the enum that defines all the different rights to do something in the network.\n\n - RIGHT_USER_INFO: The right to view user information.\n - RIGHT_USER_SETTINGS_BASIC: The right to edit basic user settings.\n - RIGHT_USER_SETTINGS_API_KEYS: The right to view and edit user API keys.\n - RIGHT_USER_DELETE: The right to delete user account.\n - RIGHT_USER_PURGE: The right to delete user account.\n - RIGHT_USER_AUTHORIZED_CLIENTS: The right to view and edit authorized OAuth clients of the user.\n - RIGHT_USER_APPLICATIONS_LIST: The right to list applications the user is a collaborator of.\n - RIGHT_USER_APPLICATIONS_CREATE: The right to create an application under the user account.\n - RIGHT_USER_GATEWAYS_LIST: The right to list gateways the user is a collaborator of.\n - RIGHT_USER_GATEWAYS_CREATE: The right to create a gateway under the account of the user.\n - RIGHT_USER_CLIENTS_LIST: The right to list OAuth clients the user is a collaborator of.\n - RIGHT_USER_CLIENTS_CREATE: The right to create an OAuth client under the account of the user.\n - RIGHT_USER_ORGANIZATIONS_LIST: The right to list organizations the user is a member of.\n - RIGHT_USER_ORGANIZATIONS_CREATE: The right to create an organization under the user account.\n - RIGHT_USER_NOTIFICATIONS_READ: The right to read notifications sent to the user.\n - RIGHT_USER_ALL: The pseudo-right for all (current and future) user rights.\n - RIGHT_APPLICATION_INFO: The right to view application information.\n - RIGHT_APPLICATION_SETTINGS_BASIC: The right to edit basic application settings.\n - RIGHT_APPLICATION_SETTINGS_API_KEYS: The right to view and edit application API keys.\n - RIGHT_APPLICATION_SETTINGS_COLLABORATORS: The right to view and edit application collaborators.\n - RIGHT_APPLICATION_SETTINGS_PACKAGES: The right to view and edit application packages and associations.\n - RIGHT_APPLICATION_DELETE: The right to delete application.\n - RIGHT_APPLICATION_PURGE: The right to purge application.\n - RIGHT_APPLICATION_DEVICES_READ: The right to view devices in application.\n - RIGHT_APPLICATION_DEVICES_WRITE: The right to create devices in application.\n - RIGHT_APPLICATION_DEVICES_READ_KEYS: The right to view device keys in application.\nNote that keys may not be stored in a way that supports viewing them.\n - RIGHT_APPLICATION_DEVICES_WRITE_KEYS: The right to edit device keys in application.\n - RIGHT_APPLICATION_TRAFFIC_READ: The right to read application traffic (uplink and downlink).\n - RIGHT_APPLICATION_TRAFFIC_UP_WRITE: The right to write uplink application traffic.\n - RIGHT_APPLICATION_TRAFFIC_DOWN_WRITE: The right to write downlink application traffic.\n - RIGHT_APPLICATION_LINK: The right to link as Application to a Network Server for traffic exchange,\ni.e. read uplink and write downlink (API keys only).\nThis right is typically only given to an Application Server.\nThis right implies RIGHT_APPLICATION_INFO, RIGHT_APPLICATION_TRAFFIC_READ,\nand RIGHT_APPLICATION_TRAFFIC_DOWN_WRITE.\n - RIGHT_APPLICATION_ALL: The pseudo-right for all (current and future) application rights.\n - RIGHT_CLIENT_ALL: The pseudo-right for all (current and future) OAuth client rights.\n - RIGHT_CLIENT_INFO: The right to read client information.\n - RIGHT_CLIENT_SETTINGS_BASIC: The right to edit basic client settings.\n - RIGHT_CLIENT_SETTINGS_COLLABORATORS: The right to view and edit client collaborators.\n - RIGHT_CLIENT_DELETE: The right to delete a client.\n - RIGHT_CLIENT_PURGE: The right to purge a client.\n - RIGHT_GATEWAY_INFO: The right to view gateway information.\n - RIGHT_GATEWAY_SETTINGS_BASIC: The right to edit basic gateway settings.\n - RIGHT_GATEWAY_SETTINGS_API_KEYS: The right to view and edit gateway API keys.\n - RIGHT_GATEWAY_SETTINGS_COLLABORATORS: The right to view and edit gateway collaborators.\n - RIGHT_GATEWAY_DELETE: The right to delete gateway.\n - RIGHT_GATEWAY_PURGE: The right to purge gateway.\n - RIGHT_GATEWAY_TRAFFIC_READ: The right to read gateway traffic.\n - RIGHT_GATEWAY_TRAFFIC_DOWN_WRITE: The right to write downlink gateway traffic.\n - RIGHT_GATEWAY_LINK: The right to link as Gateway to a Gateway Server for traffic exchange,\ni.e. write uplink and read downlink (API keys only)\nThis right is typically only given to a gateway.\nThis right implies RIGHT_GATEWAY_INFO.\n - RIGHT_GATEWAY_STATUS_READ: The right to view gateway status.\n - RIGHT_GATEWAY_LOCATION_READ: The right to view view gateway location.\n - RIGHT_GATEWAY_WRITE_SECRETS: The right to store secrets associated with this gateway.\n - RIGHT_GATEWAY_READ_SECRETS: The right to retrieve secrets associated with this gateway.\n - RIGHT_GATEWAY_ALL: The pseudo-right for all (current and future) gateway rights.\n - RIGHT_ORGANIZATION_INFO: The right to view organization information.\n - RIGHT_ORGANIZATION_SETTINGS_BASIC: The right to edit basic organization settings.\n - RIGHT_ORGANIZATION_SETTINGS_API_KEYS: The right to view and edit organization API keys.\n - RIGHT_ORGANIZATION_SETTINGS_MEMBERS: The right to view and edit organization members.\n - RIGHT_ORGANIZATION_DELETE: The right to delete organization.\n - RIGHT_ORGANIZATION_PURGE: The right to purge organization.\n - RIGHT_ORGANIZATION_APPLICATIONS_LIST: The right to list the applications the organization is a collaborator of.\n - RIGHT_ORGANIZATION_APPLICATIONS_CREATE: The right to create an application under the organization.\n - RIGHT_ORGANIZATION_GATEWAYS_LIST: The right to list the gateways the organization is a collaborator of.\n - RIGHT_ORGANIZATION_GATEWAYS_CREATE: The right to create a gateway under the organization.\n - RIGHT_ORGANIZATION_CLIENTS_LIST: The right to list the OAuth clients the organization is a collaborator of.\n - RIGHT_ORGANIZATION_CLIENTS_CREATE: The right to create an OAuth client under the organization.\n - RIGHT_ORGANIZATION_ADD_AS_COLLABORATOR: The right to add the organization as a collaborator on an existing entity.\n - RIGHT_ORGANIZATION_ALL: The pseudo-right for all (current and future) organization rights.\n - RIGHT_SEND_INVITES: The right to send invites to new users.\nNote that this is not prefixed with \"USER_\"; it is not a right on the user entity.\n - RIGHT_ALL: The pseudo-right for all (current and future) possible rights." }, "v3Rights": { "type": "object", diff --git a/api/ttn/lorawan/v3/rights.proto b/api/ttn/lorawan/v3/rights.proto index a6a30bab1d..7f9bed492d 100644 --- a/api/ttn/lorawan/v3/rights.proto +++ b/api/ttn/lorawan/v3/rights.proto @@ -114,6 +114,8 @@ enum Right { RIGHT_CLIENT_SETTINGS_COLLABORATORS = 62; // The right to delete a client. RIGHT_CLIENT_DELETE = 63; + // The right to purge a client. + RIGHT_CLIENT_PURGE = 68; // The right to view gateway information. RIGHT_GATEWAY_INFO = 30; @@ -183,7 +185,7 @@ enum Right { // The pseudo-right for all (current and future) possible rights. RIGHT_ALL = 55; - // Next value: 68 + // Next value: 69 } message Rights { diff --git a/pkg/ttnpb/rights.pb.go b/pkg/ttnpb/rights.pb.go index fa17afe8f9..7c8b7f44a2 100644 --- a/pkg/ttnpb/rights.pb.go +++ b/pkg/ttnpb/rights.pb.go @@ -122,6 +122,8 @@ const ( Right_RIGHT_CLIENT_SETTINGS_COLLABORATORS Right = 62 // The right to delete a client. Right_RIGHT_CLIENT_DELETE Right = 63 + // The right to purge a client. + Right_RIGHT_CLIENT_PURGE Right = 68 // The right to view gateway information. Right_RIGHT_GATEWAY_INFO Right = 30 // The right to edit basic gateway settings. @@ -229,6 +231,7 @@ var ( 61: "RIGHT_CLIENT_SETTINGS_BASIC", 62: "RIGHT_CLIENT_SETTINGS_COLLABORATORS", 63: "RIGHT_CLIENT_DELETE", + 68: "RIGHT_CLIENT_PURGE", 30: "RIGHT_GATEWAY_INFO", 31: "RIGHT_GATEWAY_SETTINGS_BASIC", 32: "RIGHT_GATEWAY_SETTINGS_API_KEYS", @@ -299,6 +302,7 @@ var ( "RIGHT_CLIENT_SETTINGS_BASIC": 61, "RIGHT_CLIENT_SETTINGS_COLLABORATORS": 62, "RIGHT_CLIENT_DELETE": 63, + "RIGHT_CLIENT_PURGE": 68, "RIGHT_GATEWAY_INFO": 30, "RIGHT_GATEWAY_SETTINGS_BASIC": 31, "RIGHT_GATEWAY_SETTINGS_API_KEYS": 32, @@ -782,7 +786,7 @@ var file_ttn_lorawan_v3_rights_proto_rawDesc = []byte{ 0x61, 0x62, 0x6f, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x43, 0x6f, 0x6c, 0x6c, 0x61, 0x62, 0x6f, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x0d, 0x63, - 0x6f, 0x6c, 0x6c, 0x61, 0x62, 0x6f, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x2a, 0xc9, 0x11, 0x0a, + 0x6f, 0x6c, 0x6c, 0x61, 0x62, 0x6f, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x2a, 0xe1, 0x11, 0x0a, 0x05, 0x52, 0x69, 0x67, 0x68, 0x74, 0x12, 0x11, 0x0a, 0x0d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x5f, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x01, 0x12, 0x1d, @@ -860,74 +864,75 @@ var file_ttn_lorawan_v3_rights_proto_rawDesc = []byte{ 0x4e, 0x54, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x43, 0x4f, 0x4c, 0x4c, 0x41, 0x42, 0x4f, 0x52, 0x41, 0x54, 0x4f, 0x52, 0x53, 0x10, 0x3e, 0x12, 0x17, 0x0a, 0x13, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x44, 0x45, 0x4c, 0x45, - 0x54, 0x45, 0x10, 0x3f, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, - 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x1e, 0x12, 0x20, 0x0a, 0x1c, - 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x53, 0x45, - 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x42, 0x41, 0x53, 0x49, 0x43, 0x10, 0x1f, 0x12, 0x23, - 0x0a, 0x1f, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, - 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x41, 0x50, 0x49, 0x5f, 0x4b, 0x45, 0x59, - 0x53, 0x10, 0x20, 0x12, 0x28, 0x0a, 0x24, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, - 0x45, 0x57, 0x41, 0x59, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x43, 0x4f, - 0x4c, 0x4c, 0x41, 0x42, 0x4f, 0x52, 0x41, 0x54, 0x4f, 0x52, 0x53, 0x10, 0x21, 0x12, 0x18, 0x0a, - 0x14, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x44, - 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x22, 0x12, 0x17, 0x0a, 0x13, 0x52, 0x49, 0x47, 0x48, 0x54, - 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x50, 0x55, 0x52, 0x47, 0x45, 0x10, 0x43, - 0x12, 0x1e, 0x0a, 0x1a, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, - 0x59, 0x5f, 0x54, 0x52, 0x41, 0x46, 0x46, 0x49, 0x43, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x10, 0x23, - 0x12, 0x24, 0x0a, 0x20, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, - 0x59, 0x5f, 0x54, 0x52, 0x41, 0x46, 0x46, 0x49, 0x43, 0x5f, 0x44, 0x4f, 0x57, 0x4e, 0x5f, 0x57, - 0x52, 0x49, 0x54, 0x45, 0x10, 0x24, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, - 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x4c, 0x49, 0x4e, 0x4b, 0x10, 0x25, 0x12, 0x1d, - 0x0a, 0x19, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, - 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x10, 0x26, 0x12, 0x1f, 0x0a, - 0x1b, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x4c, - 0x4f, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x10, 0x27, 0x12, 0x1f, - 0x0a, 0x1b, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, - 0x57, 0x52, 0x49, 0x54, 0x45, 0x5f, 0x53, 0x45, 0x43, 0x52, 0x45, 0x54, 0x53, 0x10, 0x39, 0x12, - 0x1e, 0x0a, 0x1a, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, - 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x53, 0x45, 0x43, 0x52, 0x45, 0x54, 0x53, 0x10, 0x3a, 0x12, - 0x15, 0x0a, 0x11, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, - 0x5f, 0x41, 0x4c, 0x4c, 0x10, 0x28, 0x12, 0x1b, 0x0a, 0x17, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, - 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x49, 0x4e, 0x46, - 0x4f, 0x10, 0x29, 0x12, 0x25, 0x0a, 0x21, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, - 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, - 0x47, 0x53, 0x5f, 0x42, 0x41, 0x53, 0x49, 0x43, 0x10, 0x2a, 0x12, 0x28, 0x0a, 0x24, 0x52, 0x49, - 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, - 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x41, 0x50, 0x49, 0x5f, 0x4b, 0x45, - 0x59, 0x53, 0x10, 0x2b, 0x12, 0x27, 0x0a, 0x23, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, - 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, - 0x4e, 0x47, 0x53, 0x5f, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, 0x53, 0x10, 0x2c, 0x12, 0x1d, 0x0a, - 0x19, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, - 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x2d, 0x12, 0x1c, 0x0a, 0x18, + 0x54, 0x45, 0x10, 0x3f, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x43, 0x4c, + 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x50, 0x55, 0x52, 0x47, 0x45, 0x10, 0x44, 0x12, 0x16, 0x0a, 0x12, + 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x49, 0x4e, + 0x46, 0x4f, 0x10, 0x1e, 0x12, 0x20, 0x0a, 0x1c, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, + 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x42, + 0x41, 0x53, 0x49, 0x43, 0x10, 0x1f, 0x12, 0x23, 0x0a, 0x1f, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, + 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, + 0x5f, 0x41, 0x50, 0x49, 0x5f, 0x4b, 0x45, 0x59, 0x53, 0x10, 0x20, 0x12, 0x28, 0x0a, 0x24, 0x52, + 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x53, 0x45, 0x54, + 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x43, 0x4f, 0x4c, 0x4c, 0x41, 0x42, 0x4f, 0x52, 0x41, 0x54, + 0x4f, 0x52, 0x53, 0x10, 0x21, 0x12, 0x18, 0x0a, 0x14, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, + 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x22, 0x12, + 0x17, 0x0a, 0x13, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, + 0x5f, 0x50, 0x55, 0x52, 0x47, 0x45, 0x10, 0x43, 0x12, 0x1e, 0x0a, 0x1a, 0x52, 0x49, 0x47, 0x48, + 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x54, 0x52, 0x41, 0x46, 0x46, 0x49, + 0x43, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x10, 0x23, 0x12, 0x24, 0x0a, 0x20, 0x52, 0x49, 0x47, 0x48, + 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x54, 0x52, 0x41, 0x46, 0x46, 0x49, + 0x43, 0x5f, 0x44, 0x4f, 0x57, 0x4e, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x10, 0x24, 0x12, 0x16, + 0x0a, 0x12, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, + 0x4c, 0x49, 0x4e, 0x4b, 0x10, 0x25, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, + 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, + 0x45, 0x41, 0x44, 0x10, 0x26, 0x12, 0x1f, 0x0a, 0x1b, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, + 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x4c, 0x4f, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, + 0x52, 0x45, 0x41, 0x44, 0x10, 0x27, 0x12, 0x1f, 0x0a, 0x1b, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, + 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x5f, 0x53, 0x45, + 0x43, 0x52, 0x45, 0x54, 0x53, 0x10, 0x39, 0x12, 0x1e, 0x0a, 0x1a, 0x52, 0x49, 0x47, 0x48, 0x54, + 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x53, 0x45, + 0x43, 0x52, 0x45, 0x54, 0x53, 0x10, 0x3a, 0x12, 0x15, 0x0a, 0x11, 0x52, 0x49, 0x47, 0x48, 0x54, + 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x41, 0x4c, 0x4c, 0x10, 0x28, 0x12, 0x1b, + 0x0a, 0x17, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, + 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x29, 0x12, 0x25, 0x0a, 0x21, 0x52, + 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, + 0x4e, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x42, 0x41, 0x53, 0x49, 0x43, + 0x10, 0x2a, 0x12, 0x28, 0x0a, 0x24, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, + 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, + 0x53, 0x5f, 0x41, 0x50, 0x49, 0x5f, 0x4b, 0x45, 0x59, 0x53, 0x10, 0x2b, 0x12, 0x27, 0x0a, 0x23, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, - 0x4f, 0x4e, 0x5f, 0x50, 0x55, 0x52, 0x47, 0x45, 0x10, 0x41, 0x12, 0x28, 0x0a, 0x24, 0x52, 0x49, - 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, - 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x5f, 0x4c, 0x49, - 0x53, 0x54, 0x10, 0x2e, 0x12, 0x2a, 0x0a, 0x26, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, - 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, - 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, 0x2f, - 0x12, 0x24, 0x0a, 0x20, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, - 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x53, 0x5f, - 0x4c, 0x49, 0x53, 0x54, 0x10, 0x30, 0x12, 0x26, 0x0a, 0x22, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, - 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x47, 0x41, 0x54, - 0x45, 0x57, 0x41, 0x59, 0x53, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, 0x31, 0x12, 0x23, - 0x0a, 0x1f, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, - 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x53, 0x5f, 0x4c, 0x49, 0x53, - 0x54, 0x10, 0x32, 0x12, 0x25, 0x0a, 0x21, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, - 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, - 0x53, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, 0x33, 0x12, 0x2a, 0x0a, 0x26, 0x52, 0x49, - 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, - 0x5f, 0x41, 0x44, 0x44, 0x5f, 0x41, 0x53, 0x5f, 0x43, 0x4f, 0x4c, 0x4c, 0x41, 0x42, 0x4f, 0x52, - 0x41, 0x54, 0x4f, 0x52, 0x10, 0x34, 0x12, 0x1a, 0x0a, 0x16, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, - 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x4c, 0x4c, - 0x10, 0x35, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x53, 0x45, 0x4e, 0x44, - 0x5f, 0x49, 0x4e, 0x56, 0x49, 0x54, 0x45, 0x53, 0x10, 0x36, 0x12, 0x0d, 0x0a, 0x09, 0x52, 0x49, - 0x47, 0x48, 0x54, 0x5f, 0x41, 0x4c, 0x4c, 0x10, 0x37, 0x1a, 0x0d, 0xea, 0xaa, 0x19, 0x09, 0x18, - 0x01, 0x2a, 0x05, 0x52, 0x49, 0x47, 0x48, 0x54, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x6f, 0x2e, 0x74, - 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, - 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, - 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x74, 0x6e, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, + 0x4f, 0x4e, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x4d, 0x45, 0x4d, 0x42, + 0x45, 0x52, 0x53, 0x10, 0x2c, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, + 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x4c, 0x45, + 0x54, 0x45, 0x10, 0x2d, 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, + 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x50, 0x55, 0x52, 0x47, 0x45, + 0x10, 0x41, 0x12, 0x28, 0x0a, 0x24, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, + 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, + 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x2e, 0x12, 0x2a, 0x0a, 0x26, + 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, + 0x4f, 0x4e, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x5f, + 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, 0x2f, 0x12, 0x24, 0x0a, 0x20, 0x52, 0x49, 0x47, 0x48, + 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x47, + 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x53, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x30, 0x12, 0x26, + 0x0a, 0x22, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, + 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x53, 0x5f, 0x43, 0x52, + 0x45, 0x41, 0x54, 0x45, 0x10, 0x31, 0x12, 0x23, 0x0a, 0x1f, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, + 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x43, 0x4c, 0x49, + 0x45, 0x4e, 0x54, 0x53, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x32, 0x12, 0x25, 0x0a, 0x21, 0x52, + 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, + 0x4e, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x53, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, + 0x10, 0x33, 0x12, 0x2a, 0x0a, 0x26, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, + 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x44, 0x44, 0x5f, 0x41, 0x53, 0x5f, + 0x43, 0x4f, 0x4c, 0x4c, 0x41, 0x42, 0x4f, 0x52, 0x41, 0x54, 0x4f, 0x52, 0x10, 0x34, 0x12, 0x1a, + 0x0a, 0x16, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, + 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x4c, 0x4c, 0x10, 0x35, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x49, + 0x47, 0x48, 0x54, 0x5f, 0x53, 0x45, 0x4e, 0x44, 0x5f, 0x49, 0x4e, 0x56, 0x49, 0x54, 0x45, 0x53, + 0x10, 0x36, 0x12, 0x0d, 0x0a, 0x09, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x4c, 0x4c, 0x10, + 0x37, 0x1a, 0x0d, 0xea, 0xaa, 0x19, 0x09, 0x18, 0x01, 0x2a, 0x05, 0x52, 0x49, 0x47, 0x48, 0x54, + 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, + 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, + 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x74, + 0x6e, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/pkg/ttnpb/rights_json.pb.go b/pkg/ttnpb/rights_json.pb.go index ed9005800c..00bc047e92 100644 --- a/pkg/ttnpb/rights_json.pb.go +++ b/pkg/ttnpb/rights_json.pb.go @@ -65,6 +65,7 @@ var Right_customvalue = map[string]int32{ "CLIENT_SETTINGS_BASIC": 61, "CLIENT_SETTINGS_COLLABORATORS": 62, "CLIENT_DELETE": 63, + "CLIENT_PURGE": 68, "GATEWAY_INFO": 30, "GATEWAY_SETTINGS_BASIC": 31, "GATEWAY_SETTINGS_API_KEYS": 32, diff --git a/sdk/js/generated/api.json b/sdk/js/generated/api.json index 71ff36d188..0d0a1eb47c 100644 --- a/sdk/js/generated/api.json +++ b/sdk/js/generated/api.json @@ -49904,6 +49904,11 @@ "number": "63", "description": "The right to delete a client." }, + { + "name": "RIGHT_CLIENT_PURGE", + "number": "68", + "description": "The right to purge a client." + }, { "name": "RIGHT_GATEWAY_INFO", "number": "30", From 27ab7ae731288cce796b826bfaa95ab0948735ff Mon Sep 17 00:00:00 2001 From: Nicholas Cristofaro Date: Mon, 25 Nov 2024 11:22:52 -0300 Subject: [PATCH 16/40] is: Update purgeClient to check rights --- pkg/identityserver/client_registry.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pkg/identityserver/client_registry.go b/pkg/identityserver/client_registry.go index 3f45477907..639dabb27a 100644 --- a/pkg/identityserver/client_registry.go +++ b/pkg/identityserver/client_registry.go @@ -429,6 +429,11 @@ func (is *IdentityServer) purgeClient(ctx context.Context, ids *ttnpb.ClientIden if !is.IsAdmin(ctx) { return nil, errAdminsPurgeClients.New() } + if err := rights.RequireClient( + store.WithSoftDeleted(ctx, false), ids, ttnpb.Right_RIGHT_CLIENT_PURGE, + ); err != nil { + return nil, err + } err := is.store.Transact(ctx, func(ctx context.Context, st store.Store) error { // delete related authorizations before purging the client err := st.DeleteClientAuthorizations(ctx, ids) From 9144339d0592e5bf1bc7eb1810a51e52d5c57d0f Mon Sep 17 00:00:00 2001 From: Nicholas Cristofaro Date: Mon, 25 Nov 2024 11:31:11 -0300 Subject: [PATCH 17/40] dev: Create generic insufficient rights error on auth/rights pkg --- config/messages.json | 9 +++++++++ pkg/auth/rights/require.go | 5 +++++ pkg/webui/locales/ja.json | 1 + 3 files changed, 15 insertions(+) diff --git a/config/messages.json b/config/messages.json index ed35fd3be9..c025a0211f 100644 --- a/config/messages.json +++ b/config/messages.json @@ -3230,6 +3230,15 @@ "file": "require.go" } }, + "error:pkg/auth/rights:insufficient_rights": { + "translations": { + "en": "insufficient rights for {entity_type} `{uid}`" + }, + "description": { + "package": "pkg/auth/rights", + "file": "require.go" + } + }, "error:pkg/auth/rights:insufficient_universal_rights": { "translations": { "en": "insufficient universal rights" diff --git a/pkg/auth/rights/require.go b/pkg/auth/rights/require.go index 067f9089ae..331512e284 100644 --- a/pkg/auth/rights/require.go +++ b/pkg/auth/rights/require.go @@ -82,6 +82,11 @@ var ( "insufficient rights for user `{uid}`", "missing", ) + ErrInsufficientRights = errors.DefinePermissionDenied( + "insufficient_rights", + "insufficient rights for {entity_type} `{uid}`", + "missing", + ) ) func rightsNames(rights ...ttnpb.Right) []string { diff --git a/pkg/webui/locales/ja.json b/pkg/webui/locales/ja.json index c1a289f572..66f0ed731d 100644 --- a/pkg/webui/locales/ja.json +++ b/pkg/webui/locales/ja.json @@ -2184,6 +2184,7 @@ "error:pkg/auth/rights:insufficient_client_rights": "クライアント `{uid}` に対して権限が不十分です", "error:pkg/auth/rights:insufficient_gateway_rights": "ゲートウェイ `{uid}` に対して権限が不十分です", "error:pkg/auth/rights:insufficient_organization_rights": "組織 `{uid}` に対して権限が不十分です", + "error:pkg/auth/rights:insufficient_rights": "", "error:pkg/auth/rights:insufficient_universal_rights": "普遍的な権利が不十分", "error:pkg/auth/rights:insufficient_user_rights": "ユーザ `{uid}` に対して権限が不十分です", "error:pkg/auth/rights:no_admin": "管理者がいません", From 690aae87a46826b0f346537fc34d944b1a5bdd79 Mon Sep 17 00:00:00 2001 From: Nicholas Cristofaro Date: Mon, 25 Nov 2024 11:33:01 -0300 Subject: [PATCH 18/40] api: Reserve enterprise rights' values --- api/ttn/lorawan/v3/rights.proto | 21 ++++++++++++++++++++- pkg/ttnpb/rights.pb.go | 17 ++++++++++++----- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/api/ttn/lorawan/v3/rights.proto b/api/ttn/lorawan/v3/rights.proto index 7f9bed492d..085e5dedce 100644 --- a/api/ttn/lorawan/v3/rights.proto +++ b/api/ttn/lorawan/v3/rights.proto @@ -182,10 +182,29 @@ enum Right { // Note that this is not prefixed with "USER_"; it is not a right on the user entity. RIGHT_SEND_INVITES = 54; + reserved 69; + reserved 70; + reserved 71; + reserved 72; + reserved 73; + reserved 74; + reserved 75; + reserved 76; + reserved 77; + reserved 78; + reserved 79; + reserved 80; + reserved 81; + reserved 82; + reserved 83; + reserved 84; + reserved 85; + reserved 86; + // The pseudo-right for all (current and future) possible rights. RIGHT_ALL = 55; - // Next value: 69 + // Next value: 87 } message Rights { diff --git a/pkg/ttnpb/rights.pb.go b/pkg/ttnpb/rights.pb.go index 7c8b7f44a2..daae1a8b46 100644 --- a/pkg/ttnpb/rights.pb.go +++ b/pkg/ttnpb/rights.pb.go @@ -786,7 +786,7 @@ var file_ttn_lorawan_v3_rights_proto_rawDesc = []byte{ 0x61, 0x62, 0x6f, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x43, 0x6f, 0x6c, 0x6c, 0x61, 0x62, 0x6f, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x0d, 0x63, - 0x6f, 0x6c, 0x6c, 0x61, 0x62, 0x6f, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x2a, 0xe1, 0x11, 0x0a, + 0x6f, 0x6c, 0x6c, 0x61, 0x62, 0x6f, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x2a, 0xcd, 0x12, 0x0a, 0x05, 0x52, 0x69, 0x67, 0x68, 0x74, 0x12, 0x11, 0x0a, 0x0d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x5f, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x01, 0x12, 0x1d, @@ -929,10 +929,17 @@ var file_ttn_lorawan_v3_rights_proto_rawDesc = []byte{ 0x47, 0x48, 0x54, 0x5f, 0x53, 0x45, 0x4e, 0x44, 0x5f, 0x49, 0x4e, 0x56, 0x49, 0x54, 0x45, 0x53, 0x10, 0x36, 0x12, 0x0d, 0x0a, 0x09, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x4c, 0x4c, 0x10, 0x37, 0x1a, 0x0d, 0xea, 0xaa, 0x19, 0x09, 0x18, 0x01, 0x2a, 0x05, 0x52, 0x49, 0x47, 0x48, 0x54, - 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, - 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, - 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x74, - 0x6e, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x22, 0x04, 0x08, 0x45, 0x10, 0x45, 0x22, 0x04, 0x08, 0x46, 0x10, 0x46, 0x22, 0x04, 0x08, 0x47, + 0x10, 0x47, 0x22, 0x04, 0x08, 0x48, 0x10, 0x48, 0x22, 0x04, 0x08, 0x49, 0x10, 0x49, 0x22, 0x04, + 0x08, 0x4a, 0x10, 0x4a, 0x22, 0x04, 0x08, 0x4b, 0x10, 0x4b, 0x22, 0x04, 0x08, 0x4c, 0x10, 0x4c, + 0x22, 0x04, 0x08, 0x4d, 0x10, 0x4d, 0x22, 0x04, 0x08, 0x4e, 0x10, 0x4e, 0x22, 0x04, 0x08, 0x4f, + 0x10, 0x4f, 0x22, 0x04, 0x08, 0x50, 0x10, 0x50, 0x22, 0x04, 0x08, 0x51, 0x10, 0x51, 0x22, 0x04, + 0x08, 0x52, 0x10, 0x52, 0x22, 0x04, 0x08, 0x53, 0x10, 0x53, 0x22, 0x04, 0x08, 0x54, 0x10, 0x54, + 0x22, 0x04, 0x08, 0x55, 0x10, 0x55, 0x22, 0x04, 0x08, 0x56, 0x10, 0x56, 0x42, 0x31, 0x5a, 0x2f, + 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, + 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, + 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x74, 0x6e, 0x70, 0x62, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( From 327078efeda15f81420bf0ff0040b7d423bd0e4f Mon Sep 17 00:00:00 2001 From: Nicholas Cristofaro Date: Mon, 25 Nov 2024 11:52:24 -0300 Subject: [PATCH 19/40] api: Add RIGHT_USER_CREATE and RIGHT_USER_LIST --- api/ttn/lorawan/v3/api.md | 2 + api/ttn/lorawan/v3/api.swagger.json | 8 +- api/ttn/lorawan/v3/rights.proto | 6 +- pkg/ttnpb/rights.pb.go | 305 ++++++++++++++-------------- pkg/ttnpb/rights_json.pb.go | 2 + sdk/js/generated/api.json | 10 + 6 files changed, 183 insertions(+), 150 deletions(-) diff --git a/api/ttn/lorawan/v3/api.md b/api/ttn/lorawan/v3/api.md index 56b3e62b74..196bc6e43a 100644 --- a/api/ttn/lorawan/v3/api.md +++ b/api/ttn/lorawan/v3/api.md @@ -10974,6 +10974,8 @@ Right is the enum that defines all the different rights to do something in the n | `right_invalid` | 0 | | | `RIGHT_USER_INFO` | 1 | The right to view user information. | | `RIGHT_USER_SETTINGS_BASIC` | 2 | The right to edit basic user settings. | +| `RIGHT_USER_LIST` | 87 | The right to list users accounts. | +| `RIGHT_USER_CREATE` | 88 | The right to create an user account. | | `RIGHT_USER_SETTINGS_API_KEYS` | 3 | The right to view and edit user API keys. | | `RIGHT_USER_DELETE` | 4 | The right to delete user account. | | `RIGHT_USER_PURGE` | 66 | The right to delete user account. | diff --git a/api/ttn/lorawan/v3/api.swagger.json b/api/ttn/lorawan/v3/api.swagger.json index 4b1565a5ef..d9eb432aee 100644 --- a/api/ttn/lorawan/v3/api.swagger.json +++ b/api/ttn/lorawan/v3/api.swagger.json @@ -6911,7 +6911,7 @@ "parameters": [ { "name": "required.rights", - "description": " - RIGHT_USER_INFO: The right to view user information.\n - RIGHT_USER_SETTINGS_BASIC: The right to edit basic user settings.\n - RIGHT_USER_SETTINGS_API_KEYS: The right to view and edit user API keys.\n - RIGHT_USER_DELETE: The right to delete user account.\n - RIGHT_USER_PURGE: The right to delete user account.\n - RIGHT_USER_AUTHORIZED_CLIENTS: The right to view and edit authorized OAuth clients of the user.\n - RIGHT_USER_APPLICATIONS_LIST: The right to list applications the user is a collaborator of.\n - RIGHT_USER_APPLICATIONS_CREATE: The right to create an application under the user account.\n - RIGHT_USER_GATEWAYS_LIST: The right to list gateways the user is a collaborator of.\n - RIGHT_USER_GATEWAYS_CREATE: The right to create a gateway under the account of the user.\n - RIGHT_USER_CLIENTS_LIST: The right to list OAuth clients the user is a collaborator of.\n - RIGHT_USER_CLIENTS_CREATE: The right to create an OAuth client under the account of the user.\n - RIGHT_USER_ORGANIZATIONS_LIST: The right to list organizations the user is a member of.\n - RIGHT_USER_ORGANIZATIONS_CREATE: The right to create an organization under the user account.\n - RIGHT_USER_NOTIFICATIONS_READ: The right to read notifications sent to the user.\n - RIGHT_USER_ALL: The pseudo-right for all (current and future) user rights.\n - RIGHT_APPLICATION_INFO: The right to view application information.\n - RIGHT_APPLICATION_SETTINGS_BASIC: The right to edit basic application settings.\n - RIGHT_APPLICATION_SETTINGS_API_KEYS: The right to view and edit application API keys.\n - RIGHT_APPLICATION_SETTINGS_COLLABORATORS: The right to view and edit application collaborators.\n - RIGHT_APPLICATION_SETTINGS_PACKAGES: The right to view and edit application packages and associations.\n - RIGHT_APPLICATION_DELETE: The right to delete application.\n - RIGHT_APPLICATION_PURGE: The right to purge application.\n - RIGHT_APPLICATION_DEVICES_READ: The right to view devices in application.\n - RIGHT_APPLICATION_DEVICES_WRITE: The right to create devices in application.\n - RIGHT_APPLICATION_DEVICES_READ_KEYS: The right to view device keys in application.\nNote that keys may not be stored in a way that supports viewing them.\n - RIGHT_APPLICATION_DEVICES_WRITE_KEYS: The right to edit device keys in application.\n - RIGHT_APPLICATION_TRAFFIC_READ: The right to read application traffic (uplink and downlink).\n - RIGHT_APPLICATION_TRAFFIC_UP_WRITE: The right to write uplink application traffic.\n - RIGHT_APPLICATION_TRAFFIC_DOWN_WRITE: The right to write downlink application traffic.\n - RIGHT_APPLICATION_LINK: The right to link as Application to a Network Server for traffic exchange,\ni.e. read uplink and write downlink (API keys only).\nThis right is typically only given to an Application Server.\nThis right implies RIGHT_APPLICATION_INFO, RIGHT_APPLICATION_TRAFFIC_READ,\nand RIGHT_APPLICATION_TRAFFIC_DOWN_WRITE.\n - RIGHT_APPLICATION_ALL: The pseudo-right for all (current and future) application rights.\n - RIGHT_CLIENT_ALL: The pseudo-right for all (current and future) OAuth client rights.\n - RIGHT_CLIENT_INFO: The right to read client information.\n - RIGHT_CLIENT_SETTINGS_BASIC: The right to edit basic client settings.\n - RIGHT_CLIENT_SETTINGS_COLLABORATORS: The right to view and edit client collaborators.\n - RIGHT_CLIENT_DELETE: The right to delete a client.\n - RIGHT_CLIENT_PURGE: The right to purge a client.\n - RIGHT_GATEWAY_INFO: The right to view gateway information.\n - RIGHT_GATEWAY_SETTINGS_BASIC: The right to edit basic gateway settings.\n - RIGHT_GATEWAY_SETTINGS_API_KEYS: The right to view and edit gateway API keys.\n - RIGHT_GATEWAY_SETTINGS_COLLABORATORS: The right to view and edit gateway collaborators.\n - RIGHT_GATEWAY_DELETE: The right to delete gateway.\n - RIGHT_GATEWAY_PURGE: The right to purge gateway.\n - RIGHT_GATEWAY_TRAFFIC_READ: The right to read gateway traffic.\n - RIGHT_GATEWAY_TRAFFIC_DOWN_WRITE: The right to write downlink gateway traffic.\n - RIGHT_GATEWAY_LINK: The right to link as Gateway to a Gateway Server for traffic exchange,\ni.e. write uplink and read downlink (API keys only)\nThis right is typically only given to a gateway.\nThis right implies RIGHT_GATEWAY_INFO.\n - RIGHT_GATEWAY_STATUS_READ: The right to view gateway status.\n - RIGHT_GATEWAY_LOCATION_READ: The right to view view gateway location.\n - RIGHT_GATEWAY_WRITE_SECRETS: The right to store secrets associated with this gateway.\n - RIGHT_GATEWAY_READ_SECRETS: The right to retrieve secrets associated with this gateway.\n - RIGHT_GATEWAY_ALL: The pseudo-right for all (current and future) gateway rights.\n - RIGHT_ORGANIZATION_INFO: The right to view organization information.\n - RIGHT_ORGANIZATION_SETTINGS_BASIC: The right to edit basic organization settings.\n - RIGHT_ORGANIZATION_SETTINGS_API_KEYS: The right to view and edit organization API keys.\n - RIGHT_ORGANIZATION_SETTINGS_MEMBERS: The right to view and edit organization members.\n - RIGHT_ORGANIZATION_DELETE: The right to delete organization.\n - RIGHT_ORGANIZATION_PURGE: The right to purge organization.\n - RIGHT_ORGANIZATION_APPLICATIONS_LIST: The right to list the applications the organization is a collaborator of.\n - RIGHT_ORGANIZATION_APPLICATIONS_CREATE: The right to create an application under the organization.\n - RIGHT_ORGANIZATION_GATEWAYS_LIST: The right to list the gateways the organization is a collaborator of.\n - RIGHT_ORGANIZATION_GATEWAYS_CREATE: The right to create a gateway under the organization.\n - RIGHT_ORGANIZATION_CLIENTS_LIST: The right to list the OAuth clients the organization is a collaborator of.\n - RIGHT_ORGANIZATION_CLIENTS_CREATE: The right to create an OAuth client under the organization.\n - RIGHT_ORGANIZATION_ADD_AS_COLLABORATOR: The right to add the organization as a collaborator on an existing entity.\n - RIGHT_ORGANIZATION_ALL: The pseudo-right for all (current and future) organization rights.\n - RIGHT_SEND_INVITES: The right to send invites to new users.\nNote that this is not prefixed with \"USER_\"; it is not a right on the user entity.\n - RIGHT_ALL: The pseudo-right for all (current and future) possible rights.", + "description": " - RIGHT_USER_INFO: The right to view user information.\n - RIGHT_USER_SETTINGS_BASIC: The right to edit basic user settings.\n - RIGHT_USER_LIST: The right to list users accounts.\n - RIGHT_USER_CREATE: The right to create an user account.\n - RIGHT_USER_SETTINGS_API_KEYS: The right to view and edit user API keys.\n - RIGHT_USER_DELETE: The right to delete user account.\n - RIGHT_USER_PURGE: The right to delete user account.\n - RIGHT_USER_AUTHORIZED_CLIENTS: The right to view and edit authorized OAuth clients of the user.\n - RIGHT_USER_APPLICATIONS_LIST: The right to list applications the user is a collaborator of.\n - RIGHT_USER_APPLICATIONS_CREATE: The right to create an application under the user account.\n - RIGHT_USER_GATEWAYS_LIST: The right to list gateways the user is a collaborator of.\n - RIGHT_USER_GATEWAYS_CREATE: The right to create a gateway under the account of the user.\n - RIGHT_USER_CLIENTS_LIST: The right to list OAuth clients the user is a collaborator of.\n - RIGHT_USER_CLIENTS_CREATE: The right to create an OAuth client under the account of the user.\n - RIGHT_USER_ORGANIZATIONS_LIST: The right to list organizations the user is a member of.\n - RIGHT_USER_ORGANIZATIONS_CREATE: The right to create an organization under the user account.\n - RIGHT_USER_NOTIFICATIONS_READ: The right to read notifications sent to the user.\n - RIGHT_USER_ALL: The pseudo-right for all (current and future) user rights.\n - RIGHT_APPLICATION_INFO: The right to view application information.\n - RIGHT_APPLICATION_SETTINGS_BASIC: The right to edit basic application settings.\n - RIGHT_APPLICATION_SETTINGS_API_KEYS: The right to view and edit application API keys.\n - RIGHT_APPLICATION_SETTINGS_COLLABORATORS: The right to view and edit application collaborators.\n - RIGHT_APPLICATION_SETTINGS_PACKAGES: The right to view and edit application packages and associations.\n - RIGHT_APPLICATION_DELETE: The right to delete application.\n - RIGHT_APPLICATION_PURGE: The right to purge application.\n - RIGHT_APPLICATION_DEVICES_READ: The right to view devices in application.\n - RIGHT_APPLICATION_DEVICES_WRITE: The right to create devices in application.\n - RIGHT_APPLICATION_DEVICES_READ_KEYS: The right to view device keys in application.\nNote that keys may not be stored in a way that supports viewing them.\n - RIGHT_APPLICATION_DEVICES_WRITE_KEYS: The right to edit device keys in application.\n - RIGHT_APPLICATION_TRAFFIC_READ: The right to read application traffic (uplink and downlink).\n - RIGHT_APPLICATION_TRAFFIC_UP_WRITE: The right to write uplink application traffic.\n - RIGHT_APPLICATION_TRAFFIC_DOWN_WRITE: The right to write downlink application traffic.\n - RIGHT_APPLICATION_LINK: The right to link as Application to a Network Server for traffic exchange,\ni.e. read uplink and write downlink (API keys only).\nThis right is typically only given to an Application Server.\nThis right implies RIGHT_APPLICATION_INFO, RIGHT_APPLICATION_TRAFFIC_READ,\nand RIGHT_APPLICATION_TRAFFIC_DOWN_WRITE.\n - RIGHT_APPLICATION_ALL: The pseudo-right for all (current and future) application rights.\n - RIGHT_CLIENT_ALL: The pseudo-right for all (current and future) OAuth client rights.\n - RIGHT_CLIENT_INFO: The right to read client information.\n - RIGHT_CLIENT_SETTINGS_BASIC: The right to edit basic client settings.\n - RIGHT_CLIENT_SETTINGS_COLLABORATORS: The right to view and edit client collaborators.\n - RIGHT_CLIENT_DELETE: The right to delete a client.\n - RIGHT_CLIENT_PURGE: The right to purge a client.\n - RIGHT_GATEWAY_INFO: The right to view gateway information.\n - RIGHT_GATEWAY_SETTINGS_BASIC: The right to edit basic gateway settings.\n - RIGHT_GATEWAY_SETTINGS_API_KEYS: The right to view and edit gateway API keys.\n - RIGHT_GATEWAY_SETTINGS_COLLABORATORS: The right to view and edit gateway collaborators.\n - RIGHT_GATEWAY_DELETE: The right to delete gateway.\n - RIGHT_GATEWAY_PURGE: The right to purge gateway.\n - RIGHT_GATEWAY_TRAFFIC_READ: The right to read gateway traffic.\n - RIGHT_GATEWAY_TRAFFIC_DOWN_WRITE: The right to write downlink gateway traffic.\n - RIGHT_GATEWAY_LINK: The right to link as Gateway to a Gateway Server for traffic exchange,\ni.e. write uplink and read downlink (API keys only)\nThis right is typically only given to a gateway.\nThis right implies RIGHT_GATEWAY_INFO.\n - RIGHT_GATEWAY_STATUS_READ: The right to view gateway status.\n - RIGHT_GATEWAY_LOCATION_READ: The right to view view gateway location.\n - RIGHT_GATEWAY_WRITE_SECRETS: The right to store secrets associated with this gateway.\n - RIGHT_GATEWAY_READ_SECRETS: The right to retrieve secrets associated with this gateway.\n - RIGHT_GATEWAY_ALL: The pseudo-right for all (current and future) gateway rights.\n - RIGHT_ORGANIZATION_INFO: The right to view organization information.\n - RIGHT_ORGANIZATION_SETTINGS_BASIC: The right to edit basic organization settings.\n - RIGHT_ORGANIZATION_SETTINGS_API_KEYS: The right to view and edit organization API keys.\n - RIGHT_ORGANIZATION_SETTINGS_MEMBERS: The right to view and edit organization members.\n - RIGHT_ORGANIZATION_DELETE: The right to delete organization.\n - RIGHT_ORGANIZATION_PURGE: The right to purge organization.\n - RIGHT_ORGANIZATION_APPLICATIONS_LIST: The right to list the applications the organization is a collaborator of.\n - RIGHT_ORGANIZATION_APPLICATIONS_CREATE: The right to create an application under the organization.\n - RIGHT_ORGANIZATION_GATEWAYS_LIST: The right to list the gateways the organization is a collaborator of.\n - RIGHT_ORGANIZATION_GATEWAYS_CREATE: The right to create a gateway under the organization.\n - RIGHT_ORGANIZATION_CLIENTS_LIST: The right to list the OAuth clients the organization is a collaborator of.\n - RIGHT_ORGANIZATION_CLIENTS_CREATE: The right to create an OAuth client under the organization.\n - RIGHT_ORGANIZATION_ADD_AS_COLLABORATOR: The right to add the organization as a collaborator on an existing entity.\n - RIGHT_ORGANIZATION_ALL: The pseudo-right for all (current and future) organization rights.\n - RIGHT_SEND_INVITES: The right to send invites to new users.\nNote that this is not prefixed with \"USER_\"; it is not a right on the user entity.\n - RIGHT_ALL: The pseudo-right for all (current and future) possible rights.", "in": "query", "required": false, "type": "array", @@ -6921,6 +6921,8 @@ "right_invalid", "RIGHT_USER_INFO", "RIGHT_USER_SETTINGS_BASIC", + "RIGHT_USER_LIST", + "RIGHT_USER_CREATE", "RIGHT_USER_SETTINGS_API_KEYS", "RIGHT_USER_DELETE", "RIGHT_USER_PURGE", @@ -28967,6 +28969,8 @@ "right_invalid", "RIGHT_USER_INFO", "RIGHT_USER_SETTINGS_BASIC", + "RIGHT_USER_LIST", + "RIGHT_USER_CREATE", "RIGHT_USER_SETTINGS_API_KEYS", "RIGHT_USER_DELETE", "RIGHT_USER_PURGE", @@ -29035,7 +29039,7 @@ "RIGHT_ALL" ], "default": "right_invalid", - "description": "Right is the enum that defines all the different rights to do something in the network.\n\n - RIGHT_USER_INFO: The right to view user information.\n - RIGHT_USER_SETTINGS_BASIC: The right to edit basic user settings.\n - RIGHT_USER_SETTINGS_API_KEYS: The right to view and edit user API keys.\n - RIGHT_USER_DELETE: The right to delete user account.\n - RIGHT_USER_PURGE: The right to delete user account.\n - RIGHT_USER_AUTHORIZED_CLIENTS: The right to view and edit authorized OAuth clients of the user.\n - RIGHT_USER_APPLICATIONS_LIST: The right to list applications the user is a collaborator of.\n - RIGHT_USER_APPLICATIONS_CREATE: The right to create an application under the user account.\n - RIGHT_USER_GATEWAYS_LIST: The right to list gateways the user is a collaborator of.\n - RIGHT_USER_GATEWAYS_CREATE: The right to create a gateway under the account of the user.\n - RIGHT_USER_CLIENTS_LIST: The right to list OAuth clients the user is a collaborator of.\n - RIGHT_USER_CLIENTS_CREATE: The right to create an OAuth client under the account of the user.\n - RIGHT_USER_ORGANIZATIONS_LIST: The right to list organizations the user is a member of.\n - RIGHT_USER_ORGANIZATIONS_CREATE: The right to create an organization under the user account.\n - RIGHT_USER_NOTIFICATIONS_READ: The right to read notifications sent to the user.\n - RIGHT_USER_ALL: The pseudo-right for all (current and future) user rights.\n - RIGHT_APPLICATION_INFO: The right to view application information.\n - RIGHT_APPLICATION_SETTINGS_BASIC: The right to edit basic application settings.\n - RIGHT_APPLICATION_SETTINGS_API_KEYS: The right to view and edit application API keys.\n - RIGHT_APPLICATION_SETTINGS_COLLABORATORS: The right to view and edit application collaborators.\n - RIGHT_APPLICATION_SETTINGS_PACKAGES: The right to view and edit application packages and associations.\n - RIGHT_APPLICATION_DELETE: The right to delete application.\n - RIGHT_APPLICATION_PURGE: The right to purge application.\n - RIGHT_APPLICATION_DEVICES_READ: The right to view devices in application.\n - RIGHT_APPLICATION_DEVICES_WRITE: The right to create devices in application.\n - RIGHT_APPLICATION_DEVICES_READ_KEYS: The right to view device keys in application.\nNote that keys may not be stored in a way that supports viewing them.\n - RIGHT_APPLICATION_DEVICES_WRITE_KEYS: The right to edit device keys in application.\n - RIGHT_APPLICATION_TRAFFIC_READ: The right to read application traffic (uplink and downlink).\n - RIGHT_APPLICATION_TRAFFIC_UP_WRITE: The right to write uplink application traffic.\n - RIGHT_APPLICATION_TRAFFIC_DOWN_WRITE: The right to write downlink application traffic.\n - RIGHT_APPLICATION_LINK: The right to link as Application to a Network Server for traffic exchange,\ni.e. read uplink and write downlink (API keys only).\nThis right is typically only given to an Application Server.\nThis right implies RIGHT_APPLICATION_INFO, RIGHT_APPLICATION_TRAFFIC_READ,\nand RIGHT_APPLICATION_TRAFFIC_DOWN_WRITE.\n - RIGHT_APPLICATION_ALL: The pseudo-right for all (current and future) application rights.\n - RIGHT_CLIENT_ALL: The pseudo-right for all (current and future) OAuth client rights.\n - RIGHT_CLIENT_INFO: The right to read client information.\n - RIGHT_CLIENT_SETTINGS_BASIC: The right to edit basic client settings.\n - RIGHT_CLIENT_SETTINGS_COLLABORATORS: The right to view and edit client collaborators.\n - RIGHT_CLIENT_DELETE: The right to delete a client.\n - RIGHT_CLIENT_PURGE: The right to purge a client.\n - RIGHT_GATEWAY_INFO: The right to view gateway information.\n - RIGHT_GATEWAY_SETTINGS_BASIC: The right to edit basic gateway settings.\n - RIGHT_GATEWAY_SETTINGS_API_KEYS: The right to view and edit gateway API keys.\n - RIGHT_GATEWAY_SETTINGS_COLLABORATORS: The right to view and edit gateway collaborators.\n - RIGHT_GATEWAY_DELETE: The right to delete gateway.\n - RIGHT_GATEWAY_PURGE: The right to purge gateway.\n - RIGHT_GATEWAY_TRAFFIC_READ: The right to read gateway traffic.\n - RIGHT_GATEWAY_TRAFFIC_DOWN_WRITE: The right to write downlink gateway traffic.\n - RIGHT_GATEWAY_LINK: The right to link as Gateway to a Gateway Server for traffic exchange,\ni.e. write uplink and read downlink (API keys only)\nThis right is typically only given to a gateway.\nThis right implies RIGHT_GATEWAY_INFO.\n - RIGHT_GATEWAY_STATUS_READ: The right to view gateway status.\n - RIGHT_GATEWAY_LOCATION_READ: The right to view view gateway location.\n - RIGHT_GATEWAY_WRITE_SECRETS: The right to store secrets associated with this gateway.\n - RIGHT_GATEWAY_READ_SECRETS: The right to retrieve secrets associated with this gateway.\n - RIGHT_GATEWAY_ALL: The pseudo-right for all (current and future) gateway rights.\n - RIGHT_ORGANIZATION_INFO: The right to view organization information.\n - RIGHT_ORGANIZATION_SETTINGS_BASIC: The right to edit basic organization settings.\n - RIGHT_ORGANIZATION_SETTINGS_API_KEYS: The right to view and edit organization API keys.\n - RIGHT_ORGANIZATION_SETTINGS_MEMBERS: The right to view and edit organization members.\n - RIGHT_ORGANIZATION_DELETE: The right to delete organization.\n - RIGHT_ORGANIZATION_PURGE: The right to purge organization.\n - RIGHT_ORGANIZATION_APPLICATIONS_LIST: The right to list the applications the organization is a collaborator of.\n - RIGHT_ORGANIZATION_APPLICATIONS_CREATE: The right to create an application under the organization.\n - RIGHT_ORGANIZATION_GATEWAYS_LIST: The right to list the gateways the organization is a collaborator of.\n - RIGHT_ORGANIZATION_GATEWAYS_CREATE: The right to create a gateway under the organization.\n - RIGHT_ORGANIZATION_CLIENTS_LIST: The right to list the OAuth clients the organization is a collaborator of.\n - RIGHT_ORGANIZATION_CLIENTS_CREATE: The right to create an OAuth client under the organization.\n - RIGHT_ORGANIZATION_ADD_AS_COLLABORATOR: The right to add the organization as a collaborator on an existing entity.\n - RIGHT_ORGANIZATION_ALL: The pseudo-right for all (current and future) organization rights.\n - RIGHT_SEND_INVITES: The right to send invites to new users.\nNote that this is not prefixed with \"USER_\"; it is not a right on the user entity.\n - RIGHT_ALL: The pseudo-right for all (current and future) possible rights." + "description": "Right is the enum that defines all the different rights to do something in the network.\n\n - RIGHT_USER_INFO: The right to view user information.\n - RIGHT_USER_SETTINGS_BASIC: The right to edit basic user settings.\n - RIGHT_USER_LIST: The right to list users accounts.\n - RIGHT_USER_CREATE: The right to create an user account.\n - RIGHT_USER_SETTINGS_API_KEYS: The right to view and edit user API keys.\n - RIGHT_USER_DELETE: The right to delete user account.\n - RIGHT_USER_PURGE: The right to delete user account.\n - RIGHT_USER_AUTHORIZED_CLIENTS: The right to view and edit authorized OAuth clients of the user.\n - RIGHT_USER_APPLICATIONS_LIST: The right to list applications the user is a collaborator of.\n - RIGHT_USER_APPLICATIONS_CREATE: The right to create an application under the user account.\n - RIGHT_USER_GATEWAYS_LIST: The right to list gateways the user is a collaborator of.\n - RIGHT_USER_GATEWAYS_CREATE: The right to create a gateway under the account of the user.\n - RIGHT_USER_CLIENTS_LIST: The right to list OAuth clients the user is a collaborator of.\n - RIGHT_USER_CLIENTS_CREATE: The right to create an OAuth client under the account of the user.\n - RIGHT_USER_ORGANIZATIONS_LIST: The right to list organizations the user is a member of.\n - RIGHT_USER_ORGANIZATIONS_CREATE: The right to create an organization under the user account.\n - RIGHT_USER_NOTIFICATIONS_READ: The right to read notifications sent to the user.\n - RIGHT_USER_ALL: The pseudo-right for all (current and future) user rights.\n - RIGHT_APPLICATION_INFO: The right to view application information.\n - RIGHT_APPLICATION_SETTINGS_BASIC: The right to edit basic application settings.\n - RIGHT_APPLICATION_SETTINGS_API_KEYS: The right to view and edit application API keys.\n - RIGHT_APPLICATION_SETTINGS_COLLABORATORS: The right to view and edit application collaborators.\n - RIGHT_APPLICATION_SETTINGS_PACKAGES: The right to view and edit application packages and associations.\n - RIGHT_APPLICATION_DELETE: The right to delete application.\n - RIGHT_APPLICATION_PURGE: The right to purge application.\n - RIGHT_APPLICATION_DEVICES_READ: The right to view devices in application.\n - RIGHT_APPLICATION_DEVICES_WRITE: The right to create devices in application.\n - RIGHT_APPLICATION_DEVICES_READ_KEYS: The right to view device keys in application.\nNote that keys may not be stored in a way that supports viewing them.\n - RIGHT_APPLICATION_DEVICES_WRITE_KEYS: The right to edit device keys in application.\n - RIGHT_APPLICATION_TRAFFIC_READ: The right to read application traffic (uplink and downlink).\n - RIGHT_APPLICATION_TRAFFIC_UP_WRITE: The right to write uplink application traffic.\n - RIGHT_APPLICATION_TRAFFIC_DOWN_WRITE: The right to write downlink application traffic.\n - RIGHT_APPLICATION_LINK: The right to link as Application to a Network Server for traffic exchange,\ni.e. read uplink and write downlink (API keys only).\nThis right is typically only given to an Application Server.\nThis right implies RIGHT_APPLICATION_INFO, RIGHT_APPLICATION_TRAFFIC_READ,\nand RIGHT_APPLICATION_TRAFFIC_DOWN_WRITE.\n - RIGHT_APPLICATION_ALL: The pseudo-right for all (current and future) application rights.\n - RIGHT_CLIENT_ALL: The pseudo-right for all (current and future) OAuth client rights.\n - RIGHT_CLIENT_INFO: The right to read client information.\n - RIGHT_CLIENT_SETTINGS_BASIC: The right to edit basic client settings.\n - RIGHT_CLIENT_SETTINGS_COLLABORATORS: The right to view and edit client collaborators.\n - RIGHT_CLIENT_DELETE: The right to delete a client.\n - RIGHT_CLIENT_PURGE: The right to purge a client.\n - RIGHT_GATEWAY_INFO: The right to view gateway information.\n - RIGHT_GATEWAY_SETTINGS_BASIC: The right to edit basic gateway settings.\n - RIGHT_GATEWAY_SETTINGS_API_KEYS: The right to view and edit gateway API keys.\n - RIGHT_GATEWAY_SETTINGS_COLLABORATORS: The right to view and edit gateway collaborators.\n - RIGHT_GATEWAY_DELETE: The right to delete gateway.\n - RIGHT_GATEWAY_PURGE: The right to purge gateway.\n - RIGHT_GATEWAY_TRAFFIC_READ: The right to read gateway traffic.\n - RIGHT_GATEWAY_TRAFFIC_DOWN_WRITE: The right to write downlink gateway traffic.\n - RIGHT_GATEWAY_LINK: The right to link as Gateway to a Gateway Server for traffic exchange,\ni.e. write uplink and read downlink (API keys only)\nThis right is typically only given to a gateway.\nThis right implies RIGHT_GATEWAY_INFO.\n - RIGHT_GATEWAY_STATUS_READ: The right to view gateway status.\n - RIGHT_GATEWAY_LOCATION_READ: The right to view view gateway location.\n - RIGHT_GATEWAY_WRITE_SECRETS: The right to store secrets associated with this gateway.\n - RIGHT_GATEWAY_READ_SECRETS: The right to retrieve secrets associated with this gateway.\n - RIGHT_GATEWAY_ALL: The pseudo-right for all (current and future) gateway rights.\n - RIGHT_ORGANIZATION_INFO: The right to view organization information.\n - RIGHT_ORGANIZATION_SETTINGS_BASIC: The right to edit basic organization settings.\n - RIGHT_ORGANIZATION_SETTINGS_API_KEYS: The right to view and edit organization API keys.\n - RIGHT_ORGANIZATION_SETTINGS_MEMBERS: The right to view and edit organization members.\n - RIGHT_ORGANIZATION_DELETE: The right to delete organization.\n - RIGHT_ORGANIZATION_PURGE: The right to purge organization.\n - RIGHT_ORGANIZATION_APPLICATIONS_LIST: The right to list the applications the organization is a collaborator of.\n - RIGHT_ORGANIZATION_APPLICATIONS_CREATE: The right to create an application under the organization.\n - RIGHT_ORGANIZATION_GATEWAYS_LIST: The right to list the gateways the organization is a collaborator of.\n - RIGHT_ORGANIZATION_GATEWAYS_CREATE: The right to create a gateway under the organization.\n - RIGHT_ORGANIZATION_CLIENTS_LIST: The right to list the OAuth clients the organization is a collaborator of.\n - RIGHT_ORGANIZATION_CLIENTS_CREATE: The right to create an OAuth client under the organization.\n - RIGHT_ORGANIZATION_ADD_AS_COLLABORATOR: The right to add the organization as a collaborator on an existing entity.\n - RIGHT_ORGANIZATION_ALL: The pseudo-right for all (current and future) organization rights.\n - RIGHT_SEND_INVITES: The right to send invites to new users.\nNote that this is not prefixed with \"USER_\"; it is not a right on the user entity.\n - RIGHT_ALL: The pseudo-right for all (current and future) possible rights." }, "v3Rights": { "type": "object", diff --git a/api/ttn/lorawan/v3/rights.proto b/api/ttn/lorawan/v3/rights.proto index 085e5dedce..2c0036adec 100644 --- a/api/ttn/lorawan/v3/rights.proto +++ b/api/ttn/lorawan/v3/rights.proto @@ -37,6 +37,10 @@ enum Right { RIGHT_USER_INFO = 1; // The right to edit basic user settings. RIGHT_USER_SETTINGS_BASIC = 2; + // The right to list users accounts. + RIGHT_USER_LIST = 87; + // The right to create an user account. + RIGHT_USER_CREATE = 88; // The right to view and edit user API keys. RIGHT_USER_SETTINGS_API_KEYS = 3; // The right to delete user account. @@ -204,7 +208,7 @@ enum Right { // The pseudo-right for all (current and future) possible rights. RIGHT_ALL = 55; - // Next value: 87 + // Next value: 89 } message Rights { diff --git a/pkg/ttnpb/rights.pb.go b/pkg/ttnpb/rights.pb.go index daae1a8b46..7af2a2a0de 100644 --- a/pkg/ttnpb/rights.pb.go +++ b/pkg/ttnpb/rights.pb.go @@ -47,6 +47,10 @@ const ( Right_RIGHT_USER_INFO Right = 1 // The right to edit basic user settings. Right_RIGHT_USER_SETTINGS_BASIC Right = 2 + // The right to list users accounts. + Right_RIGHT_USER_LIST Right = 87 + // The right to create an user account. + Right_RIGHT_USER_CREATE Right = 88 // The right to view and edit user API keys. Right_RIGHT_USER_SETTINGS_API_KEYS Right = 3 // The right to delete user account. @@ -196,6 +200,8 @@ var ( 0: "right_invalid", 1: "RIGHT_USER_INFO", 2: "RIGHT_USER_SETTINGS_BASIC", + 87: "RIGHT_USER_LIST", + 88: "RIGHT_USER_CREATE", 3: "RIGHT_USER_SETTINGS_API_KEYS", 4: "RIGHT_USER_DELETE", 66: "RIGHT_USER_PURGE", @@ -267,6 +273,8 @@ var ( "right_invalid": 0, "RIGHT_USER_INFO": 1, "RIGHT_USER_SETTINGS_BASIC": 2, + "RIGHT_USER_LIST": 87, + "RIGHT_USER_CREATE": 88, "RIGHT_USER_SETTINGS_API_KEYS": 3, "RIGHT_USER_DELETE": 4, "RIGHT_USER_PURGE": 66, @@ -786,160 +794,163 @@ var file_ttn_lorawan_v3_rights_proto_rawDesc = []byte{ 0x61, 0x62, 0x6f, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x43, 0x6f, 0x6c, 0x6c, 0x61, 0x62, 0x6f, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x0d, 0x63, - 0x6f, 0x6c, 0x6c, 0x61, 0x62, 0x6f, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x2a, 0xcd, 0x12, 0x0a, + 0x6f, 0x6c, 0x6c, 0x61, 0x62, 0x6f, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x2a, 0xf9, 0x12, 0x0a, 0x05, 0x52, 0x69, 0x67, 0x68, 0x74, 0x12, 0x11, 0x0a, 0x0d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x5f, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x01, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x53, 0x45, 0x54, - 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x42, 0x41, 0x53, 0x49, 0x43, 0x10, 0x02, 0x12, 0x20, 0x0a, - 0x1c, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x53, 0x45, 0x54, 0x54, - 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x41, 0x50, 0x49, 0x5f, 0x4b, 0x45, 0x59, 0x53, 0x10, 0x03, 0x12, - 0x15, 0x0a, 0x11, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x44, 0x45, - 0x4c, 0x45, 0x54, 0x45, 0x10, 0x04, 0x12, 0x14, 0x0a, 0x10, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, - 0x55, 0x53, 0x45, 0x52, 0x5f, 0x50, 0x55, 0x52, 0x47, 0x45, 0x10, 0x42, 0x12, 0x21, 0x0a, 0x1d, - 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x41, 0x55, 0x54, 0x48, 0x4f, - 0x52, 0x49, 0x5a, 0x45, 0x44, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x53, 0x10, 0x05, 0x12, - 0x20, 0x0a, 0x1c, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x41, 0x50, - 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, - 0x06, 0x12, 0x22, 0x0a, 0x1e, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, - 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x5f, 0x43, 0x52, 0x45, - 0x41, 0x54, 0x45, 0x10, 0x07, 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x55, - 0x53, 0x45, 0x52, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x53, 0x5f, 0x4c, 0x49, 0x53, - 0x54, 0x10, 0x08, 0x12, 0x1e, 0x0a, 0x1a, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, - 0x52, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x53, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, - 0x45, 0x10, 0x09, 0x12, 0x1b, 0x0a, 0x17, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, - 0x52, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x53, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x0a, - 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x43, - 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x53, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, 0x0b, 0x12, - 0x21, 0x0a, 0x1d, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x4f, 0x52, - 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x5f, 0x4c, 0x49, 0x53, 0x54, - 0x10, 0x0c, 0x12, 0x23, 0x0a, 0x1f, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x52, - 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x5f, 0x43, - 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, 0x0d, 0x12, 0x21, 0x0a, 0x1d, 0x52, 0x49, 0x47, 0x48, 0x54, - 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x4e, 0x4f, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x49, - 0x4f, 0x4e, 0x53, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x10, 0x3b, 0x12, 0x12, 0x0a, 0x0e, 0x52, 0x49, - 0x47, 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x41, 0x4c, 0x4c, 0x10, 0x0e, 0x12, 0x1a, - 0x0a, 0x16, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, - 0x49, 0x4f, 0x4e, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x0f, 0x12, 0x24, 0x0a, 0x20, 0x52, 0x49, + 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x42, 0x41, 0x53, 0x49, 0x43, 0x10, 0x02, 0x12, 0x13, 0x0a, + 0x0f, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x4c, 0x49, 0x53, 0x54, + 0x10, 0x57, 0x12, 0x15, 0x0a, 0x11, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x52, + 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, 0x58, 0x12, 0x20, 0x0a, 0x1c, 0x52, 0x49, 0x47, + 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, + 0x5f, 0x41, 0x50, 0x49, 0x5f, 0x4b, 0x45, 0x59, 0x53, 0x10, 0x03, 0x12, 0x15, 0x0a, 0x11, 0x52, + 0x49, 0x47, 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, + 0x10, 0x04, 0x12, 0x14, 0x0a, 0x10, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x52, + 0x5f, 0x50, 0x55, 0x52, 0x47, 0x45, 0x10, 0x42, 0x12, 0x21, 0x0a, 0x1d, 0x52, 0x49, 0x47, 0x48, + 0x54, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x41, 0x55, 0x54, 0x48, 0x4f, 0x52, 0x49, 0x5a, 0x45, + 0x44, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x53, 0x10, 0x05, 0x12, 0x20, 0x0a, 0x1c, 0x52, + 0x49, 0x47, 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, + 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x06, 0x12, 0x22, 0x0a, + 0x1e, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x41, 0x50, 0x50, 0x4c, + 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, + 0x07, 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, + 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x53, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x08, 0x12, + 0x1e, 0x0a, 0x1a, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x47, 0x41, + 0x54, 0x45, 0x57, 0x41, 0x59, 0x53, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, 0x09, 0x12, + 0x1b, 0x0a, 0x17, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x43, 0x4c, + 0x49, 0x45, 0x4e, 0x54, 0x53, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x0a, 0x12, 0x1d, 0x0a, 0x19, + 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, + 0x54, 0x53, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, 0x0b, 0x12, 0x21, 0x0a, 0x1d, 0x52, + 0x49, 0x47, 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, + 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x0c, 0x12, 0x23, + 0x0a, 0x1f, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x4f, 0x52, 0x47, + 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, + 0x45, 0x10, 0x0d, 0x12, 0x21, 0x0a, 0x1d, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x55, 0x53, 0x45, + 0x52, 0x5f, 0x4e, 0x4f, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x5f, + 0x52, 0x45, 0x41, 0x44, 0x10, 0x3b, 0x12, 0x12, 0x0a, 0x0e, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, + 0x55, 0x53, 0x45, 0x52, 0x5f, 0x41, 0x4c, 0x4c, 0x10, 0x0e, 0x12, 0x1a, 0x0a, 0x16, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, - 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x42, 0x41, 0x53, 0x49, 0x43, 0x10, 0x10, - 0x12, 0x27, 0x0a, 0x23, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, - 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x41, - 0x50, 0x49, 0x5f, 0x4b, 0x45, 0x59, 0x53, 0x10, 0x11, 0x12, 0x2c, 0x0a, 0x28, 0x52, 0x49, 0x47, - 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, - 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x43, 0x4f, 0x4c, 0x4c, 0x41, 0x42, 0x4f, 0x52, - 0x41, 0x54, 0x4f, 0x52, 0x53, 0x10, 0x12, 0x12, 0x27, 0x0a, 0x23, 0x52, 0x49, 0x47, 0x48, 0x54, - 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x45, 0x54, - 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x50, 0x41, 0x43, 0x4b, 0x41, 0x47, 0x45, 0x53, 0x10, 0x38, - 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, - 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x13, 0x12, 0x1b, - 0x0a, 0x17, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, - 0x49, 0x4f, 0x4e, 0x5f, 0x50, 0x55, 0x52, 0x47, 0x45, 0x10, 0x40, 0x12, 0x22, 0x0a, 0x1e, 0x52, - 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, - 0x5f, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x53, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x10, 0x14, 0x12, - 0x23, 0x0a, 0x1f, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, - 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x53, 0x5f, 0x57, 0x52, 0x49, - 0x54, 0x45, 0x10, 0x15, 0x12, 0x27, 0x0a, 0x23, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x50, - 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, - 0x53, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x4b, 0x45, 0x59, 0x53, 0x10, 0x16, 0x12, 0x28, 0x0a, - 0x24, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, - 0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x53, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, - 0x5f, 0x4b, 0x45, 0x59, 0x53, 0x10, 0x17, 0x12, 0x22, 0x0a, 0x1e, 0x52, 0x49, 0x47, 0x48, 0x54, - 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x54, 0x52, 0x41, - 0x46, 0x46, 0x49, 0x43, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x10, 0x18, 0x12, 0x26, 0x0a, 0x22, 0x52, + 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x0f, 0x12, 0x24, 0x0a, 0x20, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, + 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x45, 0x54, 0x54, + 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x42, 0x41, 0x53, 0x49, 0x43, 0x10, 0x10, 0x12, 0x27, 0x0a, 0x23, + 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, + 0x4e, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x41, 0x50, 0x49, 0x5f, 0x4b, + 0x45, 0x59, 0x53, 0x10, 0x11, 0x12, 0x2c, 0x0a, 0x28, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, + 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, + 0x4e, 0x47, 0x53, 0x5f, 0x43, 0x4f, 0x4c, 0x4c, 0x41, 0x42, 0x4f, 0x52, 0x41, 0x54, 0x4f, 0x52, + 0x53, 0x10, 0x12, 0x12, 0x27, 0x0a, 0x23, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, + 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, + 0x53, 0x5f, 0x50, 0x41, 0x43, 0x4b, 0x41, 0x47, 0x45, 0x53, 0x10, 0x38, 0x12, 0x1c, 0x0a, 0x18, + 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, + 0x4e, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x13, 0x12, 0x1b, 0x0a, 0x17, 0x52, 0x49, + 0x47, 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, + 0x50, 0x55, 0x52, 0x47, 0x45, 0x10, 0x40, 0x12, 0x22, 0x0a, 0x1e, 0x52, 0x49, 0x47, 0x48, 0x54, + 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x56, + 0x49, 0x43, 0x45, 0x53, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x10, 0x14, 0x12, 0x23, 0x0a, 0x1f, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, - 0x5f, 0x54, 0x52, 0x41, 0x46, 0x46, 0x49, 0x43, 0x5f, 0x55, 0x50, 0x5f, 0x57, 0x52, 0x49, 0x54, - 0x45, 0x10, 0x19, 0x12, 0x28, 0x0a, 0x24, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, + 0x5f, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x53, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x10, 0x15, + 0x12, 0x27, 0x0a, 0x23, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, + 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x53, 0x5f, 0x52, 0x45, + 0x41, 0x44, 0x5f, 0x4b, 0x45, 0x59, 0x53, 0x10, 0x16, 0x12, 0x28, 0x0a, 0x24, 0x52, 0x49, 0x47, + 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x44, + 0x45, 0x56, 0x49, 0x43, 0x45, 0x53, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x5f, 0x4b, 0x45, 0x59, + 0x53, 0x10, 0x17, 0x12, 0x22, 0x0a, 0x1e, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x54, 0x52, 0x41, 0x46, 0x46, 0x49, 0x43, - 0x5f, 0x44, 0x4f, 0x57, 0x4e, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x10, 0x1a, 0x12, 0x1a, 0x0a, - 0x16, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, - 0x4f, 0x4e, 0x5f, 0x4c, 0x49, 0x4e, 0x4b, 0x10, 0x1b, 0x12, 0x19, 0x0a, 0x15, 0x52, 0x49, 0x47, - 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x41, - 0x4c, 0x4c, 0x10, 0x1c, 0x12, 0x14, 0x0a, 0x10, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x43, 0x4c, - 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x41, 0x4c, 0x4c, 0x10, 0x1d, 0x12, 0x15, 0x0a, 0x11, 0x52, 0x49, - 0x47, 0x48, 0x54, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x10, - 0x3c, 0x12, 0x1f, 0x0a, 0x1b, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, - 0x54, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x42, 0x41, 0x53, 0x49, 0x43, - 0x10, 0x3d, 0x12, 0x27, 0x0a, 0x23, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x43, 0x4c, 0x49, 0x45, - 0x4e, 0x54, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x43, 0x4f, 0x4c, 0x4c, - 0x41, 0x42, 0x4f, 0x52, 0x41, 0x54, 0x4f, 0x52, 0x53, 0x10, 0x3e, 0x12, 0x17, 0x0a, 0x13, 0x52, - 0x49, 0x47, 0x48, 0x54, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x44, 0x45, 0x4c, 0x45, - 0x54, 0x45, 0x10, 0x3f, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x43, 0x4c, - 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x50, 0x55, 0x52, 0x47, 0x45, 0x10, 0x44, 0x12, 0x16, 0x0a, 0x12, - 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x49, 0x4e, - 0x46, 0x4f, 0x10, 0x1e, 0x12, 0x20, 0x0a, 0x1c, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, - 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x42, - 0x41, 0x53, 0x49, 0x43, 0x10, 0x1f, 0x12, 0x23, 0x0a, 0x1f, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, - 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, - 0x5f, 0x41, 0x50, 0x49, 0x5f, 0x4b, 0x45, 0x59, 0x53, 0x10, 0x20, 0x12, 0x28, 0x0a, 0x24, 0x52, - 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x53, 0x45, 0x54, - 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x43, 0x4f, 0x4c, 0x4c, 0x41, 0x42, 0x4f, 0x52, 0x41, 0x54, - 0x4f, 0x52, 0x53, 0x10, 0x21, 0x12, 0x18, 0x0a, 0x14, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, - 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x22, 0x12, - 0x17, 0x0a, 0x13, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, - 0x5f, 0x50, 0x55, 0x52, 0x47, 0x45, 0x10, 0x43, 0x12, 0x1e, 0x0a, 0x1a, 0x52, 0x49, 0x47, 0x48, - 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x54, 0x52, 0x41, 0x46, 0x46, 0x49, - 0x43, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x10, 0x23, 0x12, 0x24, 0x0a, 0x20, 0x52, 0x49, 0x47, 0x48, - 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x54, 0x52, 0x41, 0x46, 0x46, 0x49, - 0x43, 0x5f, 0x44, 0x4f, 0x57, 0x4e, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x10, 0x24, 0x12, 0x16, - 0x0a, 0x12, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, - 0x4c, 0x49, 0x4e, 0x4b, 0x10, 0x25, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, - 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, - 0x45, 0x41, 0x44, 0x10, 0x26, 0x12, 0x1f, 0x0a, 0x1b, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, - 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x4c, 0x4f, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, - 0x52, 0x45, 0x41, 0x44, 0x10, 0x27, 0x12, 0x1f, 0x0a, 0x1b, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, - 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x5f, 0x53, 0x45, - 0x43, 0x52, 0x45, 0x54, 0x53, 0x10, 0x39, 0x12, 0x1e, 0x0a, 0x1a, 0x52, 0x49, 0x47, 0x48, 0x54, - 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x53, 0x45, - 0x43, 0x52, 0x45, 0x54, 0x53, 0x10, 0x3a, 0x12, 0x15, 0x0a, 0x11, 0x52, 0x49, 0x47, 0x48, 0x54, - 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x41, 0x4c, 0x4c, 0x10, 0x28, 0x12, 0x1b, - 0x0a, 0x17, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, - 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x29, 0x12, 0x25, 0x0a, 0x21, 0x52, - 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, - 0x4e, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x42, 0x41, 0x53, 0x49, 0x43, - 0x10, 0x2a, 0x12, 0x28, 0x0a, 0x24, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, - 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, - 0x53, 0x5f, 0x41, 0x50, 0x49, 0x5f, 0x4b, 0x45, 0x59, 0x53, 0x10, 0x2b, 0x12, 0x27, 0x0a, 0x23, - 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, - 0x4f, 0x4e, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x4d, 0x45, 0x4d, 0x42, - 0x45, 0x52, 0x53, 0x10, 0x2c, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, - 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x4c, 0x45, - 0x54, 0x45, 0x10, 0x2d, 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, - 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x50, 0x55, 0x52, 0x47, 0x45, - 0x10, 0x41, 0x12, 0x28, 0x0a, 0x24, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, - 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, - 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x2e, 0x12, 0x2a, 0x0a, 0x26, - 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, - 0x4f, 0x4e, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x5f, - 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, 0x2f, 0x12, 0x24, 0x0a, 0x20, 0x52, 0x49, 0x47, 0x48, - 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x47, - 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x53, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x30, 0x12, 0x26, - 0x0a, 0x22, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, - 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x53, 0x5f, 0x43, 0x52, - 0x45, 0x41, 0x54, 0x45, 0x10, 0x31, 0x12, 0x23, 0x0a, 0x1f, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, - 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x43, 0x4c, 0x49, - 0x45, 0x4e, 0x54, 0x53, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x32, 0x12, 0x25, 0x0a, 0x21, 0x52, - 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, - 0x4e, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x53, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, - 0x10, 0x33, 0x12, 0x2a, 0x0a, 0x26, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, - 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x44, 0x44, 0x5f, 0x41, 0x53, 0x5f, - 0x43, 0x4f, 0x4c, 0x4c, 0x41, 0x42, 0x4f, 0x52, 0x41, 0x54, 0x4f, 0x52, 0x10, 0x34, 0x12, 0x1a, - 0x0a, 0x16, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, - 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x4c, 0x4c, 0x10, 0x35, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x49, - 0x47, 0x48, 0x54, 0x5f, 0x53, 0x45, 0x4e, 0x44, 0x5f, 0x49, 0x4e, 0x56, 0x49, 0x54, 0x45, 0x53, - 0x10, 0x36, 0x12, 0x0d, 0x0a, 0x09, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x4c, 0x4c, 0x10, - 0x37, 0x1a, 0x0d, 0xea, 0xaa, 0x19, 0x09, 0x18, 0x01, 0x2a, 0x05, 0x52, 0x49, 0x47, 0x48, 0x54, - 0x22, 0x04, 0x08, 0x45, 0x10, 0x45, 0x22, 0x04, 0x08, 0x46, 0x10, 0x46, 0x22, 0x04, 0x08, 0x47, - 0x10, 0x47, 0x22, 0x04, 0x08, 0x48, 0x10, 0x48, 0x22, 0x04, 0x08, 0x49, 0x10, 0x49, 0x22, 0x04, - 0x08, 0x4a, 0x10, 0x4a, 0x22, 0x04, 0x08, 0x4b, 0x10, 0x4b, 0x22, 0x04, 0x08, 0x4c, 0x10, 0x4c, - 0x22, 0x04, 0x08, 0x4d, 0x10, 0x4d, 0x22, 0x04, 0x08, 0x4e, 0x10, 0x4e, 0x22, 0x04, 0x08, 0x4f, - 0x10, 0x4f, 0x22, 0x04, 0x08, 0x50, 0x10, 0x50, 0x22, 0x04, 0x08, 0x51, 0x10, 0x51, 0x22, 0x04, - 0x08, 0x52, 0x10, 0x52, 0x22, 0x04, 0x08, 0x53, 0x10, 0x53, 0x22, 0x04, 0x08, 0x54, 0x10, 0x54, - 0x22, 0x04, 0x08, 0x55, 0x10, 0x55, 0x22, 0x04, 0x08, 0x56, 0x10, 0x56, 0x42, 0x31, 0x5a, 0x2f, - 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, - 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, - 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x74, 0x6e, 0x70, 0x62, 0x62, - 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x5f, 0x52, 0x45, 0x41, 0x44, 0x10, 0x18, 0x12, 0x26, 0x0a, 0x22, 0x52, 0x49, 0x47, 0x48, 0x54, + 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x54, 0x52, 0x41, + 0x46, 0x46, 0x49, 0x43, 0x5f, 0x55, 0x50, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x10, 0x19, 0x12, + 0x28, 0x0a, 0x24, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, + 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x54, 0x52, 0x41, 0x46, 0x46, 0x49, 0x43, 0x5f, 0x44, 0x4f, 0x57, + 0x4e, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x10, 0x1a, 0x12, 0x1a, 0x0a, 0x16, 0x52, 0x49, 0x47, + 0x48, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4c, + 0x49, 0x4e, 0x4b, 0x10, 0x1b, 0x12, 0x19, 0x0a, 0x15, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, + 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x4c, 0x4c, 0x10, 0x1c, + 0x12, 0x14, 0x0a, 0x10, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, + 0x5f, 0x41, 0x4c, 0x4c, 0x10, 0x1d, 0x12, 0x15, 0x0a, 0x11, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, + 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x3c, 0x12, 0x1f, 0x0a, + 0x1b, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x53, 0x45, + 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x42, 0x41, 0x53, 0x49, 0x43, 0x10, 0x3d, 0x12, 0x27, + 0x0a, 0x23, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x53, + 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x43, 0x4f, 0x4c, 0x4c, 0x41, 0x42, 0x4f, 0x52, + 0x41, 0x54, 0x4f, 0x52, 0x53, 0x10, 0x3e, 0x12, 0x17, 0x0a, 0x13, 0x52, 0x49, 0x47, 0x48, 0x54, + 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x3f, + 0x12, 0x16, 0x0a, 0x12, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, + 0x5f, 0x50, 0x55, 0x52, 0x47, 0x45, 0x10, 0x44, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x49, 0x47, 0x48, + 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x1e, + 0x12, 0x20, 0x0a, 0x1c, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, + 0x59, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x42, 0x41, 0x53, 0x49, 0x43, + 0x10, 0x1f, 0x12, 0x23, 0x0a, 0x1f, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, + 0x57, 0x41, 0x59, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x41, 0x50, 0x49, + 0x5f, 0x4b, 0x45, 0x59, 0x53, 0x10, 0x20, 0x12, 0x28, 0x0a, 0x24, 0x52, 0x49, 0x47, 0x48, 0x54, + 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, + 0x53, 0x5f, 0x43, 0x4f, 0x4c, 0x4c, 0x41, 0x42, 0x4f, 0x52, 0x41, 0x54, 0x4f, 0x52, 0x53, 0x10, + 0x21, 0x12, 0x18, 0x0a, 0x14, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, + 0x41, 0x59, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x22, 0x12, 0x17, 0x0a, 0x13, 0x52, + 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x50, 0x55, 0x52, + 0x47, 0x45, 0x10, 0x43, 0x12, 0x1e, 0x0a, 0x1a, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, + 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x54, 0x52, 0x41, 0x46, 0x46, 0x49, 0x43, 0x5f, 0x52, 0x45, + 0x41, 0x44, 0x10, 0x23, 0x12, 0x24, 0x0a, 0x20, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, + 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x54, 0x52, 0x41, 0x46, 0x46, 0x49, 0x43, 0x5f, 0x44, 0x4f, + 0x57, 0x4e, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x10, 0x24, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x49, + 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x4c, 0x49, 0x4e, 0x4b, + 0x10, 0x25, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, + 0x57, 0x41, 0x59, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x10, + 0x26, 0x12, 0x1f, 0x0a, 0x1b, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, + 0x41, 0x59, 0x5f, 0x4c, 0x4f, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x52, 0x45, 0x41, 0x44, + 0x10, 0x27, 0x12, 0x1f, 0x0a, 0x1b, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, 0x45, + 0x57, 0x41, 0x59, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x5f, 0x53, 0x45, 0x43, 0x52, 0x45, 0x54, + 0x53, 0x10, 0x39, 0x12, 0x1e, 0x0a, 0x1a, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, + 0x45, 0x57, 0x41, 0x59, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x53, 0x45, 0x43, 0x52, 0x45, 0x54, + 0x53, 0x10, 0x3a, 0x12, 0x15, 0x0a, 0x11, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x47, 0x41, 0x54, + 0x45, 0x57, 0x41, 0x59, 0x5f, 0x41, 0x4c, 0x4c, 0x10, 0x28, 0x12, 0x1b, 0x0a, 0x17, 0x52, 0x49, + 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, + 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x29, 0x12, 0x25, 0x0a, 0x21, 0x52, 0x49, 0x47, 0x48, 0x54, + 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x45, + 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x42, 0x41, 0x53, 0x49, 0x43, 0x10, 0x2a, 0x12, 0x28, + 0x0a, 0x24, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, + 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x41, 0x50, + 0x49, 0x5f, 0x4b, 0x45, 0x59, 0x53, 0x10, 0x2b, 0x12, 0x27, 0x0a, 0x23, 0x52, 0x49, 0x47, 0x48, + 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, + 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, 0x53, 0x10, + 0x2c, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, + 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x2d, + 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, + 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x50, 0x55, 0x52, 0x47, 0x45, 0x10, 0x41, 0x12, 0x28, + 0x0a, 0x24, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, + 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, + 0x53, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x2e, 0x12, 0x2a, 0x0a, 0x26, 0x52, 0x49, 0x47, 0x48, + 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x41, + 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x5f, 0x43, 0x52, 0x45, 0x41, + 0x54, 0x45, 0x10, 0x2f, 0x12, 0x24, 0x0a, 0x20, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, + 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, + 0x41, 0x59, 0x53, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x30, 0x12, 0x26, 0x0a, 0x22, 0x52, 0x49, + 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, + 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x53, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, + 0x10, 0x31, 0x12, 0x23, 0x0a, 0x1f, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, + 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x53, + 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x32, 0x12, 0x25, 0x0a, 0x21, 0x52, 0x49, 0x47, 0x48, 0x54, + 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x43, 0x4c, + 0x49, 0x45, 0x4e, 0x54, 0x53, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, 0x33, 0x12, 0x2a, + 0x0a, 0x26, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, + 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x44, 0x44, 0x5f, 0x41, 0x53, 0x5f, 0x43, 0x4f, 0x4c, 0x4c, + 0x41, 0x42, 0x4f, 0x52, 0x41, 0x54, 0x4f, 0x52, 0x10, 0x34, 0x12, 0x1a, 0x0a, 0x16, 0x52, 0x49, + 0x47, 0x48, 0x54, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, + 0x5f, 0x41, 0x4c, 0x4c, 0x10, 0x35, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, + 0x53, 0x45, 0x4e, 0x44, 0x5f, 0x49, 0x4e, 0x56, 0x49, 0x54, 0x45, 0x53, 0x10, 0x36, 0x12, 0x0d, + 0x0a, 0x09, 0x52, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x41, 0x4c, 0x4c, 0x10, 0x37, 0x1a, 0x0d, 0xea, + 0xaa, 0x19, 0x09, 0x18, 0x01, 0x2a, 0x05, 0x52, 0x49, 0x47, 0x48, 0x54, 0x22, 0x04, 0x08, 0x45, + 0x10, 0x45, 0x22, 0x04, 0x08, 0x46, 0x10, 0x46, 0x22, 0x04, 0x08, 0x47, 0x10, 0x47, 0x22, 0x04, + 0x08, 0x48, 0x10, 0x48, 0x22, 0x04, 0x08, 0x49, 0x10, 0x49, 0x22, 0x04, 0x08, 0x4a, 0x10, 0x4a, + 0x22, 0x04, 0x08, 0x4b, 0x10, 0x4b, 0x22, 0x04, 0x08, 0x4c, 0x10, 0x4c, 0x22, 0x04, 0x08, 0x4d, + 0x10, 0x4d, 0x22, 0x04, 0x08, 0x4e, 0x10, 0x4e, 0x22, 0x04, 0x08, 0x4f, 0x10, 0x4f, 0x22, 0x04, + 0x08, 0x50, 0x10, 0x50, 0x22, 0x04, 0x08, 0x51, 0x10, 0x51, 0x22, 0x04, 0x08, 0x52, 0x10, 0x52, + 0x22, 0x04, 0x08, 0x53, 0x10, 0x53, 0x22, 0x04, 0x08, 0x54, 0x10, 0x54, 0x22, 0x04, 0x08, 0x55, + 0x10, 0x55, 0x22, 0x04, 0x08, 0x56, 0x10, 0x56, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x6f, 0x2e, 0x74, + 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, + 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, + 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x74, 0x6e, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, } var ( diff --git a/pkg/ttnpb/rights_json.pb.go b/pkg/ttnpb/rights_json.pb.go index 00bc047e92..f4fbb3f88d 100644 --- a/pkg/ttnpb/rights_json.pb.go +++ b/pkg/ttnpb/rights_json.pb.go @@ -30,6 +30,8 @@ func (x Right) MarshalJSON() ([]byte, error) { var Right_customvalue = map[string]int32{ "USER_INFO": 1, "USER_SETTINGS_BASIC": 2, + "USER_LIST": 87, + "USER_CREATE": 88, "USER_SETTINGS_API_KEYS": 3, "USER_DELETE": 4, "USER_PURGE": 66, diff --git a/sdk/js/generated/api.json b/sdk/js/generated/api.json index 0d0a1eb47c..5ceb4fcecf 100644 --- a/sdk/js/generated/api.json +++ b/sdk/js/generated/api.json @@ -49729,6 +49729,16 @@ "number": "2", "description": "The right to edit basic user settings." }, + { + "name": "RIGHT_USER_LIST", + "number": "87", + "description": "The right to list users accounts." + }, + { + "name": "RIGHT_USER_CREATE", + "number": "88", + "description": "The right to create an user account." + }, { "name": "RIGHT_USER_SETTINGS_API_KEYS", "number": "3", From 7001e5bec9bd3e001cc2a072273bee0c53b6b84d Mon Sep 17 00:00:00 2001 From: Nicholas Cristofaro Date: Mon, 25 Nov 2024 11:57:16 -0300 Subject: [PATCH 20/40] is: Add rights validation for user registry --- pkg/identityserver/user_registry.go | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/pkg/identityserver/user_registry.go b/pkg/identityserver/user_registry.go index 22de9f7c98..12838a0aff 100644 --- a/pkg/identityserver/user_registry.go +++ b/pkg/identityserver/user_registry.go @@ -179,6 +179,20 @@ func (is *IdentityServer) createUser(ctx context.Context, req *ttnpb.CreateUserR createdByAdmin := is.IsAdmin(ctx) config := is.configFromContext(ctx) + if createdByAdmin { + authInfo, err := is.authInfo(ctx) + if err != nil { + return nil, err + } + if !ttnpb.RightsFrom(authInfo.GetRights()...).IncludesAll(ttnpb.Right_RIGHT_USER_CREATE) { + return nil, rights.ErrInsufficientRights.WithAttributes( + "uid", req.IDString(), + "entity_type", "user", + "missing", ttnpb.Right_RIGHT_ALL.String(), + ) + } + } + if err = blocklist.Check(ctx, req.User.GetIds().GetUserId()); err != nil { return nil, err } @@ -338,6 +352,18 @@ func (is *IdentityServer) listUsers(ctx context.Context, req *ttnpb.ListUsersReq if err = is.RequireAdmin(ctx); err != nil { return nil, err } + + authInfo, err := is.authInfo(ctx) + if err != nil { + return nil, err + } + if !ttnpb.RightsFrom(authInfo.GetRights()...).IncludesAll(ttnpb.Right_RIGHT_USER_LIST) { + return nil, rights.ErrInsufficientRights.WithAttributes( + "entity_type", "user", + "missing", ttnpb.Right_RIGHT_ALL.String(), + ) + } + contactInfoInPath := ttnpb.HasAnyField(req.FieldMask.GetPaths(), "contact_info") if contactInfoInPath { req.FieldMask.Paths = ttnpb.ExcludeFields(req.FieldMask.Paths, "contact_info") From 745a123db21d6694101956329fce2872eeb983f4 Mon Sep 17 00:00:00 2001 From: Nicholas Cristofaro Date: Mon, 25 Nov 2024 12:03:08 -0300 Subject: [PATCH 21/40] dev: Update RIGHTs related tests --- pkg/ttnpb/i18n.go | 7 +++++++ pkg/ttnpb/testdata/ttnpb_encoding_golden.md | 21 +++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/pkg/ttnpb/i18n.go b/pkg/ttnpb/i18n.go index 6c2b8d0296..63761a8156 100644 --- a/pkg/ttnpb/i18n.go +++ b/pkg/ttnpb/i18n.go @@ -113,8 +113,11 @@ func init() { defineEnum(Right_RIGHT_USER_INFO, "view user information") defineEnum(Right_RIGHT_USER_SETTINGS_BASIC, "edit basic user settings") + defineEnum(Right_RIGHT_USER_LIST, "list user accounts") + defineEnum(Right_RIGHT_USER_CREATE, "create user account") defineEnum(Right_RIGHT_USER_SETTINGS_API_KEYS, "view and edit user API keys") defineEnum(Right_RIGHT_USER_DELETE, "delete user account") + defineEnum(Right_RIGHT_USER_PURGE, "purge user account") defineEnum(Right_RIGHT_USER_AUTHORIZED_CLIENTS, "view and edit authorized OAuth clients of the user") defineEnum(Right_RIGHT_USER_APPLICATIONS_LIST, "list applications the user is a collaborator of") defineEnum(Right_RIGHT_USER_APPLICATIONS_CREATE, "create an application under the user account") @@ -133,6 +136,7 @@ func init() { defineEnum(Right_RIGHT_APPLICATION_SETTINGS_COLLABORATORS, "view and edit application collaborators") defineEnum(Right_RIGHT_APPLICATION_SETTINGS_PACKAGES, "view and edit application packages and associations") defineEnum(Right_RIGHT_APPLICATION_DELETE, "delete application") + defineEnum(Right_RIGHT_APPLICATION_PURGE, "purge application") defineEnum(Right_RIGHT_APPLICATION_DEVICES_READ, "view devices in application") defineEnum(Right_RIGHT_APPLICATION_DEVICES_WRITE, "create devices in application") defineEnum(Right_RIGHT_APPLICATION_DEVICES_READ_KEYS, "view device keys in application") @@ -148,12 +152,14 @@ func init() { defineEnum(Right_RIGHT_CLIENT_SETTINGS_BASIC, "edit OAuth client basic settings") defineEnum(Right_RIGHT_CLIENT_SETTINGS_COLLABORATORS, "view and edit OAuth client collaborators") defineEnum(Right_RIGHT_CLIENT_DELETE, "delete OAuth client") + defineEnum(Right_RIGHT_CLIENT_PURGE, "purge OAuth client") defineEnum(Right_RIGHT_GATEWAY_INFO, "view gateway information") defineEnum(Right_RIGHT_GATEWAY_SETTINGS_BASIC, "edit basic gateway settings") defineEnum(Right_RIGHT_GATEWAY_SETTINGS_API_KEYS, "view and edit gateway API keys") defineEnum(Right_RIGHT_GATEWAY_SETTINGS_COLLABORATORS, "view and edit gateway collaborators") defineEnum(Right_RIGHT_GATEWAY_DELETE, "delete gateway") + defineEnum(Right_RIGHT_GATEWAY_PURGE, "purge gateway") defineEnum(Right_RIGHT_GATEWAY_TRAFFIC_READ, "read gateway traffic") defineEnum(Right_RIGHT_GATEWAY_TRAFFIC_DOWN_WRITE, "write downlink gateway traffic") defineEnum(Right_RIGHT_GATEWAY_LINK, "link as Gateway to a Gateway Server for traffic exchange, i.e. write uplink and read downlink") @@ -168,6 +174,7 @@ func init() { defineEnum(Right_RIGHT_ORGANIZATION_SETTINGS_API_KEYS, "view and edit organization API keys") defineEnum(Right_RIGHT_ORGANIZATION_SETTINGS_MEMBERS, "view and edit organization members") defineEnum(Right_RIGHT_ORGANIZATION_DELETE, "delete organization") + defineEnum(Right_RIGHT_ORGANIZATION_PURGE, "purge organization") defineEnum(Right_RIGHT_ORGANIZATION_APPLICATIONS_LIST, "list the applications the organization is a collaborator of") defineEnum(Right_RIGHT_ORGANIZATION_APPLICATIONS_CREATE, "create an application under the organization") defineEnum(Right_RIGHT_ORGANIZATION_GATEWAYS_LIST, "list the gateways the organization is a collaborator of") diff --git a/pkg/ttnpb/testdata/ttnpb_encoding_golden.md b/pkg/ttnpb/testdata/ttnpb_encoding_golden.md index 4bb15def24..35fae9bf03 100644 --- a/pkg/ttnpb/testdata/ttnpb_encoding_golden.md +++ b/pkg/ttnpb/testdata/ttnpb_encoding_golden.md @@ -702,6 +702,7 @@ JSON | ttnpb.Right | RIGHT_APPLICATION_DEVICES_WRITE | "RIGHT_APPLICATION_DEVICE JSON | ttnpb.Right | RIGHT_APPLICATION_DEVICES_WRITE_KEYS | "RIGHT_APPLICATION_DEVICES_WRITE_KEYS" JSON | ttnpb.Right | RIGHT_APPLICATION_INFO | "RIGHT_APPLICATION_INFO" JSON | ttnpb.Right | RIGHT_APPLICATION_LINK | "RIGHT_APPLICATION_LINK" +JSON | ttnpb.Right | RIGHT_APPLICATION_PURGE | "RIGHT_APPLICATION_PURGE" JSON | ttnpb.Right | RIGHT_APPLICATION_SETTINGS_API_KEYS | "RIGHT_APPLICATION_SETTINGS_API_KEYS" JSON | ttnpb.Right | RIGHT_APPLICATION_SETTINGS_BASIC | "RIGHT_APPLICATION_SETTINGS_BASIC" JSON | ttnpb.Right | RIGHT_APPLICATION_SETTINGS_COLLABORATORS | "RIGHT_APPLICATION_SETTINGS_COLLABORATORS" @@ -712,6 +713,7 @@ JSON | ttnpb.Right | RIGHT_APPLICATION_TRAFFIC_UP_WRITE | "RIGHT_APPLICATION_TRA JSON | ttnpb.Right | RIGHT_CLIENT_ALL | "RIGHT_CLIENT_ALL" JSON | ttnpb.Right | RIGHT_CLIENT_DELETE | "RIGHT_CLIENT_DELETE" JSON | ttnpb.Right | RIGHT_CLIENT_INFO | "RIGHT_CLIENT_INFO" +JSON | ttnpb.Right | RIGHT_CLIENT_PURGE | "RIGHT_CLIENT_PURGE" JSON | ttnpb.Right | RIGHT_CLIENT_SETTINGS_BASIC | "RIGHT_CLIENT_SETTINGS_BASIC" JSON | ttnpb.Right | RIGHT_CLIENT_SETTINGS_COLLABORATORS | "RIGHT_CLIENT_SETTINGS_COLLABORATORS" JSON | ttnpb.Right | RIGHT_GATEWAY_ALL | "RIGHT_GATEWAY_ALL" @@ -719,6 +721,7 @@ JSON | ttnpb.Right | RIGHT_GATEWAY_DELETE | "RIGHT_GATEWAY_DELETE" JSON | ttnpb.Right | RIGHT_GATEWAY_INFO | "RIGHT_GATEWAY_INFO" JSON | ttnpb.Right | RIGHT_GATEWAY_LINK | "RIGHT_GATEWAY_LINK" JSON | ttnpb.Right | RIGHT_GATEWAY_LOCATION_READ | "RIGHT_GATEWAY_LOCATION_READ" +JSON | ttnpb.Right | RIGHT_GATEWAY_PURGE | "RIGHT_GATEWAY_PURGE" JSON | ttnpb.Right | RIGHT_GATEWAY_READ_SECRETS | "RIGHT_GATEWAY_READ_SECRETS" JSON | ttnpb.Right | RIGHT_GATEWAY_SETTINGS_API_KEYS | "RIGHT_GATEWAY_SETTINGS_API_KEYS" JSON | ttnpb.Right | RIGHT_GATEWAY_SETTINGS_BASIC | "RIGHT_GATEWAY_SETTINGS_BASIC" @@ -737,6 +740,7 @@ JSON | ttnpb.Right | RIGHT_ORGANIZATION_DELETE | "RIGHT_ORGANIZATION_DELETE" JSON | ttnpb.Right | RIGHT_ORGANIZATION_GATEWAYS_CREATE | "RIGHT_ORGANIZATION_GATEWAYS_CREATE" JSON | ttnpb.Right | RIGHT_ORGANIZATION_GATEWAYS_LIST | "RIGHT_ORGANIZATION_GATEWAYS_LIST" JSON | ttnpb.Right | RIGHT_ORGANIZATION_INFO | "RIGHT_ORGANIZATION_INFO" +JSON | ttnpb.Right | RIGHT_ORGANIZATION_PURGE | "RIGHT_ORGANIZATION_PURGE" JSON | ttnpb.Right | RIGHT_ORGANIZATION_SETTINGS_API_KEYS | "RIGHT_ORGANIZATION_SETTINGS_API_KEYS" JSON | ttnpb.Right | RIGHT_ORGANIZATION_SETTINGS_BASIC | "RIGHT_ORGANIZATION_SETTINGS_BASIC" JSON | ttnpb.Right | RIGHT_ORGANIZATION_SETTINGS_MEMBERS | "RIGHT_ORGANIZATION_SETTINGS_MEMBERS" @@ -747,13 +751,16 @@ JSON | ttnpb.Right | RIGHT_USER_APPLICATIONS_LIST | "RIGHT_USER_APPLICATIONS_LIS JSON | ttnpb.Right | RIGHT_USER_AUTHORIZED_CLIENTS | "RIGHT_USER_AUTHORIZED_CLIENTS" JSON | ttnpb.Right | RIGHT_USER_CLIENTS_CREATE | "RIGHT_USER_CLIENTS_CREATE" JSON | ttnpb.Right | RIGHT_USER_CLIENTS_LIST | "RIGHT_USER_CLIENTS_LIST" +JSON | ttnpb.Right | RIGHT_USER_CREATE | "RIGHT_USER_CREATE" JSON | ttnpb.Right | RIGHT_USER_DELETE | "RIGHT_USER_DELETE" JSON | ttnpb.Right | RIGHT_USER_GATEWAYS_CREATE | "RIGHT_USER_GATEWAYS_CREATE" JSON | ttnpb.Right | RIGHT_USER_GATEWAYS_LIST | "RIGHT_USER_GATEWAYS_LIST" JSON | ttnpb.Right | RIGHT_USER_INFO | "RIGHT_USER_INFO" +JSON | ttnpb.Right | RIGHT_USER_LIST | "RIGHT_USER_LIST" JSON | ttnpb.Right | RIGHT_USER_NOTIFICATIONS_READ | "RIGHT_USER_NOTIFICATIONS_READ" JSON | ttnpb.Right | RIGHT_USER_ORGANIZATIONS_CREATE | "RIGHT_USER_ORGANIZATIONS_CREATE" JSON | ttnpb.Right | RIGHT_USER_ORGANIZATIONS_LIST | "RIGHT_USER_ORGANIZATIONS_LIST" +JSON | ttnpb.Right | RIGHT_USER_PURGE | "RIGHT_USER_PURGE" JSON | ttnpb.Right | RIGHT_USER_SETTINGS_API_KEYS | "RIGHT_USER_SETTINGS_API_KEYS" JSON | ttnpb.Right | RIGHT_USER_SETTINGS_BASIC | "RIGHT_USER_SETTINGS_BASIC" JSON | ttnpb.Right | right_invalid | "right_invalid" @@ -1151,6 +1158,7 @@ ProtoJSON | ttnpb.Right | RIGHT_APPLICATION_DEVICES_WRITE | "RIGHT_APPLICATION_D ProtoJSON | ttnpb.Right | RIGHT_APPLICATION_DEVICES_WRITE_KEYS | "RIGHT_APPLICATION_DEVICES_WRITE_KEYS" ProtoJSON | ttnpb.Right | RIGHT_APPLICATION_INFO | "RIGHT_APPLICATION_INFO" ProtoJSON | ttnpb.Right | RIGHT_APPLICATION_LINK | "RIGHT_APPLICATION_LINK" +ProtoJSON | ttnpb.Right | RIGHT_APPLICATION_PURGE | "RIGHT_APPLICATION_PURGE" ProtoJSON | ttnpb.Right | RIGHT_APPLICATION_SETTINGS_API_KEYS | "RIGHT_APPLICATION_SETTINGS_API_KEYS" ProtoJSON | ttnpb.Right | RIGHT_APPLICATION_SETTINGS_BASIC | "RIGHT_APPLICATION_SETTINGS_BASIC" ProtoJSON | ttnpb.Right | RIGHT_APPLICATION_SETTINGS_COLLABORATORS | "RIGHT_APPLICATION_SETTINGS_COLLABORATORS" @@ -1161,6 +1169,7 @@ ProtoJSON | ttnpb.Right | RIGHT_APPLICATION_TRAFFIC_UP_WRITE | "RIGHT_APPLICATIO ProtoJSON | ttnpb.Right | RIGHT_CLIENT_ALL | "RIGHT_CLIENT_ALL" ProtoJSON | ttnpb.Right | RIGHT_CLIENT_DELETE | "RIGHT_CLIENT_DELETE" ProtoJSON | ttnpb.Right | RIGHT_CLIENT_INFO | "RIGHT_CLIENT_INFO" +ProtoJSON | ttnpb.Right | RIGHT_CLIENT_PURGE | "RIGHT_CLIENT_PURGE" ProtoJSON | ttnpb.Right | RIGHT_CLIENT_SETTINGS_BASIC | "RIGHT_CLIENT_SETTINGS_BASIC" ProtoJSON | ttnpb.Right | RIGHT_CLIENT_SETTINGS_COLLABORATORS | "RIGHT_CLIENT_SETTINGS_COLLABORATORS" ProtoJSON | ttnpb.Right | RIGHT_GATEWAY_ALL | "RIGHT_GATEWAY_ALL" @@ -1168,6 +1177,7 @@ ProtoJSON | ttnpb.Right | RIGHT_GATEWAY_DELETE | "RIGHT_GATEWAY_DELETE" ProtoJSON | ttnpb.Right | RIGHT_GATEWAY_INFO | "RIGHT_GATEWAY_INFO" ProtoJSON | ttnpb.Right | RIGHT_GATEWAY_LINK | "RIGHT_GATEWAY_LINK" ProtoJSON | ttnpb.Right | RIGHT_GATEWAY_LOCATION_READ | "RIGHT_GATEWAY_LOCATION_READ" +ProtoJSON | ttnpb.Right | RIGHT_GATEWAY_PURGE | "RIGHT_GATEWAY_PURGE" ProtoJSON | ttnpb.Right | RIGHT_GATEWAY_READ_SECRETS | "RIGHT_GATEWAY_READ_SECRETS" ProtoJSON | ttnpb.Right | RIGHT_GATEWAY_SETTINGS_API_KEYS | "RIGHT_GATEWAY_SETTINGS_API_KEYS" ProtoJSON | ttnpb.Right | RIGHT_GATEWAY_SETTINGS_BASIC | "RIGHT_GATEWAY_SETTINGS_BASIC" @@ -1186,6 +1196,7 @@ ProtoJSON | ttnpb.Right | RIGHT_ORGANIZATION_DELETE | "RIGHT_ORGANIZATION_DELETE ProtoJSON | ttnpb.Right | RIGHT_ORGANIZATION_GATEWAYS_CREATE | "RIGHT_ORGANIZATION_GATEWAYS_CREATE" ProtoJSON | ttnpb.Right | RIGHT_ORGANIZATION_GATEWAYS_LIST | "RIGHT_ORGANIZATION_GATEWAYS_LIST" ProtoJSON | ttnpb.Right | RIGHT_ORGANIZATION_INFO | "RIGHT_ORGANIZATION_INFO" +ProtoJSON | ttnpb.Right | RIGHT_ORGANIZATION_PURGE | "RIGHT_ORGANIZATION_PURGE" ProtoJSON | ttnpb.Right | RIGHT_ORGANIZATION_SETTINGS_API_KEYS | "RIGHT_ORGANIZATION_SETTINGS_API_KEYS" ProtoJSON | ttnpb.Right | RIGHT_ORGANIZATION_SETTINGS_BASIC | "RIGHT_ORGANIZATION_SETTINGS_BASIC" ProtoJSON | ttnpb.Right | RIGHT_ORGANIZATION_SETTINGS_MEMBERS | "RIGHT_ORGANIZATION_SETTINGS_MEMBERS" @@ -1196,13 +1207,16 @@ ProtoJSON | ttnpb.Right | RIGHT_USER_APPLICATIONS_LIST | "RIGHT_USER_APPLICATION ProtoJSON | ttnpb.Right | RIGHT_USER_AUTHORIZED_CLIENTS | "RIGHT_USER_AUTHORIZED_CLIENTS" ProtoJSON | ttnpb.Right | RIGHT_USER_CLIENTS_CREATE | "RIGHT_USER_CLIENTS_CREATE" ProtoJSON | ttnpb.Right | RIGHT_USER_CLIENTS_LIST | "RIGHT_USER_CLIENTS_LIST" +ProtoJSON | ttnpb.Right | RIGHT_USER_CREATE | "RIGHT_USER_CREATE" ProtoJSON | ttnpb.Right | RIGHT_USER_DELETE | "RIGHT_USER_DELETE" ProtoJSON | ttnpb.Right | RIGHT_USER_GATEWAYS_CREATE | "RIGHT_USER_GATEWAYS_CREATE" ProtoJSON | ttnpb.Right | RIGHT_USER_GATEWAYS_LIST | "RIGHT_USER_GATEWAYS_LIST" ProtoJSON | ttnpb.Right | RIGHT_USER_INFO | "RIGHT_USER_INFO" +ProtoJSON | ttnpb.Right | RIGHT_USER_LIST | "RIGHT_USER_LIST" ProtoJSON | ttnpb.Right | RIGHT_USER_NOTIFICATIONS_READ | "RIGHT_USER_NOTIFICATIONS_READ" ProtoJSON | ttnpb.Right | RIGHT_USER_ORGANIZATIONS_CREATE | "RIGHT_USER_ORGANIZATIONS_CREATE" ProtoJSON | ttnpb.Right | RIGHT_USER_ORGANIZATIONS_LIST | "RIGHT_USER_ORGANIZATIONS_LIST" +ProtoJSON | ttnpb.Right | RIGHT_USER_PURGE | "RIGHT_USER_PURGE" ProtoJSON | ttnpb.Right | RIGHT_USER_SETTINGS_API_KEYS | "RIGHT_USER_SETTINGS_API_KEYS" ProtoJSON | ttnpb.Right | RIGHT_USER_SETTINGS_BASIC | "RIGHT_USER_SETTINGS_BASIC" ProtoJSON | ttnpb.Right | right_invalid | "right_invalid" @@ -1600,6 +1614,7 @@ Text | ttnpb.Right | RIGHT_APPLICATION_DEVICES_WRITE | RIGHT_APPLICATION_DEVICES Text | ttnpb.Right | RIGHT_APPLICATION_DEVICES_WRITE_KEYS | RIGHT_APPLICATION_DEVICES_WRITE_KEYS Text | ttnpb.Right | RIGHT_APPLICATION_INFO | RIGHT_APPLICATION_INFO Text | ttnpb.Right | RIGHT_APPLICATION_LINK | RIGHT_APPLICATION_LINK +Text | ttnpb.Right | RIGHT_APPLICATION_PURGE | RIGHT_APPLICATION_PURGE Text | ttnpb.Right | RIGHT_APPLICATION_SETTINGS_API_KEYS | RIGHT_APPLICATION_SETTINGS_API_KEYS Text | ttnpb.Right | RIGHT_APPLICATION_SETTINGS_BASIC | RIGHT_APPLICATION_SETTINGS_BASIC Text | ttnpb.Right | RIGHT_APPLICATION_SETTINGS_COLLABORATORS | RIGHT_APPLICATION_SETTINGS_COLLABORATORS @@ -1610,6 +1625,7 @@ Text | ttnpb.Right | RIGHT_APPLICATION_TRAFFIC_UP_WRITE | RIGHT_APPLICATION_TRAF Text | ttnpb.Right | RIGHT_CLIENT_ALL | RIGHT_CLIENT_ALL Text | ttnpb.Right | RIGHT_CLIENT_DELETE | RIGHT_CLIENT_DELETE Text | ttnpb.Right | RIGHT_CLIENT_INFO | RIGHT_CLIENT_INFO +Text | ttnpb.Right | RIGHT_CLIENT_PURGE | RIGHT_CLIENT_PURGE Text | ttnpb.Right | RIGHT_CLIENT_SETTINGS_BASIC | RIGHT_CLIENT_SETTINGS_BASIC Text | ttnpb.Right | RIGHT_CLIENT_SETTINGS_COLLABORATORS | RIGHT_CLIENT_SETTINGS_COLLABORATORS Text | ttnpb.Right | RIGHT_GATEWAY_ALL | RIGHT_GATEWAY_ALL @@ -1617,6 +1633,7 @@ Text | ttnpb.Right | RIGHT_GATEWAY_DELETE | RIGHT_GATEWAY_DELETE Text | ttnpb.Right | RIGHT_GATEWAY_INFO | RIGHT_GATEWAY_INFO Text | ttnpb.Right | RIGHT_GATEWAY_LINK | RIGHT_GATEWAY_LINK Text | ttnpb.Right | RIGHT_GATEWAY_LOCATION_READ | RIGHT_GATEWAY_LOCATION_READ +Text | ttnpb.Right | RIGHT_GATEWAY_PURGE | RIGHT_GATEWAY_PURGE Text | ttnpb.Right | RIGHT_GATEWAY_READ_SECRETS | RIGHT_GATEWAY_READ_SECRETS Text | ttnpb.Right | RIGHT_GATEWAY_SETTINGS_API_KEYS | RIGHT_GATEWAY_SETTINGS_API_KEYS Text | ttnpb.Right | RIGHT_GATEWAY_SETTINGS_BASIC | RIGHT_GATEWAY_SETTINGS_BASIC @@ -1635,6 +1652,7 @@ Text | ttnpb.Right | RIGHT_ORGANIZATION_DELETE | RIGHT_ORGANIZATION_DELETE Text | ttnpb.Right | RIGHT_ORGANIZATION_GATEWAYS_CREATE | RIGHT_ORGANIZATION_GATEWAYS_CREATE Text | ttnpb.Right | RIGHT_ORGANIZATION_GATEWAYS_LIST | RIGHT_ORGANIZATION_GATEWAYS_LIST Text | ttnpb.Right | RIGHT_ORGANIZATION_INFO | RIGHT_ORGANIZATION_INFO +Text | ttnpb.Right | RIGHT_ORGANIZATION_PURGE | RIGHT_ORGANIZATION_PURGE Text | ttnpb.Right | RIGHT_ORGANIZATION_SETTINGS_API_KEYS | RIGHT_ORGANIZATION_SETTINGS_API_KEYS Text | ttnpb.Right | RIGHT_ORGANIZATION_SETTINGS_BASIC | RIGHT_ORGANIZATION_SETTINGS_BASIC Text | ttnpb.Right | RIGHT_ORGANIZATION_SETTINGS_MEMBERS | RIGHT_ORGANIZATION_SETTINGS_MEMBERS @@ -1645,13 +1663,16 @@ Text | ttnpb.Right | RIGHT_USER_APPLICATIONS_LIST | RIGHT_USER_APPLICATIONS_LIST Text | ttnpb.Right | RIGHT_USER_AUTHORIZED_CLIENTS | RIGHT_USER_AUTHORIZED_CLIENTS Text | ttnpb.Right | RIGHT_USER_CLIENTS_CREATE | RIGHT_USER_CLIENTS_CREATE Text | ttnpb.Right | RIGHT_USER_CLIENTS_LIST | RIGHT_USER_CLIENTS_LIST +Text | ttnpb.Right | RIGHT_USER_CREATE | RIGHT_USER_CREATE Text | ttnpb.Right | RIGHT_USER_DELETE | RIGHT_USER_DELETE Text | ttnpb.Right | RIGHT_USER_GATEWAYS_CREATE | RIGHT_USER_GATEWAYS_CREATE Text | ttnpb.Right | RIGHT_USER_GATEWAYS_LIST | RIGHT_USER_GATEWAYS_LIST Text | ttnpb.Right | RIGHT_USER_INFO | RIGHT_USER_INFO +Text | ttnpb.Right | RIGHT_USER_LIST | RIGHT_USER_LIST Text | ttnpb.Right | RIGHT_USER_NOTIFICATIONS_READ | RIGHT_USER_NOTIFICATIONS_READ Text | ttnpb.Right | RIGHT_USER_ORGANIZATIONS_CREATE | RIGHT_USER_ORGANIZATIONS_CREATE Text | ttnpb.Right | RIGHT_USER_ORGANIZATIONS_LIST | RIGHT_USER_ORGANIZATIONS_LIST +Text | ttnpb.Right | RIGHT_USER_PURGE | RIGHT_USER_PURGE Text | ttnpb.Right | RIGHT_USER_SETTINGS_API_KEYS | RIGHT_USER_SETTINGS_API_KEYS Text | ttnpb.Right | RIGHT_USER_SETTINGS_BASIC | RIGHT_USER_SETTINGS_BASIC Text | ttnpb.Right | right_invalid | right_invalid From a20177b699545ace85764956f2dcdef6179f82a5 Mon Sep 17 00:00:00 2001 From: Nicholas Cristofaro Date: Mon, 25 Nov 2024 12:05:33 -0300 Subject: [PATCH 22/40] dev: Generate messages and translations for new RIGHTS --- config/messages.json | 63 +++++++++++++++++++++++++++++++++++++++ pkg/webui/locales/ja.json | 7 +++++ 2 files changed, 70 insertions(+) diff --git a/config/messages.json b/config/messages.json index c025a0211f..5a0494a916 100644 --- a/config/messages.json +++ b/config/messages.json @@ -593,6 +593,15 @@ "file": "i18n.go" } }, + "enum:RIGHT_APPLICATION_PURGE": { + "translations": { + "en": "purge application" + }, + "description": { + "package": "pkg/ttnpb", + "file": "i18n.go" + } + }, "enum:RIGHT_APPLICATION_SETTINGS_API_KEYS": { "translations": { "en": "view and edit application API keys" @@ -683,6 +692,15 @@ "file": "i18n.go" } }, + "enum:RIGHT_CLIENT_PURGE": { + "translations": { + "en": "purge OAuth client" + }, + "description": { + "package": "pkg/ttnpb", + "file": "i18n.go" + } + }, "enum:RIGHT_CLIENT_SETTINGS_BASIC": { "translations": { "en": "edit OAuth client basic settings" @@ -746,6 +764,15 @@ "file": "i18n.go" } }, + "enum:RIGHT_GATEWAY_PURGE": { + "translations": { + "en": "purge gateway" + }, + "description": { + "package": "pkg/ttnpb", + "file": "i18n.go" + } + }, "enum:RIGHT_GATEWAY_READ_SECRETS": { "translations": { "en": "retrieve secrets associated with a gateway" @@ -908,6 +935,15 @@ "file": "i18n.go" } }, + "enum:RIGHT_ORGANIZATION_PURGE": { + "translations": { + "en": "purge organization" + }, + "description": { + "package": "pkg/ttnpb", + "file": "i18n.go" + } + }, "enum:RIGHT_ORGANIZATION_SETTINGS_API_KEYS": { "translations": { "en": "view and edit organization API keys" @@ -998,6 +1034,15 @@ "file": "i18n.go" } }, + "enum:RIGHT_USER_CREATE": { + "translations": { + "en": "create user account" + }, + "description": { + "package": "pkg/ttnpb", + "file": "i18n.go" + } + }, "enum:RIGHT_USER_DELETE": { "translations": { "en": "delete user account" @@ -1034,6 +1079,15 @@ "file": "i18n.go" } }, + "enum:RIGHT_USER_LIST": { + "translations": { + "en": "list user accounts" + }, + "description": { + "package": "pkg/ttnpb", + "file": "i18n.go" + } + }, "enum:RIGHT_USER_NOTIFICATIONS_READ": { "translations": { "en": "read user notifications" @@ -1061,6 +1115,15 @@ "file": "i18n.go" } }, + "enum:RIGHT_USER_PURGE": { + "translations": { + "en": "purge user account" + }, + "description": { + "package": "pkg/ttnpb", + "file": "i18n.go" + } + }, "enum:RIGHT_USER_SETTINGS_API_KEYS": { "translations": { "en": "view and edit user API keys" diff --git a/pkg/webui/locales/ja.json b/pkg/webui/locales/ja.json index 66f0ed731d..acae28092e 100644 --- a/pkg/webui/locales/ja.json +++ b/pkg/webui/locales/ja.json @@ -1891,6 +1891,7 @@ "enum:RIGHT_APPLICATION_DEVICES_WRITE_KEYS": "アプリケーション内のデバイスキーの編集", "enum:RIGHT_APPLICATION_INFO": "アプリケーション情報の閲覧", "enum:RIGHT_APPLICATION_LINK": "アプリケーションのネットワークサーバへのリンク(アップリンクの読み取りとダウンリンクの書き込み)", + "enum:RIGHT_APPLICATION_PURGE": "", "enum:RIGHT_APPLICATION_SETTINGS_API_KEYS": "アプリケーションAPIキーの閲覧・編集", "enum:RIGHT_APPLICATION_SETTINGS_BASIC": "基本的なアプリケーション設定の編集", "enum:RIGHT_APPLICATION_SETTINGS_COLLABORATORS": "アプリケーションコラボレーターの閲覧・編集", @@ -1901,6 +1902,7 @@ "enum:RIGHT_CLIENT_ALL": "全OAuthクライアント権限", "enum:RIGHT_CLIENT_DELETE": "OAuthクライアントを削除", "enum:RIGHT_CLIENT_INFO": "OAuthクライアント情報を表示", + "enum:RIGHT_CLIENT_PURGE": "", "enum:RIGHT_CLIENT_SETTINGS_BASIC": "OAuthクライアントの基本設定を編集", "enum:RIGHT_CLIENT_SETTINGS_COLLABORATORS": "OAuthクライアントの共同作業者を表示および編集", "enum:RIGHT_GATEWAY_ALL": "全ゲートウェイ権限", @@ -1908,6 +1910,7 @@ "enum:RIGHT_GATEWAY_INFO": "ゲートウェイ情報の閲覧", "enum:RIGHT_GATEWAY_LINK": "ゲートウェイのネットワークサーバへのリンク(アップリンクの書き込みとダウンリンクの読み込み)", "enum:RIGHT_GATEWAY_LOCATION_READ": "ゲートウェイ位置の閲覧", + "enum:RIGHT_GATEWAY_PURGE": "", "enum:RIGHT_GATEWAY_READ_SECRETS": "ゲートウェイに関連した秘密情報を取得", "enum:RIGHT_GATEWAY_SETTINGS_API_KEYS": "ゲートウェイAPIキーの閲覧・編集", "enum:RIGHT_GATEWAY_SETTINGS_BASIC": "基本的なゲートウェイ設定の編集", @@ -1926,6 +1929,7 @@ "enum:RIGHT_ORGANIZATION_GATEWAYS_CREATE": "組織内のゲートウェイの作成", "enum:RIGHT_ORGANIZATION_GATEWAYS_LIST": "組織がコラボレータであるゲートウェイ一覧", "enum:RIGHT_ORGANIZATION_INFO": "組織情報の閲覧", + "enum:RIGHT_ORGANIZATION_PURGE": "", "enum:RIGHT_ORGANIZATION_SETTINGS_API_KEYS": "組織APIキーの閲覧・編集", "enum:RIGHT_ORGANIZATION_SETTINGS_BASIC": "基本的な組織情報の閲覧・編集", "enum:RIGHT_ORGANIZATION_SETTINGS_MEMBERS": "組織メンバーの閲覧・編集", @@ -1936,13 +1940,16 @@ "enum:RIGHT_USER_AUTHORIZED_CLIENTS": "認証済みOAuthクライアントの閲覧・編集", "enum:RIGHT_USER_CLIENTS_CREATE": "ユーザ内のOAuthクライアントの作成", "enum:RIGHT_USER_CLIENTS_LIST": "ユーザがコラボレータであるOAuthクライアント一覧", + "enum:RIGHT_USER_CREATE": "", "enum:RIGHT_USER_DELETE": "ユーザアカウントの削除", "enum:RIGHT_USER_GATEWAYS_CREATE": "ユーザ内のゲートウェイ作成", "enum:RIGHT_USER_GATEWAYS_LIST": "ユーザがコラボレータであるゲートウェイ一覧", "enum:RIGHT_USER_INFO": "ユーザ情報の閲覧", + "enum:RIGHT_USER_LIST": "", "enum:RIGHT_USER_NOTIFICATIONS_READ": "ユーザー通知を読む", "enum:RIGHT_USER_ORGANIZATIONS_CREATE": "ユーザ内の組織の作成", "enum:RIGHT_USER_ORGANIZATIONS_LIST": "ユーザが所属する組織一覧", + "enum:RIGHT_USER_PURGE": "", "enum:RIGHT_USER_SETTINGS_API_KEYS": "ユーザAPIキーの閲覧・編集", "enum:RIGHT_USER_SETTINGS_BASIC": "基本的なユーザ設定の編集", "enum:SESSION": "セッション更新", From f642ab34a47e42a3ccac4f0eb6d56da610452521 Mon Sep 17 00:00:00 2001 From: Nicholas Cristofaro Date: Mon, 25 Nov 2024 15:12:06 -0300 Subject: [PATCH 23/40] is: Add read-only admin tests to application_access --- pkg/identityserver/application_access_test.go | 217 +++++++++++------- 1 file changed, 139 insertions(+), 78 deletions(-) diff --git a/pkg/identityserver/application_access_test.go b/pkg/identityserver/application_access_test.go index e5f24407a1..e1aab795fc 100644 --- a/pkg/identityserver/application_access_test.go +++ b/pkg/identityserver/application_access_test.go @@ -26,6 +26,79 @@ import ( "google.golang.org/grpc" ) +func TestApplicationAPIKeysPermissions(t *testing.T) { + p := &storetest.Population{} + + readOnlyAdmin := p.NewUser() + readOnlyAdmin.Admin = true + readOnlyAdminKey, _ := p.NewAPIKey(readOnlyAdmin.GetEntityIdentifiers(), ttnpb.AllReadAdminRights.GetRights()...) + readOnlyAdminKeyCreds := rpcCreds(readOnlyAdminKey) + + usr1 := p.NewUser() + app1 := p.NewApplication(usr1.GetOrganizationOrUserIdentifiers()) + appKey, _ := p.NewAPIKey(app1.GetEntityIdentifiers(), + ttnpb.Right_RIGHT_APPLICATION_INFO, + ttnpb.Right_RIGHT_APPLICATION_LINK, + ) + appCreds := rpcCreds(appKey) + + t.Parallel() + a, ctx := test.New(t) + + testWithIdentityServer(t, func(is *IdentityServer, cc *grpc.ClientConn) { + is.config.AdminRights.All = true + reg := ttnpb.NewApplicationAccessClient(cc) + + t.Run("API Key CRUD with different invalid credentials", func(t *testing.T) { // nolint:paralleltest + for _, opts := range [][]grpc.CallOption{nil, {appCreds}, {readOnlyAdminKeyCreds}} { + created, err := reg.CreateAPIKey(ctx, &ttnpb.CreateApplicationAPIKeyRequest{ + ApplicationIds: app1.GetIds(), + Name: "api-key-name", + Rights: []ttnpb.Right{ttnpb.Right_RIGHT_APPLICATION_INFO}, + }, opts...) + if a.So(err, should.NotBeNil) && a.So(errors.IsPermissionDenied(err), should.BeTrue) { + a.So(created, should.BeNil) + } + + list, err := reg.ListAPIKeys(ctx, &ttnpb.ListApplicationAPIKeysRequest{ + ApplicationIds: app1.GetIds(), + }, opts...) + if a.So(err, should.NotBeNil) && a.So(errors.IsPermissionDenied(err), should.BeTrue) { + a.So(list, should.BeNil) + } + + got, err := reg.GetAPIKey(ctx, &ttnpb.GetApplicationAPIKeyRequest{ + ApplicationIds: app1.GetIds(), + KeyId: appKey.GetId(), + }, opts...) + if a.So(err, should.NotBeNil) && a.So(errors.IsPermissionDenied(err), should.BeTrue) { + a.So(got, should.BeNil) + } + + updated, err := reg.UpdateAPIKey(ctx, &ttnpb.UpdateApplicationAPIKeyRequest{ + ApplicationIds: app1.GetIds(), + ApiKey: &ttnpb.APIKey{ + Id: appKey.GetId(), + Name: "api-key-name-updated", + }, + FieldMask: ttnpb.FieldMask("name"), + }, opts...) + if a.So(err, should.NotBeNil) && a.So(errors.IsPermissionDenied(err), should.BeTrue) { + a.So(updated, should.BeNil) + } + + _, err = reg.DeleteAPIKey(ctx, &ttnpb.DeleteApplicationAPIKeyRequest{ + ApplicationIds: app1.GetIds(), + KeyId: created.GetId(), + }, opts...) + if !a.So(errors.IsPermissionDenied(err), should.BeTrue) { + t.FailNow() + } + } + }) + }, withPrivateTestDatabase(p)) +} + func TestApplicationAPIKeys(t *testing.T) { // nolint:gocyclo p := &storetest.Population{} @@ -50,7 +123,6 @@ func TestApplicationAPIKeys(t *testing.T) { // nolint:gocyclo ttnpb.Right_RIGHT_APPLICATION_INFO, ttnpb.Right_RIGHT_APPLICATION_LINK, ) - appCreds := rpcCreds(appKey) t.Parallel() a, ctx := test.New(t) @@ -147,53 +219,6 @@ func TestApplicationAPIKeys(t *testing.T) { // nolint:gocyclo }) } - // API Key CRUD with different invalid credentials. - for _, opts := range [][]grpc.CallOption{nil, {appCreds}} { - created, err := reg.CreateAPIKey(ctx, &ttnpb.CreateApplicationAPIKeyRequest{ - ApplicationIds: app1.GetIds(), - Name: "api-key-name", - Rights: []ttnpb.Right{ttnpb.Right_RIGHT_APPLICATION_INFO}, - }, opts...) - if a.So(err, should.NotBeNil) && a.So(errors.IsPermissionDenied(err), should.BeTrue) { - a.So(created, should.BeNil) - } - - list, err := reg.ListAPIKeys(ctx, &ttnpb.ListApplicationAPIKeysRequest{ - ApplicationIds: app1.GetIds(), - }, opts...) - if a.So(err, should.NotBeNil) && a.So(errors.IsPermissionDenied(err), should.BeTrue) { - a.So(list, should.BeNil) - } - - got, err := reg.GetAPIKey(ctx, &ttnpb.GetApplicationAPIKeyRequest{ - ApplicationIds: app1.GetIds(), - KeyId: appKey.GetId(), - }, opts...) - if a.So(err, should.NotBeNil) && a.So(errors.IsPermissionDenied(err), should.BeTrue) { - a.So(got, should.BeNil) - } - - updated, err := reg.UpdateAPIKey(ctx, &ttnpb.UpdateApplicationAPIKeyRequest{ - ApplicationIds: app1.GetIds(), - ApiKey: &ttnpb.APIKey{ - Id: appKey.GetId(), - Name: "api-key-name-updated", - }, - FieldMask: ttnpb.FieldMask("name"), - }, opts...) - if a.So(err, should.NotBeNil) && a.So(errors.IsPermissionDenied(err), should.BeTrue) { - a.So(updated, should.BeNil) - } - - _, err = reg.DeleteAPIKey(ctx, &ttnpb.DeleteApplicationAPIKeyRequest{ - ApplicationIds: app1.GetIds(), - KeyId: created.GetId(), - }, opts...) - if !a.So(errors.IsPermissionDenied(err), should.BeTrue) { - t.FailNow() - } - } - // API Key CRUD with different valid credentials. for _, opts := range [][]grpc.CallOption{{adminCreds}, {usr1Creds}, {limitedCreds}} { created, err := reg.CreateAPIKey(ctx, &ttnpb.CreateApplicationAPIKeyRequest{ @@ -287,6 +312,72 @@ func TestApplicationAPIKeys(t *testing.T) { // nolint:gocyclo }, withPrivateTestDatabase(p)) } +func TestApplicationCollaboratorsPermissions(t *testing.T) { // nolint:gocyclo + p := &storetest.Population{} + + readOnlyAdmin := p.NewUser() + readOnlyAdmin.Admin = true + readOnlyAdminKey, _ := p.NewAPIKey(readOnlyAdmin.GetEntityIdentifiers(), ttnpb.AllReadAdminRights.GetRights()...) + readOnlyAdminKeyCreds := rpcCreds(readOnlyAdminKey) + + usr1 := p.NewUser() + app1 := p.NewApplication(usr1.GetOrganizationOrUserIdentifiers()) + appKey, _ := p.NewAPIKey(app1.GetEntityIdentifiers(), + ttnpb.Right_RIGHT_APPLICATION_INFO, + ttnpb.Right_RIGHT_APPLICATION_LINK, + ) + appCreds := rpcCreds(appKey) + + usr2 := p.NewUser() + p.NewMembership( + usr2.GetOrganizationOrUserIdentifiers(), + app1.GetEntityIdentifiers(), + ttnpb.Right_RIGHT_APPLICATION_INFO, + ttnpb.Right_RIGHT_APPLICATION_LINK, + ) + + t.Parallel() + a, ctx := test.New(t) + + testWithIdentityServer(t, func(is *IdentityServer, cc *grpc.ClientConn) { + is.config.AdminRights.All = true + + reg := ttnpb.NewApplicationAccessClient(cc) + + // Collaborator CRUD with different invalid credentials. + for _, opts := range [][]grpc.CallOption{nil, {appCreds}, {readOnlyAdminKeyCreds}} { + _, err := reg.SetCollaborator(ctx, &ttnpb.SetApplicationCollaboratorRequest{ + ApplicationIds: app1.GetIds(), + Collaborator: &ttnpb.Collaborator{ + Ids: usr2.GetOrganizationOrUserIdentifiers(), + Rights: []ttnpb.Right{ + ttnpb.Right_RIGHT_APPLICATION_INFO, + }, + }, + }, opts...) + if a.So(err, should.NotBeNil) { + a.So(errors.IsPermissionDenied(err), should.BeTrue) + } + + got, err := reg.GetCollaborator(ctx, &ttnpb.GetApplicationCollaboratorRequest{ + ApplicationIds: app1.GetIds(), + Collaborator: usr2.GetOrganizationOrUserIdentifiers(), + }, opts...) + if a.So(err, should.NotBeNil) && a.So(errors.IsPermissionDenied(err), should.BeTrue) { + a.So(got, should.BeNil) + } + } + + // ListCollaborators without credentials. + list, err := reg.ListCollaborators(ctx, &ttnpb.ListApplicationCollaboratorsRequest{ + ApplicationIds: app1.GetIds(), + }) + if a.So(err, should.NotBeNil) && a.So(errors.IsUnauthenticated(err), should.BeTrue) { + a.So(list, should.BeNil) + } + }, withPrivateTestDatabase(p)) +} + func TestApplicationCollaborators(t *testing.T) { // nolint:gocyclo p := &storetest.Population{} @@ -308,12 +399,6 @@ func TestApplicationCollaborators(t *testing.T) { // nolint:gocyclo ) limitedCreds := rpcCreds(limitedKey) - appKey, _ := p.NewAPIKey(app1.GetEntityIdentifiers(), - ttnpb.Right_RIGHT_APPLICATION_INFO, - ttnpb.Right_RIGHT_APPLICATION_LINK, - ) - appCreds := rpcCreds(appKey) - usr2 := p.NewUser() p.NewMembership( usr2.GetOrganizationOrUserIdentifiers(), @@ -385,30 +470,6 @@ func TestApplicationCollaborators(t *testing.T) { // nolint:gocyclo }, limitedCreds) a.So(err, should.BeNil) - // Collaborator CRUD with different invalid credentials. - for _, opts := range [][]grpc.CallOption{nil, {appCreds}} { - _, err := reg.SetCollaborator(ctx, &ttnpb.SetApplicationCollaboratorRequest{ - ApplicationIds: app1.GetIds(), - Collaborator: &ttnpb.Collaborator{ - Ids: usr2.GetOrganizationOrUserIdentifiers(), - Rights: []ttnpb.Right{ - ttnpb.Right_RIGHT_APPLICATION_INFO, - }, - }, - }, opts...) - if a.So(err, should.NotBeNil) { - a.So(errors.IsPermissionDenied(err), should.BeTrue) - } - - got, err := reg.GetCollaborator(ctx, &ttnpb.GetApplicationCollaboratorRequest{ - ApplicationIds: app1.GetIds(), - Collaborator: usr2.GetOrganizationOrUserIdentifiers(), - }, opts...) - if a.So(err, should.NotBeNil) && a.So(errors.IsPermissionDenied(err), should.BeTrue) { - a.So(got, should.BeNil) - } - } - // ListCollaborators without credentials. list, err := reg.ListCollaborators(ctx, &ttnpb.ListApplicationCollaboratorsRequest{ ApplicationIds: app1.GetIds(), From 42aba22313b04f72486567af19046e7dca3a2c7b Mon Sep 17 00:00:00 2001 From: Nicholas Cristofaro Date: Mon, 25 Nov 2024 15:15:47 -0300 Subject: [PATCH 24/40] is: Add read-only admin tests to application_registry --- .../application_registry_test.go | 130 ++++++++++++------ 1 file changed, 89 insertions(+), 41 deletions(-) diff --git a/pkg/identityserver/application_registry_test.go b/pkg/identityserver/application_registry_test.go index 3fc372ecf8..bf32a907fa 100644 --- a/pkg/identityserver/application_registry_test.go +++ b/pkg/identityserver/application_registry_test.go @@ -26,66 +26,114 @@ import ( "google.golang.org/grpc/metadata" ) -func TestApplicationsPermissionDenied(t *testing.T) { +func TestApplicationsPermissions(t *testing.T) { p := &storetest.Population{} usr1 := p.NewUser() app1 := p.NewApplication(usr1.GetOrganizationOrUserIdentifiers()) + readAdminUsr := p.NewUser() + readAdminUsr.Admin = true + readAdminUsrKey, _ := p.NewAPIKey(readAdminUsr.GetEntityIdentifiers(), ttnpb.AllReadAdminRights.GetRights()...) + readAdminUsrCreds := rpcCreds(readAdminUsrKey) + t.Parallel() a, ctx := test.New(t) testWithIdentityServer(t, func(_ *IdentityServer, cc *grpc.ClientConn) { reg := ttnpb.NewApplicationRegistryClient(cc) - _, err := reg.Create(ctx, &ttnpb.CreateApplicationRequest{ - Application: &ttnpb.Application{ - Ids: &ttnpb.ApplicationIdentifiers{ApplicationId: "foo-app"}, - }, - Collaborator: usr1.GetOrganizationOrUserIdentifiers(), - }) - if a.So(err, should.NotBeNil) { - a.So(errors.IsPermissionDenied(err), should.BeTrue) - } + t.Run("Permission denied", func(t *testing.T) { // nolint:paralleltest + reg := ttnpb.NewApplicationRegistryClient(cc) - _, err = reg.Get(ctx, &ttnpb.GetApplicationRequest{ - ApplicationIds: app1.GetIds(), - FieldMask: ttnpb.FieldMask("name"), - }) - if a.So(err, should.NotBeNil) { - a.So(errors.IsUnauthenticated(err), should.BeTrue) - } + _, err := reg.Create(ctx, &ttnpb.CreateApplicationRequest{ + Application: &ttnpb.Application{ + Ids: &ttnpb.ApplicationIdentifiers{ApplicationId: "foo-app"}, + }, + Collaborator: usr1.GetOrganizationOrUserIdentifiers(), + }) + if a.So(err, should.NotBeNil) { + a.So(errors.IsPermissionDenied(err), should.BeTrue) + } - listRes, err := reg.List(ctx, &ttnpb.ListApplicationsRequest{ - FieldMask: ttnpb.FieldMask("name"), - }) - a.So(err, should.BeNil) - if a.So(listRes, should.NotBeNil) { - a.So(listRes.Applications, should.BeEmpty) - } + _, err = reg.Get(ctx, &ttnpb.GetApplicationRequest{ + ApplicationIds: app1.GetIds(), + FieldMask: ttnpb.FieldMask("name"), + }) + if a.So(err, should.NotBeNil) { + a.So(errors.IsUnauthenticated(err), should.BeTrue) + } - _, err = reg.List(ctx, &ttnpb.ListApplicationsRequest{ - Collaborator: usr1.GetOrganizationOrUserIdentifiers(), - FieldMask: ttnpb.FieldMask("name"), + listRes, err := reg.List(ctx, &ttnpb.ListApplicationsRequest{ + FieldMask: ttnpb.FieldMask("name"), + }) + a.So(err, should.BeNil) + if a.So(listRes, should.NotBeNil) { + a.So(listRes.Applications, should.BeEmpty) + } + + _, err = reg.List(ctx, &ttnpb.ListApplicationsRequest{ + Collaborator: usr1.GetOrganizationOrUserIdentifiers(), + FieldMask: ttnpb.FieldMask("name"), + }) + if a.So(err, should.NotBeNil) { + a.So(errors.IsPermissionDenied(err), should.BeTrue) + } + + _, err = reg.Update(ctx, &ttnpb.UpdateApplicationRequest{ + Application: &ttnpb.Application{ + Ids: app1.GetIds(), + Name: "Updated Name", + }, + FieldMask: ttnpb.FieldMask("name"), + }) + if a.So(err, should.NotBeNil) { + a.So(errors.IsPermissionDenied(err), should.BeTrue) + } + + _, err = reg.Delete(ctx, app1.GetIds()) + if a.So(err, should.NotBeNil) { + a.So(errors.IsPermissionDenied(err), should.BeTrue) + } }) - if a.So(err, should.NotBeNil) { + + t.Run("Admin read-only", func(t *testing.T) { // nolint:paralleltest + _, err := reg.Create(ctx, &ttnpb.CreateApplicationRequest{ + Application: &ttnpb.Application{ + Ids: &ttnpb.ApplicationIdentifiers{ApplicationId: "foo-app"}, + }, + Collaborator: usr1.GetOrganizationOrUserIdentifiers(), + }, readAdminUsrCreds) a.So(errors.IsPermissionDenied(err), should.BeTrue) - } - _, err = reg.Update(ctx, &ttnpb.UpdateApplicationRequest{ - Application: &ttnpb.Application{ - Ids: app1.GetIds(), - Name: "Updated Name", - }, - FieldMask: ttnpb.FieldMask("name"), - }) - if a.So(err, should.NotBeNil) { + _, err = reg.Get(ctx, &ttnpb.GetApplicationRequest{ + ApplicationIds: app1.GetIds(), + FieldMask: ttnpb.FieldMask("name"), + }, readAdminUsrCreds) + a.So(errors.IsPermissionDenied(err), should.BeFalse) + + _, err = reg.List(ctx, &ttnpb.ListApplicationsRequest{ + FieldMask: ttnpb.FieldMask("name"), + }, readAdminUsrCreds) + a.So(errors.IsPermissionDenied(err), should.BeFalse) + + _, err = reg.List(ctx, &ttnpb.ListApplicationsRequest{ + Collaborator: usr1.GetOrganizationOrUserIdentifiers(), + FieldMask: ttnpb.FieldMask("name"), + }, readAdminUsrCreds) + a.So(errors.IsPermissionDenied(err), should.BeFalse) + + _, err = reg.Update(ctx, &ttnpb.UpdateApplicationRequest{ + Application: &ttnpb.Application{ + Ids: app1.GetIds(), + Name: "Updated Name", + }, + FieldMask: ttnpb.FieldMask("name"), + }, readAdminUsrCreds) a.So(errors.IsPermissionDenied(err), should.BeTrue) - } - _, err = reg.Delete(ctx, app1.GetIds()) - if a.So(err, should.NotBeNil) { + _, err = reg.Delete(ctx, app1.GetIds(), readAdminUsrCreds) a.So(errors.IsPermissionDenied(err), should.BeTrue) - } + }) }, withPrivateTestDatabase(p)) } From de247a35ed9de51e8143021effd7f91486a133cd Mon Sep 17 00:00:00 2001 From: Nicholas Cristofaro Date: Mon, 25 Nov 2024 15:20:52 -0300 Subject: [PATCH 25/40] is: Add read-only admin tests to client_access --- pkg/identityserver/client_access_test.go | 166 ++++++++++++----------- 1 file changed, 90 insertions(+), 76 deletions(-) diff --git a/pkg/identityserver/client_access_test.go b/pkg/identityserver/client_access_test.go index 624750d5b6..d28ff62812 100644 --- a/pkg/identityserver/client_access_test.go +++ b/pkg/identityserver/client_access_test.go @@ -26,6 +26,95 @@ import ( "google.golang.org/grpc" ) +func TestClientCollaboratorsPermissions(t *testing.T) { // nolint:gocyclo + p := &storetest.Population{} + + usr1 := p.NewUser() + + readAdmin := p.NewUser() + readAdmin.Admin = true + readAdminKey, _ := p.NewAPIKey(readAdmin.GetEntityIdentifiers(), ttnpb.AllReadAdminRights.GetRights()...) + readAdminCreds := rpcCreds(readAdminKey) + + cli1 := p.NewClient(usr1.GetOrganizationOrUserIdentifiers()) + cliKey, _ := p.NewAPIKey(cli1.GetEntityIdentifiers(), + ttnpb.Right_RIGHT_GATEWAY_INFO, + ttnpb.Right_RIGHT_GATEWAY_LINK, + ) + cliCreds := rpcCreds(cliKey) + + p.NewMembership( + usr1.GetOrganizationOrUserIdentifiers(), + cli1.GetEntityIdentifiers(), + ttnpb.Right_RIGHT_CLIENT_SETTINGS_COLLABORATORS, + ) + + t.Parallel() + a, ctx := test.New(t) + + testWithIdentityServer(t, func(is *IdentityServer, cc *grpc.ClientConn) { + is.config.AdminRights.All = true + + reg := ttnpb.NewClientAccessClient(cc) + + t.Run("Invalid credentials", func(t *testing.T) { // nolint:paralleltest + for _, opts := range [][]grpc.CallOption{nil, {cliCreds}} { + _, err := reg.GetCollaborator(ctx, &ttnpb.GetClientCollaboratorRequest{ + ClientIds: cli1.GetIds(), + Collaborator: usr1.GetOrganizationOrUserIdentifiers(), + }) + a.So(errors.IsPermissionDenied(err), should.BeTrue) + + _, err = reg.ListCollaborators(ctx, &ttnpb.ListClientCollaboratorsRequest{ + ClientIds: cli1.GetIds(), + }) + a.So(errors.IsUnauthenticated(err), should.BeTrue) + + _, err = reg.SetCollaborator(ctx, &ttnpb.SetClientCollaboratorRequest{ + ClientIds: cli1.GetIds(), + Collaborator: &ttnpb.Collaborator{ + Ids: usr1.GetOrganizationOrUserIdentifiers(), + Rights: []ttnpb.Right{ttnpb.Right_RIGHT_GATEWAY_INFO}, + }, + }, opts...) + a.So(errors.IsPermissionDenied(err), should.BeTrue) + } + }) + + t.Run("Admin read-only", func(t *testing.T) { // nolint:paralleltest + _, err := reg.GetCollaborator(ctx, &ttnpb.GetClientCollaboratorRequest{ + ClientIds: cli1.GetIds(), + Collaborator: usr1.GetOrganizationOrUserIdentifiers(), + }, readAdminCreds) + a.So(errors.IsPermissionDenied(err), should.BeTrue) + + // ListCollaborators without credentials. + _, err = reg.ListCollaborators(ctx, &ttnpb.ListClientCollaboratorsRequest{ + ClientIds: cli1.GetIds(), + }, readAdminCreds) + a.So(errors.IsPermissionDenied(err), should.BeFalse) + + _, err = reg.SetCollaborator(ctx, &ttnpb.SetClientCollaboratorRequest{ + ClientIds: cli1.GetIds(), + Collaborator: &ttnpb.Collaborator{ + Ids: usr1.GetOrganizationOrUserIdentifiers(), + Rights: []ttnpb.Right{ttnpb.Right_RIGHT_GATEWAY_INFO}, + }, + }, readAdminCreds) + if a.So(err, should.NotBeNil) { + a.So(errors.IsPermissionDenied(err), should.BeTrue) + } + }) + + t.Run("cluster auth", func(t *testing.T) { // nolint:paralleltest + rights, err := reg.ListRights(ctx, cli1.GetIds(), is.WithClusterAuth()) + if a.So(err, should.BeNil) && a.So(rights, should.NotBeNil) { + a.So(ttnpb.AllClusterRights.Intersect(ttnpb.AllClientRights).Sub(rights).Rights, should.BeEmpty) + } + }) + }, withPrivateTestDatabase(p)) +} + func TestClientCollaborators(t *testing.T) { // nolint:gocyclo p := &storetest.Population{} @@ -39,11 +128,6 @@ func TestClientCollaborators(t *testing.T) { // nolint:gocyclo usr1Creds := rpcCreds(usr1Key) cli1 := p.NewClient(usr1.GetOrganizationOrUserIdentifiers()) - cliKey, _ := p.NewAPIKey(cli1.GetEntityIdentifiers(), - ttnpb.Right_RIGHT_GATEWAY_INFO, - ttnpb.Right_RIGHT_GATEWAY_LINK, - ) - cliCreds := rpcCreds(cliKey) usr2 := p.NewUser() p.NewMembership( @@ -72,59 +156,6 @@ func TestClientCollaborators(t *testing.T) { // nolint:gocyclo } a.So(got, should.BeNil) - // SetCollaborator without credentials. - _, err = reg.SetCollaborator(ctx, &ttnpb.SetClientCollaboratorRequest{ - ClientIds: cli1.GetIds(), - Collaborator: &ttnpb.Collaborator{ - Ids: usr2.GetOrganizationOrUserIdentifiers(), - Rights: []ttnpb.Right{ - ttnpb.Right_RIGHT_CLIENT_SETTINGS_COLLABORATORS, - }, - }, - }) - if a.So(err, should.NotBeNil) { - a.So(errors.IsPermissionDenied(err), should.BeTrue) - } - - // GetCollaborator without credentials. - got, err = reg.GetCollaborator(ctx, &ttnpb.GetClientCollaboratorRequest{ - ClientIds: cli1.GetIds(), - Collaborator: usr2.GetOrganizationOrUserIdentifiers(), - }) - if a.So(err, should.NotBeNil) && a.So(errors.IsPermissionDenied(err), should.BeTrue) { - a.So(got, should.BeNil) - } - - // ListCollaborators without credentials. - list, err := reg.ListCollaborators(ctx, &ttnpb.ListClientCollaboratorsRequest{ - ClientIds: cli1.GetIds(), - }) - if a.So(err, should.NotBeNil) && a.So(errors.IsUnauthenticated(err), should.BeTrue) { - a.So(list, should.BeNil) - } - - // Collaborator CRUD with different invalid credentials. - for _, opts := range [][]grpc.CallOption{nil, {cliCreds}} { - _, err := reg.SetCollaborator(ctx, &ttnpb.SetClientCollaboratorRequest{ - ClientIds: cli1.GetIds(), - Collaborator: &ttnpb.Collaborator{ - Ids: usr2.GetOrganizationOrUserIdentifiers(), - Rights: []ttnpb.Right{ttnpb.Right_RIGHT_GATEWAY_INFO}, - }, - }, opts...) - if a.So(err, should.NotBeNil) { - a.So(errors.IsPermissionDenied(err), should.BeTrue) - } - - got, err := reg.GetCollaborator(ctx, &ttnpb.GetClientCollaboratorRequest{ - ClientIds: cli1.GetIds(), - Collaborator: usr2.GetOrganizationOrUserIdentifiers(), - }, opts...) - if a.So(err, should.NotBeNil) && a.So(errors.IsPermissionDenied(err), should.BeTrue) { - a.So(got, should.BeNil) - } - } - // Collaborator CRUD with different valid credentials. for _, opts := range [][]grpc.CallOption{{adminCreds}, {usr1Creds}} { // Adds `usr3` as a collaborator of `cli1` client. @@ -138,7 +169,7 @@ func TestClientCollaborators(t *testing.T) { // nolint:gocyclo a.So(err, should.BeNil) // Lists collaborators of the `cli1` client. - list, err = reg.ListCollaborators(ctx, &ttnpb.ListClientCollaboratorsRequest{ + list, err := reg.ListCollaborators(ctx, &ttnpb.ListClientCollaboratorsRequest{ ClientIds: cli1.GetIds(), }, opts...) if a.So(err, should.BeNil) && a.So(list, should.NotBeNil) && a.So(list.Collaborators, should.HaveLength, 3) { @@ -230,23 +261,6 @@ func TestClientCollaborators(t *testing.T) { // nolint:gocyclo }, withPrivateTestDatabase(p)) } -func TestClientAccessClusterAuth(t *testing.T) { - p := &storetest.Population{} - cli1 := p.NewClient(nil) - - t.Parallel() - a, ctx := test.New(t) - - testWithIdentityServer(t, func(is *IdentityServer, cc *grpc.ClientConn) { - reg := ttnpb.NewClientAccessClient(cc) - - rights, err := reg.ListRights(ctx, cli1.GetIds(), is.WithClusterAuth()) - if a.So(err, should.BeNil) && a.So(rights, should.NotBeNil) { - a.So(ttnpb.AllClusterRights.Intersect(ttnpb.AllClientRights).Sub(rights).Rights, should.BeEmpty) - } - }, withPrivateTestDatabase(p)) -} - func TestClientContactRestrictions(t *testing.T) { p := &storetest.Population{} From 89279121ffb53b8b74918f149b41fa4df4b1c033 Mon Sep 17 00:00:00 2001 From: Nicholas Cristofaro Date: Mon, 25 Nov 2024 15:25:03 -0300 Subject: [PATCH 26/40] is: Add read-only admin tests to client_registry --- pkg/identityserver/client_registry_test.go | 111 +++++++++++++-------- 1 file changed, 72 insertions(+), 39 deletions(-) diff --git a/pkg/identityserver/client_registry_test.go b/pkg/identityserver/client_registry_test.go index 5622363832..95121286ae 100644 --- a/pkg/identityserver/client_registry_test.go +++ b/pkg/identityserver/client_registry_test.go @@ -26,8 +26,14 @@ import ( "google.golang.org/grpc/metadata" ) -func TestClientsPermissionDenied(t *testing.T) { +func TestClientsPermissions(t *testing.T) { p := &storetest.Population{} + + readOnlyAdmin := p.NewUser() + readOnlyAdmin.Admin = true + readOnlyAdminKey, _ := p.NewAPIKey(readOnlyAdmin.GetEntityIdentifiers(), ttnpb.AllReadAdminRights.GetRights()...) + readOnlyAdminKeyCreds := rpcCreds(readOnlyAdminKey) + usr1 := p.NewUser() cli1 := p.NewClient(usr1.GetOrganizationOrUserIdentifiers()) @@ -37,55 +43,82 @@ func TestClientsPermissionDenied(t *testing.T) { testWithIdentityServer(t, func(_ *IdentityServer, cc *grpc.ClientConn) { reg := ttnpb.NewClientRegistryClient(cc) - _, err := reg.Create(ctx, &ttnpb.CreateClientRequest{ - Client: &ttnpb.Client{ - Ids: &ttnpb.ClientIdentifiers{ClientId: "foo-cli"}, - }, - Collaborator: usr1.GetOrganizationOrUserIdentifiers(), - }) - if a.So(err, should.NotBeNil) { + t.Run("Invalid credentials", func(t *testing.T) { // nolint:paralleltest + _, err := reg.Create(ctx, &ttnpb.CreateClientRequest{ + Client: &ttnpb.Client{ + Ids: &ttnpb.ClientIdentifiers{ClientId: "foo-cli"}, + }, + Collaborator: usr1.GetOrganizationOrUserIdentifiers(), + }) a.So(errors.IsPermissionDenied(err), should.BeTrue) - } - _, err = reg.Get(ctx, &ttnpb.GetClientRequest{ - ClientIds: cli1.GetIds(), - FieldMask: ttnpb.FieldMask("name"), - }) - if a.So(err, should.NotBeNil) { + _, err = reg.Get(ctx, &ttnpb.GetClientRequest{ + ClientIds: cli1.GetIds(), + FieldMask: ttnpb.FieldMask("name"), + }) a.So(errors.IsUnauthenticated(err), should.BeTrue) - } - listRes, err := reg.List(ctx, &ttnpb.ListClientsRequest{ - FieldMask: ttnpb.FieldMask("name"), - }) - a.So(err, should.BeNil) - if a.So(listRes, should.NotBeNil) { - a.So(listRes.Clients, should.BeEmpty) - } + listRes, err := reg.List(ctx, &ttnpb.ListClientsRequest{ + FieldMask: ttnpb.FieldMask("name"), + }) + a.So(err, should.BeNil) + if a.So(listRes, should.NotBeNil) { + a.So(listRes.Clients, should.BeEmpty) + } - _, err = reg.List(ctx, &ttnpb.ListClientsRequest{ - Collaborator: usr1.GetOrganizationOrUserIdentifiers(), - FieldMask: ttnpb.FieldMask("name"), - }) - if a.So(err, should.NotBeNil) { + _, err = reg.List(ctx, &ttnpb.ListClientsRequest{ + Collaborator: usr1.GetOrganizationOrUserIdentifiers(), + FieldMask: ttnpb.FieldMask("name"), + }) a.So(errors.IsPermissionDenied(err), should.BeTrue) - } - _, err = reg.Update(ctx, &ttnpb.UpdateClientRequest{ - Client: &ttnpb.Client{ - Ids: cli1.GetIds(), - Name: "Updated Name", - }, - FieldMask: ttnpb.FieldMask("name"), + _, err = reg.Update(ctx, &ttnpb.UpdateClientRequest{ + Client: &ttnpb.Client{ + Ids: cli1.GetIds(), + Name: "Updated Name", + }, + FieldMask: ttnpb.FieldMask("name"), + }) + a.So(errors.IsPermissionDenied(err), should.BeTrue) + + _, err = reg.Delete(ctx, cli1.GetIds()) + a.So(errors.IsPermissionDenied(err), should.BeTrue) }) - if a.So(err, should.NotBeNil) { + + t.Run("Admin read-only", func(t *testing.T) { // nolint:paralleltest + _, err := reg.Create(ctx, &ttnpb.CreateClientRequest{ + Client: &ttnpb.Client{ + Ids: &ttnpb.ClientIdentifiers{ClientId: "foo-cli"}, + }, + Collaborator: usr1.GetOrganizationOrUserIdentifiers(), + }, readOnlyAdminKeyCreds) a.So(errors.IsPermissionDenied(err), should.BeTrue) - } - _, err = reg.Delete(ctx, cli1.GetIds()) - if a.So(err, should.NotBeNil) { + _, err = reg.Get(ctx, &ttnpb.GetClientRequest{ + ClientIds: cli1.GetIds(), + FieldMask: ttnpb.FieldMask("name"), + }, readOnlyAdminKeyCreds) + // NOTE: This will always be nil because there are no client fields which are not public. + // Meaning that even without the proper rights the response is `nil`. + a.So(err, should.BeNil) + + _, err = reg.List(ctx, &ttnpb.ListClientsRequest{ + FieldMask: ttnpb.FieldMask("name"), + }, readOnlyAdminKeyCreds) + a.So(errors.IsPermissionDenied(err), should.BeFalse) + + _, err = reg.Update(ctx, &ttnpb.UpdateClientRequest{ + Client: &ttnpb.Client{ + Ids: cli1.GetIds(), + Name: "Updated Name", + }, + FieldMask: ttnpb.FieldMask("name"), + }, readOnlyAdminKeyCreds) a.So(errors.IsPermissionDenied(err), should.BeTrue) - } + + _, err = reg.Delete(ctx, cli1.GetIds(), readOnlyAdminKeyCreds) + a.So(errors.IsPermissionDenied(err), should.BeTrue) + }) }, withPrivateTestDatabase(p)) } From b4c7c63c8b93d4b076827aaabdca421df123ecd1 Mon Sep 17 00:00:00 2001 From: Nicholas Cristofaro Date: Mon, 25 Nov 2024 15:26:43 -0300 Subject: [PATCH 27/40] is: Add read-only admin tests to email_validation_registry --- pkg/identityserver/email_validation_registry_test.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pkg/identityserver/email_validation_registry_test.go b/pkg/identityserver/email_validation_registry_test.go index f5a0ce4ffd..40a277b13f 100644 --- a/pkg/identityserver/email_validation_registry_test.go +++ b/pkg/identityserver/email_validation_registry_test.go @@ -29,6 +29,11 @@ import ( func TestEmailValidation(t *testing.T) { p := &storetest.Population{} + readOnlyAdmin := p.NewUser() + readOnlyAdmin.Admin = true + readOnlyAdminKey, _ := p.NewAPIKey(readOnlyAdmin.GetEntityIdentifiers(), ttnpb.AllReadAdminRights.GetRights()...) + readOnlyAdminKeyCreds := rpcCreds(readOnlyAdminKey) + usr1 := p.NewUser() usr1.PrimaryEmailAddress = "usr1@email.com" usr1Key, _ := p.NewAPIKey(usr1.GetEntityIdentifiers(), ttnpb.Right_RIGHT_ALL) @@ -58,6 +63,11 @@ func TestEmailValidation(t *testing.T) { a.So(err, should.NotBeNil) a.So(errors.IsPermissionDenied(err), should.BeTrue) + // Only reader rights. + _, err = reg.RequestValidation(ctx, usr1.Ids, readOnlyAdminKeyCreds) + a.So(err, should.NotBeNil) + a.So(errors.IsPermissionDenied(err), should.BeTrue) + // Proper Request. validation, err := reg.RequestValidation(ctx, usr1.Ids, usr1Creds) a.So(err, should.BeNil) From a75fdd8bf465b8e295b933558baf44aecfb02085 Mon Sep 17 00:00:00 2001 From: Nicholas Cristofaro Date: Mon, 25 Nov 2024 15:35:26 -0300 Subject: [PATCH 28/40] is: Add read-only admin tests to end_device_registry --- .../end_device_registry_test.go | 176 ++++++++++++++---- 1 file changed, 136 insertions(+), 40 deletions(-) diff --git a/pkg/identityserver/end_device_registry_test.go b/pkg/identityserver/end_device_registry_test.go index c01de47556..77de955958 100644 --- a/pkg/identityserver/end_device_registry_test.go +++ b/pkg/identityserver/end_device_registry_test.go @@ -30,61 +30,110 @@ import ( const noOfDevices = 3 -func TestEndDevicesPermissionDenied(t *testing.T) { +func TestEndDevicesPermissions(t *testing.T) { p := &storetest.Population{} usr1 := p.NewUser() app1 := p.NewApplication(usr1.GetOrganizationOrUserIdentifiers()) dev1 := p.NewEndDevice(app1.GetIds()) + readOnlyAdmin := p.NewUser() + readOnlyAdmin.Admin = true + readOnlyAdminKey, _ := p.NewAPIKey(readOnlyAdmin.GetEntityIdentifiers(), ttnpb.AllReadAdminRights.GetRights()...) + readOnlyAdminKeyCreds := rpcCreds(readOnlyAdminKey) + t.Parallel() a, ctx := test.New(t) testWithIdentityServer(t, func(_ *IdentityServer, cc *grpc.ClientConn) { reg := ttnpb.NewEndDeviceRegistryClient(cc) - _, err := reg.Create(ctx, &ttnpb.CreateEndDeviceRequest{ - EndDevice: &ttnpb.EndDevice{ - Ids: &ttnpb.EndDeviceIdentifiers{ - ApplicationIds: app1.GetIds(), - DeviceId: "foo-dev", + t.Run("Invalid credentials", func(t *testing.T) { // nolint:paralleltest + _, err := reg.Create(ctx, &ttnpb.CreateEndDeviceRequest{ + EndDevice: &ttnpb.EndDevice{ + Ids: &ttnpb.EndDeviceIdentifiers{ + ApplicationIds: app1.GetIds(), + DeviceId: "foo-dev", + }, }, - }, - }) - if a.So(err, should.NotBeNil) { - a.So(errors.IsPermissionDenied(err), should.BeTrue) - } + }) + if a.So(err, should.NotBeNil) { + a.So(errors.IsPermissionDenied(err), should.BeTrue) + } - _, err = reg.Get(ctx, &ttnpb.GetEndDeviceRequest{ - EndDeviceIds: dev1.GetIds(), - FieldMask: ttnpb.FieldMask("name"), - }) - if a.So(err, should.NotBeNil) { - a.So(errors.IsPermissionDenied(err), should.BeTrue) - } + _, err = reg.Get(ctx, &ttnpb.GetEndDeviceRequest{ + EndDeviceIds: dev1.GetIds(), + FieldMask: ttnpb.FieldMask("name"), + }) + if a.So(err, should.NotBeNil) { + a.So(errors.IsPermissionDenied(err), should.BeTrue) + } - _, err = reg.List(ctx, &ttnpb.ListEndDevicesRequest{ - ApplicationIds: app1.GetIds(), - FieldMask: ttnpb.FieldMask("name"), - }) - if a.So(err, should.NotBeNil) { - a.So(errors.IsPermissionDenied(err), should.BeTrue) - } + _, err = reg.List(ctx, &ttnpb.ListEndDevicesRequest{ + ApplicationIds: app1.GetIds(), + FieldMask: ttnpb.FieldMask("name"), + }) + if a.So(err, should.NotBeNil) { + a.So(errors.IsPermissionDenied(err), should.BeTrue) + } - _, err = reg.Update(ctx, &ttnpb.UpdateEndDeviceRequest{ - EndDevice: &ttnpb.EndDevice{ - Ids: dev1.GetIds(), - Name: "Updated Name", - }, - FieldMask: ttnpb.FieldMask("name"), + _, err = reg.Update(ctx, &ttnpb.UpdateEndDeviceRequest{ + EndDevice: &ttnpb.EndDevice{ + Ids: dev1.GetIds(), + Name: "Updated Name", + }, + FieldMask: ttnpb.FieldMask("name"), + }) + if a.So(err, should.NotBeNil) { + a.So(errors.IsPermissionDenied(err), should.BeTrue) + } + + _, err = reg.Delete(ctx, dev1.GetIds()) + if a.So(err, should.NotBeNil) { + a.So(errors.IsPermissionDenied(err), should.BeTrue) + } }) - if a.So(err, should.NotBeNil) { - a.So(errors.IsPermissionDenied(err), should.BeTrue) - } - _, err = reg.Delete(ctx, dev1.GetIds()) - if a.So(err, should.NotBeNil) { - a.So(errors.IsPermissionDenied(err), should.BeTrue) - } + t.Run("Admin read-only", func(t *testing.T) { // nolint:paralleltest + _, err := reg.Create(ctx, &ttnpb.CreateEndDeviceRequest{ + EndDevice: &ttnpb.EndDevice{ + Ids: &ttnpb.EndDeviceIdentifiers{ + ApplicationIds: app1.GetIds(), + DeviceId: "foo-dev", + }, + }, + }, readOnlyAdminKeyCreds) + if a.So(err, should.NotBeNil) { + a.So(errors.IsPermissionDenied(err), should.BeTrue) + } + + _, err = reg.Get(ctx, &ttnpb.GetEndDeviceRequest{ + EndDeviceIds: dev1.GetIds(), + FieldMask: ttnpb.FieldMask("name"), + }, readOnlyAdminKeyCreds) + a.So(errors.IsPermissionDenied(err), should.BeFalse) + + _, err = reg.List(ctx, &ttnpb.ListEndDevicesRequest{ + ApplicationIds: app1.GetIds(), + FieldMask: ttnpb.FieldMask("name"), + }, readOnlyAdminKeyCreds) + a.So(errors.IsPermissionDenied(err), should.BeFalse) + + _, err = reg.Update(ctx, &ttnpb.UpdateEndDeviceRequest{ + EndDevice: &ttnpb.EndDevice{ + Ids: dev1.GetIds(), + Name: "Updated Name", + }, + FieldMask: ttnpb.FieldMask("name"), + }, readOnlyAdminKeyCreds) + if a.So(err, should.NotBeNil) { + a.So(errors.IsPermissionDenied(err), should.BeTrue) + } + + _, err = reg.Delete(ctx, dev1.GetIds()) + if a.So(err, should.NotBeNil) { + a.So(errors.IsPermissionDenied(err), should.BeTrue) + } + }) }, withPrivateTestDatabase(p)) } @@ -219,7 +268,7 @@ func TestEndDevicesPagination(t *testing.T) { }, withPrivateTestDatabase(p)) } -func TestEndDevicesBatchOperations(t *testing.T) { +func TestEndDevicesBatchOperationsPermissions(t *testing.T) { t.Parallel() a, ctx := test.New(t) p := &storetest.Population{} @@ -246,6 +295,11 @@ func TestEndDevicesBatchOperations(t *testing.T) { writeKey, _ := p.NewAPIKey(usr1.GetEntityIdentifiers(), ttnpb.Right_RIGHT_APPLICATION_DEVICES_WRITE) writeCreds := rpcCreds(writeKey) + readOnlyAdmin := p.NewUser() + readOnlyAdmin.Admin = true + readOnlyAdminKey, _ := p.NewAPIKey(readOnlyAdmin.GetEntityIdentifiers(), ttnpb.AllReadAdminRights.GetRights()...) + readOnlyAdminKeyCreds := rpcCreds(readOnlyAdminKey) + testWithIdentityServer(t, func(is *IdentityServer, cc *grpc.ClientConn) { reg := ttnpb.NewEndDeviceBatchRegistryClient(cc) @@ -276,8 +330,50 @@ func TestEndDevicesBatchOperations(t *testing.T) { }, writeCreds) a.So(errors.IsPermissionDenied(err), should.BeTrue) + t.Run("Admin read-only", func(t *testing.T) { // nolint:paralleltest + devs, err := reg.Get(ctx, &ttnpb.BatchGetEndDevicesRequest{ + ApplicationIds: app1.GetIds(), + DeviceIds: devIDs, + }, readOnlyAdminKeyCreds) + a.So(err, should.BeNil) + a.So(devs, should.NotBeNil) + a.So(devs.GetEndDevices(), should.HaveLength, noOfDevices) + }) + }, withPrivateTestDatabase(p)) +} + +func TestEndDevicesBatchOperations(t *testing.T) { + t.Parallel() + a, ctx := test.New(t) + p := &storetest.Population{} + usr1 := p.NewUser() + app1 := p.NewApplication(usr1.GetOrganizationOrUserIdentifiers()) + devIDs := make([]string, 0, noOfDevices) + for i := 0; i < noOfDevices; i++ { + dev := p.NewEndDevice(app1.GetIds()) + dev.Attributes = map[string]string{ + "foo": "bar", + } + dev.Locations = map[string]*ttnpb.Location{ + "foo": { + Latitude: 1, + Longitude: 2, + Altitude: 3, + }, + } + devIDs = append(devIDs, dev.GetIds().DeviceId) + } + readKey, _ := p.NewAPIKey(usr1.GetEntityIdentifiers(), ttnpb.Right_RIGHT_APPLICATION_DEVICES_READ) + readCreds := rpcCreds(readKey) + + writeKey, _ := p.NewAPIKey(usr1.GetEntityIdentifiers(), ttnpb.Right_RIGHT_APPLICATION_DEVICES_WRITE) + writeCreds := rpcCreds(writeKey) + + testWithIdentityServer(t, func(is *IdentityServer, cc *grpc.ClientConn) { + reg := ttnpb.NewEndDeviceBatchRegistryClient(cc) + // Unknown device ignored. - _, err = reg.Get(ctx, &ttnpb.BatchGetEndDevicesRequest{ + _, err := reg.Get(ctx, &ttnpb.BatchGetEndDevicesRequest{ ApplicationIds: app1.GetIds(), DeviceIds: []string{ "unknown", From 60f66dc4a6a8e2ef3bb867e452ff14c9ab86ba68 Mon Sep 17 00:00:00 2001 From: Nicholas Cristofaro Date: Mon, 25 Nov 2024 15:37:06 -0300 Subject: [PATCH 29/40] is: Add read-only admin tests to entity_access --- pkg/identityserver/entity_access_test.go | 34 +++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/pkg/identityserver/entity_access_test.go b/pkg/identityserver/entity_access_test.go index d6173444a4..2dfe01a05e 100644 --- a/pkg/identityserver/entity_access_test.go +++ b/pkg/identityserver/entity_access_test.go @@ -54,6 +54,12 @@ func TestEntityAccess(t *testing.T) { adminUsrKey, _ := p.NewAPIKey(adminUsr.GetEntityIdentifiers(), ttnpb.Right_RIGHT_ALL) adminUsrCreds := rpcCreds(adminUsrKey) + readOnlyAdmin := p.NewUser() + readOnlyAdmin.Admin = true + readOnlyAdmin.UniversalRights = ttnpb.AllReadAdminRights.GetRights() + readOnlyAdminKey, _ := p.NewAPIKey(readOnlyAdmin.GetEntityIdentifiers(), ttnpb.Right_RIGHT_ALL) + readOnlyAdminKeyCreds := rpcCreds(readOnlyAdminKey) + expiredKey, storedKey := p.NewAPIKey(adminUsr.GetEntityIdentifiers(), ttnpb.Right_RIGHT_ALL) storedKey.ExpiresAt = timestamppb.New(time.Now().Add(-10 * time.Minute)) expiredCreds := rpcCreds(expiredKey) @@ -72,7 +78,14 @@ func TestEntityAccess(t *testing.T) { a.So(md.Get("warning"), should.Contain, "Restricted rights while account pending") if a.So(authInfo, should.NotBeNil) && a.So(authInfo.GetApiKey(), should.NotBeNil) { rights := ttnpb.RightsFrom(authInfo.GetApiKey().GetApiKey().GetRights()...) - a.So(rights.IncludesAll(ttnpb.Right_RIGHT_USER_INFO, ttnpb.Right_RIGHT_USER_SETTINGS_BASIC, ttnpb.Right_RIGHT_USER_DELETE), should.BeTrue) + a.So( + rights.IncludesAll( + ttnpb.Right_RIGHT_USER_INFO, + ttnpb.Right_RIGHT_USER_SETTINGS_BASIC, + ttnpb.Right_RIGHT_USER_DELETE, + ), + should.BeTrue, + ) } } }) @@ -117,6 +130,25 @@ func TestEntityAccess(t *testing.T) { } }) + t.Run("Read-only Admin User", func(t *testing.T) { + a, ctx := test.New(t) + var md metadata.MD + authInfo, err := cli.AuthInfo(ctx, ttnpb.Empty, readOnlyAdminKeyCreds, grpc.Header(&md)) + if a.So(err, should.BeNil) && a.So(authInfo, should.NotBeNil) { + a.So(authInfo.GetIsAdmin(), should.BeTrue) + a.So(authInfo.GetUniversalRights().GetRights(), should.NotBeEmpty) + a.So( + authInfo.GetUniversalRights().IncludesAll(ttnpb.AllReadAdminRights.GetRights()...), + should.BeTrue, + ) + a.So( + authInfo.GetUniversalRights().IncludesAll(ttnpb.Right_RIGHT_USER_APPLICATIONS_CREATE), + should.BeFalse, + ) + + } + }) + t.Run("Cluster Peer", func(t *testing.T) { a, ctx := test.New(t) var md metadata.MD From 894ea7ac1423a98f9fd3d49aa652e70e604bf535 Mon Sep 17 00:00:00 2001 From: Nicholas Cristofaro Date: Mon, 25 Nov 2024 15:43:01 -0300 Subject: [PATCH 30/40] is: Add read-only admin tests to gateway_access --- pkg/identityserver/gateway_access_test.go | 262 ++++++++++++++++++---- 1 file changed, 214 insertions(+), 48 deletions(-) diff --git a/pkg/identityserver/gateway_access_test.go b/pkg/identityserver/gateway_access_test.go index 75a265b9b0..ab7bf70478 100644 --- a/pkg/identityserver/gateway_access_test.go +++ b/pkg/identityserver/gateway_access_test.go @@ -26,6 +26,127 @@ import ( "google.golang.org/grpc" ) +func TestGatewayAPIKeysPermissions(t *testing.T) { // nolint:gocyclo + p := &storetest.Population{} + + readOnlyAdmin := p.NewUser() + readOnlyAdmin.Admin = true + readOnlyAdminKey, _ := p.NewAPIKey(readOnlyAdmin.GetEntityIdentifiers(), ttnpb.AllReadAdminRights.GetRights()...) + readOnlyAdminKeyCreds := rpcCreds(readOnlyAdminKey) + + usr1 := p.NewUser() + gtw1 := p.NewGateway(usr1.GetOrganizationOrUserIdentifiers()) + + gtwKey, _ := p.NewAPIKey(gtw1.GetEntityIdentifiers(), + ttnpb.Right_RIGHT_GATEWAY_INFO, + ttnpb.Right_RIGHT_GATEWAY_LINK, + ) + gtwCreds := rpcCreds(gtwKey) + + t.Parallel() + a, ctx := test.New(t) + + testWithIdentityServer(t, func(is *IdentityServer, cc *grpc.ClientConn) { + is.config.AdminRights.All = true + + reg := ttnpb.NewGatewayAccessClient(cc) + + t.Run("Invalid credentials", func(t *testing.T) { // nolint:paralleltest + for _, opts := range [][]grpc.CallOption{nil, {gtwCreds}} { + created, err := reg.CreateAPIKey(ctx, &ttnpb.CreateGatewayAPIKeyRequest{ + GatewayIds: gtw1.GetIds(), + Name: "api-key-name", + Rights: []ttnpb.Right{ttnpb.Right_RIGHT_GATEWAY_INFO}, + }, opts...) + if a.So(err, should.NotBeNil) && a.So(errors.IsPermissionDenied(err), should.BeTrue) { + a.So(created, should.BeNil) + } + + list, err := reg.ListAPIKeys(ctx, &ttnpb.ListGatewayAPIKeysRequest{ + GatewayIds: gtw1.GetIds(), + }, opts...) + if a.So(err, should.NotBeNil) && a.So(errors.IsPermissionDenied(err), should.BeTrue) { + a.So(list, should.BeNil) + } + + got, err := reg.GetAPIKey(ctx, &ttnpb.GetGatewayAPIKeyRequest{ + GatewayIds: gtw1.GetIds(), + KeyId: gtwKey.GetId(), + }, opts...) + if a.So(err, should.NotBeNil) && a.So(errors.IsPermissionDenied(err), should.BeTrue) { + a.So(got, should.BeNil) + } + + updated, err := reg.UpdateAPIKey(ctx, &ttnpb.UpdateGatewayAPIKeyRequest{ + GatewayIds: gtw1.GetIds(), + ApiKey: &ttnpb.APIKey{ + Id: gtwKey.GetId(), + Name: "api-key-name-updated", + }, + FieldMask: ttnpb.FieldMask("name"), + }, opts...) + if a.So(err, should.NotBeNil) && a.So(errors.IsPermissionDenied(err), should.BeTrue) { + a.So(updated, should.BeNil) + } + + _, err = reg.DeleteAPIKey(ctx, &ttnpb.DeleteGatewayAPIKeyRequest{ + GatewayIds: gtw1.GetIds(), + KeyId: created.GetId(), + }, opts...) + if !a.So(errors.IsPermissionDenied(err), should.BeTrue) { + t.FailNow() + } + } + }) + + t.Run("Admin read-only", func(t *testing.T) { // nolint:paralleltest + _, err := reg.CreateAPIKey(ctx, &ttnpb.CreateGatewayAPIKeyRequest{ + GatewayIds: gtw1.GetIds(), + Name: "api-key-name", + Rights: []ttnpb.Right{ttnpb.Right_RIGHT_GATEWAY_INFO}, + }, readOnlyAdminKeyCreds) + if a.So(err, should.NotBeNil) { + a.So(errors.IsPermissionDenied(err), should.BeTrue) + } + + _, err = reg.ListAPIKeys(ctx, &ttnpb.ListGatewayAPIKeysRequest{ + GatewayIds: gtw1.GetIds(), + }, readOnlyAdminKeyCreds) + if a.So(err, should.NotBeNil) { + a.So(errors.IsPermissionDenied(err), should.BeTrue) + } + + _, err = reg.GetAPIKey(ctx, &ttnpb.GetGatewayAPIKeyRequest{ + GatewayIds: gtw1.GetIds(), + KeyId: gtwKey.GetId(), + }, readOnlyAdminKeyCreds) + if a.So(err, should.NotBeNil) { + a.So(errors.IsPermissionDenied(err), should.BeTrue) + } + + _, err = reg.UpdateAPIKey(ctx, &ttnpb.UpdateGatewayAPIKeyRequest{ + GatewayIds: gtw1.GetIds(), + ApiKey: &ttnpb.APIKey{ + Id: gtwKey.GetId(), + Name: "api-key-name-updated", + }, + FieldMask: ttnpb.FieldMask("name"), + }, readOnlyAdminKeyCreds) + if a.So(err, should.NotBeNil) { + a.So(errors.IsPermissionDenied(err), should.BeTrue) + } + + _, err = reg.DeleteAPIKey(ctx, &ttnpb.DeleteGatewayAPIKeyRequest{ + GatewayIds: gtw1.GetIds(), + KeyId: "unknown-key", + }, readOnlyAdminKeyCreds) + if a.So(err, should.NotBeNil) { + a.So(errors.IsPermissionDenied(err), should.BeTrue) + } + }) + }, withPrivateTestDatabase(p)) +} + func TestGatewayAPIKeys(t *testing.T) { // nolint:gocyclo p := &storetest.Population{} @@ -50,7 +171,6 @@ func TestGatewayAPIKeys(t *testing.T) { // nolint:gocyclo ttnpb.Right_RIGHT_GATEWAY_INFO, ttnpb.Right_RIGHT_GATEWAY_LINK, ) - gtwCreds := rpcCreds(gtwKey) t.Parallel() a, ctx := test.New(t) @@ -147,53 +267,6 @@ func TestGatewayAPIKeys(t *testing.T) { // nolint:gocyclo }) } - // API Key CRUD with different invalid credentials. - for _, opts := range [][]grpc.CallOption{nil, {gtwCreds}} { - created, err := reg.CreateAPIKey(ctx, &ttnpb.CreateGatewayAPIKeyRequest{ - GatewayIds: gtw1.GetIds(), - Name: "api-key-name", - Rights: []ttnpb.Right{ttnpb.Right_RIGHT_GATEWAY_INFO}, - }, opts...) - if a.So(err, should.NotBeNil) && a.So(errors.IsPermissionDenied(err), should.BeTrue) { - a.So(created, should.BeNil) - } - - list, err := reg.ListAPIKeys(ctx, &ttnpb.ListGatewayAPIKeysRequest{ - GatewayIds: gtw1.GetIds(), - }, opts...) - if a.So(err, should.NotBeNil) && a.So(errors.IsPermissionDenied(err), should.BeTrue) { - a.So(list, should.BeNil) - } - - got, err := reg.GetAPIKey(ctx, &ttnpb.GetGatewayAPIKeyRequest{ - GatewayIds: gtw1.GetIds(), - KeyId: gtwKey.GetId(), - }, opts...) - if a.So(err, should.NotBeNil) && a.So(errors.IsPermissionDenied(err), should.BeTrue) { - a.So(got, should.BeNil) - } - - updated, err := reg.UpdateAPIKey(ctx, &ttnpb.UpdateGatewayAPIKeyRequest{ - GatewayIds: gtw1.GetIds(), - ApiKey: &ttnpb.APIKey{ - Id: gtwKey.GetId(), - Name: "api-key-name-updated", - }, - FieldMask: ttnpb.FieldMask("name"), - }, opts...) - if a.So(err, should.NotBeNil) && a.So(errors.IsPermissionDenied(err), should.BeTrue) { - a.So(updated, should.BeNil) - } - - _, err = reg.DeleteAPIKey(ctx, &ttnpb.DeleteGatewayAPIKeyRequest{ - GatewayIds: gtw1.GetIds(), - KeyId: created.GetId(), - }, opts...) - if !a.So(errors.IsPermissionDenied(err), should.BeTrue) { - t.FailNow() - } - } - // API Key CRUD with different valid credentials. for _, opts := range [][]grpc.CallOption{{adminCreds}, {usr1Creds}, {limitedCreds}} { created, err := reg.CreateAPIKey(ctx, &ttnpb.CreateGatewayAPIKeyRequest{ @@ -287,6 +360,99 @@ func TestGatewayAPIKeys(t *testing.T) { // nolint:gocyclo }, withPrivateTestDatabase(p)) } +func TestGatewayCollaboratorsPermissions(t *testing.T) { // nolint:gocyclo + p := &storetest.Population{} + + usr1 := p.NewUser() + gtw1 := p.NewGateway(usr1.GetOrganizationOrUserIdentifiers()) + + gtwKey, _ := p.NewAPIKey(gtw1.GetEntityIdentifiers(), + ttnpb.Right_RIGHT_GATEWAY_INFO, + ttnpb.Right_RIGHT_GATEWAY_LINK, + ) + gtwCreds := rpcCreds(gtwKey) + + readOnlyAdmin := p.NewUser() + readOnlyAdmin.Admin = true + readOnlyAdminKey, _ := p.NewAPIKey(readOnlyAdmin.GetEntityIdentifiers(), ttnpb.AllReadAdminRights.GetRights()...) + readOnlyAdminKeyCreds := rpcCreds(readOnlyAdminKey) + + usr2 := p.NewUser() + p.NewMembership( + usr2.GetOrganizationOrUserIdentifiers(), + gtw1.GetEntityIdentifiers(), + ttnpb.Right_RIGHT_GATEWAY_INFO, + ttnpb.Right_RIGHT_GATEWAY_LINK, + ) + + t.Parallel() + a, ctx := test.New(t) + + testWithIdentityServer(t, func(is *IdentityServer, cc *grpc.ClientConn) { + is.config.AdminRights.All = true + + reg := ttnpb.NewGatewayAccessClient(cc) + + t.Run("Permission denied", func(t *testing.T) { // nolint:paralleltest + for _, opts := range [][]grpc.CallOption{nil, {gtwCreds}} { + _, err := reg.SetCollaborator(ctx, &ttnpb.SetGatewayCollaboratorRequest{ + GatewayIds: gtw1.GetIds(), + Collaborator: &ttnpb.Collaborator{ + Ids: usr2.GetOrganizationOrUserIdentifiers(), + Rights: []ttnpb.Right{ttnpb.Right_RIGHT_GATEWAY_INFO}, + }, + }, opts...) + if a.So(err, should.NotBeNil) { + a.So(errors.IsPermissionDenied(err), should.BeTrue) + } + + got, err := reg.GetCollaborator(ctx, &ttnpb.GetGatewayCollaboratorRequest{ + GatewayIds: gtw1.GetIds(), + Collaborator: usr2.GetOrganizationOrUserIdentifiers(), + }, opts...) + if a.So(err, should.NotBeNil) && a.So(errors.IsPermissionDenied(err), should.BeTrue) { + a.So(got, should.BeNil) + } + + // ListCollaborators without credentials. + list, err := reg.ListCollaborators(ctx, &ttnpb.ListGatewayCollaboratorsRequest{ + GatewayIds: gtw1.GetIds(), + }) + if a.So(err, should.NotBeNil) && a.So(errors.IsUnauthenticated(err), should.BeTrue) { + a.So(list, should.BeNil) + } + } + }) + + t.Run("Admin read-only", func(t *testing.T) { // nolint:paralleltest + _, err := reg.SetCollaborator(ctx, &ttnpb.SetGatewayCollaboratorRequest{ + GatewayIds: gtw1.GetIds(), + Collaborator: &ttnpb.Collaborator{ + Ids: usr2.GetOrganizationOrUserIdentifiers(), + Rights: []ttnpb.Right{ttnpb.Right_RIGHT_GATEWAY_INFO}, + }, + }, readOnlyAdminKeyCreds) + if a.So(err, should.NotBeNil) { + a.So(errors.IsPermissionDenied(err), should.BeTrue) + } + + _, err = reg.GetCollaborator(ctx, &ttnpb.GetGatewayCollaboratorRequest{ + GatewayIds: gtw1.GetIds(), + Collaborator: usr2.GetOrganizationOrUserIdentifiers(), + }, readOnlyAdminKeyCreds) + if a.So(err, should.NotBeNil) { + a.So(errors.IsPermissionDenied(err), should.BeTrue) + } + + // ListCollaborators without credentials. + _, err = reg.ListCollaborators(ctx, &ttnpb.ListGatewayCollaboratorsRequest{ + GatewayIds: gtw1.GetIds(), + }, readOnlyAdminKeyCreds) + a.So(errors.IsPermissionDenied(err), should.BeFalse) + }) + }, withPrivateTestDatabase(p)) +} + func TestGatewayCollaborators(t *testing.T) { // nolint:gocyclo p := &storetest.Population{} From 41e2856264ad424b7aff7388e793204367753122 Mon Sep 17 00:00:00 2001 From: Nicholas Cristofaro Date: Mon, 25 Nov 2024 16:01:36 -0300 Subject: [PATCH 31/40] is: Add read-only admin tests to gateway_registry --- pkg/identityserver/gateway_registry_test.go | 151 ++++++++++++++------ 1 file changed, 107 insertions(+), 44 deletions(-) diff --git a/pkg/identityserver/gateway_registry_test.go b/pkg/identityserver/gateway_registry_test.go index 6d768985f4..6b1b158951 100644 --- a/pkg/identityserver/gateway_registry_test.go +++ b/pkg/identityserver/gateway_registry_test.go @@ -31,66 +31,118 @@ import ( const noOfGateways = 3 -func TestGatewaysPermissionDenied(t *testing.T) { +func TestGatewaysPermissions(t *testing.T) { p := &storetest.Population{} usr1 := p.NewUser() gtw1 := p.NewGateway(usr1.GetOrganizationOrUserIdentifiers()) + readOnlyAdmin := p.NewUser() + readOnlyAdmin.Admin = true + readOnlyAdminKey, _ := p.NewAPIKey(readOnlyAdmin.GetEntityIdentifiers(), ttnpb.AllReadAdminRights.GetRights()...) + readOnlyAdminKeyCreds := rpcCreds(readOnlyAdminKey) + t.Parallel() a, ctx := test.New(t) testWithIdentityServer(t, func(_ *IdentityServer, cc *grpc.ClientConn) { reg := ttnpb.NewGatewayRegistryClient(cc) - _, err := reg.Create(ctx, &ttnpb.CreateGatewayRequest{ - Gateway: &ttnpb.Gateway{ - Ids: &ttnpb.GatewayIdentifiers{GatewayId: "foo-gtw"}, - }, - Collaborator: usr1.GetOrganizationOrUserIdentifiers(), - }) - if a.So(err, should.NotBeNil) { - a.So(errors.IsPermissionDenied(err), should.BeTrue) - } + t.Run("Invalid credentials", func(t *testing.T) { // nolint:paralleltest + _, err := reg.Create(ctx, &ttnpb.CreateGatewayRequest{ + Gateway: &ttnpb.Gateway{ + Ids: &ttnpb.GatewayIdentifiers{GatewayId: "foo-gtw"}, + }, + Collaborator: usr1.GetOrganizationOrUserIdentifiers(), + }) + if a.So(err, should.NotBeNil) { + a.So(errors.IsPermissionDenied(err), should.BeTrue) + } - _, err = reg.Get(ctx, &ttnpb.GetGatewayRequest{ - GatewayIds: gtw1.GetIds(), - FieldMask: ttnpb.FieldMask("name"), - }) - if a.So(err, should.NotBeNil) { - a.So(errors.IsUnauthenticated(err), should.BeTrue) - } + _, err = reg.Get(ctx, &ttnpb.GetGatewayRequest{ + GatewayIds: gtw1.GetIds(), + FieldMask: ttnpb.FieldMask("name"), + }) + if a.So(err, should.NotBeNil) { + a.So(errors.IsUnauthenticated(err), should.BeTrue) + } - listRes, err := reg.List(ctx, &ttnpb.ListGatewaysRequest{ - FieldMask: ttnpb.FieldMask("name"), - }) - a.So(err, should.BeNil) - if a.So(listRes, should.NotBeNil) { - a.So(listRes.Gateways, should.BeEmpty) - } + listRes, err := reg.List(ctx, &ttnpb.ListGatewaysRequest{ + FieldMask: ttnpb.FieldMask("name"), + }) + a.So(err, should.BeNil) + if a.So(listRes, should.NotBeNil) { + a.So(listRes.Gateways, should.BeEmpty) + } - _, err = reg.List(ctx, &ttnpb.ListGatewaysRequest{ - Collaborator: usr1.GetOrganizationOrUserIdentifiers(), - FieldMask: ttnpb.FieldMask("name"), - }) - if a.So(err, should.NotBeNil) { - a.So(errors.IsPermissionDenied(err), should.BeTrue) - } + _, err = reg.List(ctx, &ttnpb.ListGatewaysRequest{ + Collaborator: usr1.GetOrganizationOrUserIdentifiers(), + FieldMask: ttnpb.FieldMask("name"), + }) + if a.So(err, should.NotBeNil) { + a.So(errors.IsPermissionDenied(err), should.BeTrue) + } - _, err = reg.Update(ctx, &ttnpb.UpdateGatewayRequest{ - Gateway: &ttnpb.Gateway{ - Ids: gtw1.GetIds(), - Name: "Updated Name", - }, - FieldMask: ttnpb.FieldMask("name"), + _, err = reg.Update(ctx, &ttnpb.UpdateGatewayRequest{ + Gateway: &ttnpb.Gateway{ + Ids: gtw1.GetIds(), + Name: "Updated Name", + }, + FieldMask: ttnpb.FieldMask("name"), + }) + if a.So(err, should.NotBeNil) { + a.So(errors.IsPermissionDenied(err), should.BeTrue) + } + + _, err = reg.Delete(ctx, gtw1.GetIds()) + if a.So(err, should.NotBeNil) { + a.So(errors.IsPermissionDenied(err), should.BeTrue) + } }) - if a.So(err, should.NotBeNil) { - a.So(errors.IsPermissionDenied(err), should.BeTrue) - } - _, err = reg.Delete(ctx, gtw1.GetIds()) - if a.So(err, should.NotBeNil) { - a.So(errors.IsPermissionDenied(err), should.BeTrue) - } + t.Run("Admin read-only", func(t *testing.T) { // nolint:paralleltest + _, err := reg.Create(ctx, &ttnpb.CreateGatewayRequest{ + Gateway: &ttnpb.Gateway{ + Ids: &ttnpb.GatewayIdentifiers{GatewayId: "foo-gtw"}, + }, + Collaborator: usr1.GetOrganizationOrUserIdentifiers(), + }, readOnlyAdminKeyCreds) + if a.So(err, should.NotBeNil) { + a.So(errors.IsPermissionDenied(err), should.BeTrue) + } + + _, err = reg.Get(ctx, &ttnpb.GetGatewayRequest{ + GatewayIds: gtw1.GetIds(), + FieldMask: ttnpb.FieldMask("name"), + }, readOnlyAdminKeyCreds) + a.So(errors.IsPermissionDenied(err), should.BeFalse) + + _, err = reg.List(ctx, &ttnpb.ListGatewaysRequest{ + FieldMask: ttnpb.FieldMask("name"), + }, readOnlyAdminKeyCreds) + a.So(errors.IsPermissionDenied(err), should.BeFalse) + + _, err = reg.List(ctx, &ttnpb.ListGatewaysRequest{ + Collaborator: usr1.GetOrganizationOrUserIdentifiers(), + FieldMask: ttnpb.FieldMask("name"), + }, readOnlyAdminKeyCreds) + a.So(errors.IsPermissionDenied(err), should.BeFalse) + + _, err = reg.Update(ctx, &ttnpb.UpdateGatewayRequest{ + Gateway: &ttnpb.Gateway{ + Ids: gtw1.GetIds(), + Name: "Updated Name", + }, + FieldMask: ttnpb.FieldMask("name"), + }, readOnlyAdminKeyCreds) + if a.So(err, should.NotBeNil) { + a.So(errors.IsPermissionDenied(err), should.BeTrue) + } + + _, err = reg.Delete(ctx, gtw1.GetIds(), readOnlyAdminKeyCreds) + if a.So(err, should.NotBeNil) { + a.So(errors.IsPermissionDenied(err), should.BeTrue) + } + }) }, withPrivateTestDatabase(p)) } @@ -396,6 +448,11 @@ func TestGatewayBatchOperations(t *testing.T) { usr2Key, _ := p.NewAPIKey(usr2.GetEntityIdentifiers(), ttnpb.Right_RIGHT_ALL) usr2Creds := rpcCreds(usr2Key) + readOnlyAdmin := p.NewUser() + readOnlyAdmin.Admin = true + readOnlyAdminKey, _ := p.NewAPIKey(readOnlyAdmin.GetEntityIdentifiers(), ttnpb.AllReadAdminRights.GetRights()...) + readOnlyAdminKeyCreds := rpcCreds(readOnlyAdminKey) + testWithIdentityServer(t, func(is *IdentityServer, cc *grpc.ClientConn) { reg := ttnpb.NewGatewayBatchRegistryClient(cc) readReg := ttnpb.NewGatewayRegistryClient(cc) @@ -419,6 +476,12 @@ func TestGatewayBatchOperations(t *testing.T) { }, limitedCreds) a.So(errors.IsPermissionDenied(err), should.BeTrue) + // Read-only admin rights. + _, err = reg.Delete(ctx, &ttnpb.BatchDeleteGatewaysRequest{ + GatewayIds: gtwIDs, + }, readOnlyAdminKeyCreds) + a.So(errors.IsPermissionDenied(err), should.BeTrue) + // User without rights on gateways. _, err = reg.Delete(ctx, &ttnpb.BatchDeleteGatewaysRequest{ GatewayIds: gtwIDs, From 98989d67cb05aff57dd165c8d39efd7766e056bc Mon Sep 17 00:00:00 2001 From: Nicholas Cristofaro Date: Mon, 25 Nov 2024 16:05:46 -0300 Subject: [PATCH 32/40] is: Add read-only admin tests to organization_access --- .../organization_access_test.go | 238 ++++++++++++------ 1 file changed, 160 insertions(+), 78 deletions(-) diff --git a/pkg/identityserver/organization_access_test.go b/pkg/identityserver/organization_access_test.go index b11c511d0d..6d36868fa0 100644 --- a/pkg/identityserver/organization_access_test.go +++ b/pkg/identityserver/organization_access_test.go @@ -26,6 +26,80 @@ import ( "google.golang.org/grpc" ) +func TestOrganizationAPIKeysPermissions(t *testing.T) { // nolint:gocyclo + p := &storetest.Population{} + + readOnlyAdmin := p.NewUser() + readOnlyAdmin.Admin = true + readOnlyAdminKey, _ := p.NewAPIKey(readOnlyAdmin.GetEntityIdentifiers(), ttnpb.AllReadAdminRights.GetRights()...) + readOnlyAdminKeyCreds := rpcCreds(readOnlyAdminKey) + + usr1 := p.NewUser() + org1 := p.NewOrganization(usr1.GetOrganizationOrUserIdentifiers()) + orgKey, _ := p.NewAPIKey(org1.GetEntityIdentifiers(), + ttnpb.Right_RIGHT_ORGANIZATION_INFO, + ttnpb.Right_RIGHT_ORGANIZATION_APPLICATIONS_LIST, + ) + orgCreds := rpcCreds(orgKey) + + t.Parallel() + a, ctx := test.New(t) + + testWithIdentityServer(t, func(is *IdentityServer, cc *grpc.ClientConn) { + is.config.AdminRights.All = true + + reg := ttnpb.NewOrganizationAccessClient(cc) + + t.Run("Invalid credentials", func(t *testing.T) { // nolint:paralleltest + for _, opts := range [][]grpc.CallOption{nil, {orgCreds}, {readOnlyAdminKeyCreds}} { + created, err := reg.CreateAPIKey(ctx, &ttnpb.CreateOrganizationAPIKeyRequest{ + OrganizationIds: org1.GetIds(), + Name: "api-key-name", + Rights: []ttnpb.Right{ttnpb.Right_RIGHT_ORGANIZATION_INFO}, + }, opts...) + if a.So(err, should.NotBeNil) && a.So(errors.IsPermissionDenied(err), should.BeTrue) { + a.So(created, should.BeNil) + } + + list, err := reg.ListAPIKeys(ctx, &ttnpb.ListOrganizationAPIKeysRequest{ + OrganizationIds: org1.GetIds(), + }, opts...) + if a.So(err, should.NotBeNil) && a.So(errors.IsPermissionDenied(err), should.BeTrue) { + a.So(list, should.BeNil) + } + + got, err := reg.GetAPIKey(ctx, &ttnpb.GetOrganizationAPIKeyRequest{ + OrganizationIds: org1.GetIds(), + KeyId: orgKey.GetId(), + }, opts...) + if a.So(err, should.NotBeNil) && a.So(errors.IsPermissionDenied(err), should.BeTrue) { + a.So(got, should.BeNil) + } + + updated, err := reg.UpdateAPIKey(ctx, &ttnpb.UpdateOrganizationAPIKeyRequest{ + OrganizationIds: org1.GetIds(), + ApiKey: &ttnpb.APIKey{ + Id: orgKey.GetId(), + Name: "api-key-name-updated", + }, + FieldMask: ttnpb.FieldMask("name"), + }, opts...) + if a.So(err, should.NotBeNil) && a.So(errors.IsPermissionDenied(err), should.BeTrue) { + a.So(updated, should.BeNil) + } + + _, err = reg.DeleteAPIKey(ctx, &ttnpb.DeleteOrganizationAPIKeyRequest{ + OrganizationIds: org1.GetIds(), + KeyId: created.GetId(), + }, opts...) + if !a.So(errors.IsPermissionDenied(err), should.BeTrue) { + t.FailNow() + } + } + }) + }, withPrivateTestDatabase(p)) +} + func TestOrganizationAPIKeys(t *testing.T) { // nolint:gocyclo p := &storetest.Population{} @@ -50,7 +124,6 @@ func TestOrganizationAPIKeys(t *testing.T) { // nolint:gocyclo ttnpb.Right_RIGHT_ORGANIZATION_INFO, ttnpb.Right_RIGHT_ORGANIZATION_APPLICATIONS_LIST, ) - orgCreds := rpcCreds(orgKey) t.Parallel() a, ctx := test.New(t) @@ -147,53 +220,6 @@ func TestOrganizationAPIKeys(t *testing.T) { // nolint:gocyclo }) } - // API Key CRUD with different invalid credentials. - for _, opts := range [][]grpc.CallOption{nil, {orgCreds}} { - created, err := reg.CreateAPIKey(ctx, &ttnpb.CreateOrganizationAPIKeyRequest{ - OrganizationIds: org1.GetIds(), - Name: "api-key-name", - Rights: []ttnpb.Right{ttnpb.Right_RIGHT_ORGANIZATION_INFO}, - }, opts...) - if a.So(err, should.NotBeNil) && a.So(errors.IsPermissionDenied(err), should.BeTrue) { - a.So(created, should.BeNil) - } - - list, err := reg.ListAPIKeys(ctx, &ttnpb.ListOrganizationAPIKeysRequest{ - OrganizationIds: org1.GetIds(), - }, opts...) - if a.So(err, should.NotBeNil) && a.So(errors.IsPermissionDenied(err), should.BeTrue) { - a.So(list, should.BeNil) - } - - got, err := reg.GetAPIKey(ctx, &ttnpb.GetOrganizationAPIKeyRequest{ - OrganizationIds: org1.GetIds(), - KeyId: orgKey.GetId(), - }, opts...) - if a.So(err, should.NotBeNil) && a.So(errors.IsPermissionDenied(err), should.BeTrue) { - a.So(got, should.BeNil) - } - - updated, err := reg.UpdateAPIKey(ctx, &ttnpb.UpdateOrganizationAPIKeyRequest{ - OrganizationIds: org1.GetIds(), - ApiKey: &ttnpb.APIKey{ - Id: orgKey.GetId(), - Name: "api-key-name-updated", - }, - FieldMask: ttnpb.FieldMask("name"), - }, opts...) - if a.So(err, should.NotBeNil) && a.So(errors.IsPermissionDenied(err), should.BeTrue) { - a.So(updated, should.BeNil) - } - - _, err = reg.DeleteAPIKey(ctx, &ttnpb.DeleteOrganizationAPIKeyRequest{ - OrganizationIds: org1.GetIds(), - KeyId: created.GetId(), - }, opts...) - if !a.So(errors.IsPermissionDenied(err), should.BeTrue) { - t.FailNow() - } - } - // API Key CRUD with different valid credentials. for _, opts := range [][]grpc.CallOption{{adminCreds}, {usr1Creds}, {limitedCreds}} { created, err := reg.CreateAPIKey(ctx, &ttnpb.CreateOrganizationAPIKeyRequest{ @@ -287,6 +313,92 @@ func TestOrganizationAPIKeys(t *testing.T) { // nolint:gocyclo }, withPrivateTestDatabase(p)) } +func TestOrganizationCollaboratorsPermissions(t *testing.T) { // nolint:gocyclo + p := &storetest.Population{} + + admin := p.NewUser() + admin.Admin = true + + readOnlyAdmin := p.NewUser() + readOnlyAdmin.Admin = true + readOnlyAdminKey, _ := p.NewAPIKey(readOnlyAdmin.GetEntityIdentifiers(), ttnpb.AllReadAdminRights.GetRights()...) + readOnlyAdminKeyCreds := rpcCreds(readOnlyAdminKey) + + usr1 := p.NewUser() + org1 := p.NewOrganization(usr1.GetOrganizationOrUserIdentifiers()) + + orgKey, _ := p.NewAPIKey(org1.GetEntityIdentifiers(), + ttnpb.Right_RIGHT_ORGANIZATION_INFO, + ttnpb.Right_RIGHT_ORGANIZATION_APPLICATIONS_LIST, + ) + orgCreds := rpcCreds(orgKey) + + usr2 := p.NewUser() + p.NewMembership( + usr2.GetOrganizationOrUserIdentifiers(), + org1.GetEntityIdentifiers(), + ttnpb.Right_RIGHT_ORGANIZATION_INFO, + ttnpb.Right_RIGHT_ORGANIZATION_APPLICATIONS_LIST, + ) + + t.Parallel() + a, ctx := test.New(t) + + testWithIdentityServer(t, func(is *IdentityServer, cc *grpc.ClientConn) { + is.config.AdminRights.All = true + + reg := ttnpb.NewOrganizationAccessClient(cc) + + t.Run("Invalid credentials", func(t *testing.T) { // nolint:paralleltest + for _, opts := range [][]grpc.CallOption{nil, {orgCreds}, {readOnlyAdminKeyCreds}} { + _, err := reg.SetCollaborator(ctx, &ttnpb.SetOrganizationCollaboratorRequest{ + OrganizationIds: org1.GetIds(), + Collaborator: &ttnpb.Collaborator{ + Ids: usr2.GetOrganizationOrUserIdentifiers(), + Rights: []ttnpb.Right{ + ttnpb.Right_RIGHT_ORGANIZATION_INFO, + }, + }, + }, opts...) + if a.So(err, should.NotBeNil) { + a.So(errors.IsPermissionDenied(err), should.BeTrue) + } + + got, err := reg.GetCollaborator(ctx, &ttnpb.GetOrganizationCollaboratorRequest{ + OrganizationIds: org1.GetIds(), + Collaborator: usr2.GetOrganizationOrUserIdentifiers(), + }, opts...) + if a.So(err, should.NotBeNil) && a.So(errors.IsPermissionDenied(err), should.BeTrue) { + a.So(got, should.BeNil) + } + + _, err = reg.DeleteCollaborator(ctx, &ttnpb.DeleteOrganizationCollaboratorRequest{ + OrganizationIds: org1.GetIds(), + CollaboratorIds: usr2.GetOrganizationOrUserIdentifiers(), + }, opts...) + if a.So(err, should.NotBeNil) { + a.So(errors.IsPermissionDenied(err), should.BeTrue) + } + } + + // ListCollaborators without credentials. + list, err := reg.ListCollaborators(ctx, &ttnpb.ListOrganizationCollaboratorsRequest{ + OrganizationIds: org1.GetIds(), + }) + if a.So(err, should.NotBeNil) && a.So(errors.IsUnauthenticated(err), should.BeTrue) { + a.So(list, should.BeNil) + } + + // ListCollaborators with read-only credentials. Returns only safe fields. + list, err = reg.ListCollaborators(ctx, &ttnpb.ListOrganizationCollaboratorsRequest{ + OrganizationIds: org1.GetIds(), + }, readOnlyAdminKeyCreds) + a.So(err, should.BeNil) + a.So(list, should.NotBeNil) + }) + }, withPrivateTestDatabase(p)) +} + func TestOrganizationCollaborators(t *testing.T) { // nolint:gocyclo p := &storetest.Population{} @@ -308,12 +420,6 @@ func TestOrganizationCollaborators(t *testing.T) { // nolint:gocyclo ) limitedCreds := rpcCreds(limitedKey) - orgKey, _ := p.NewAPIKey(org1.GetEntityIdentifiers(), - ttnpb.Right_RIGHT_ORGANIZATION_INFO, - ttnpb.Right_RIGHT_ORGANIZATION_APPLICATIONS_LIST, - ) - orgCreds := rpcCreds(orgKey) - usr2 := p.NewUser() p.NewMembership( usr2.GetOrganizationOrUserIdentifiers(), @@ -383,30 +489,6 @@ func TestOrganizationCollaborators(t *testing.T) { // nolint:gocyclo }, limitedCreds) a.So(err, should.BeNil) - // Collaborator CRUD with different invalid credentials. - for _, opts := range [][]grpc.CallOption{nil, {orgCreds}} { - _, err := reg.SetCollaborator(ctx, &ttnpb.SetOrganizationCollaboratorRequest{ - OrganizationIds: org1.GetIds(), - Collaborator: &ttnpb.Collaborator{ - Ids: usr2.GetOrganizationOrUserIdentifiers(), - Rights: []ttnpb.Right{ - ttnpb.Right_RIGHT_ORGANIZATION_INFO, - }, - }, - }, opts...) - if a.So(err, should.NotBeNil) { - a.So(errors.IsPermissionDenied(err), should.BeTrue) - } - - got, err := reg.GetCollaborator(ctx, &ttnpb.GetOrganizationCollaboratorRequest{ - OrganizationIds: org1.GetIds(), - Collaborator: usr2.GetOrganizationOrUserIdentifiers(), - }, opts...) - if a.So(err, should.NotBeNil) && a.So(errors.IsPermissionDenied(err), should.BeTrue) { - a.So(got, should.BeNil) - } - } - // ListCollaborators without credentials. list, err := reg.ListCollaborators(ctx, &ttnpb.ListOrganizationCollaboratorsRequest{ OrganizationIds: org1.GetIds(), From c6a3b2a8b782b5a3ce77aac02ba43f235c5f4f1c Mon Sep 17 00:00:00 2001 From: Nicholas Cristofaro Date: Mon, 25 Nov 2024 16:07:29 -0300 Subject: [PATCH 33/40] is: Add read-only admin tests to organization_registry --- .../organization_registry_test.go | 145 ++++++++++++------ 1 file changed, 100 insertions(+), 45 deletions(-) diff --git a/pkg/identityserver/organization_registry_test.go b/pkg/identityserver/organization_registry_test.go index 6f5e3e1fa4..39f0ab3132 100644 --- a/pkg/identityserver/organization_registry_test.go +++ b/pkg/identityserver/organization_registry_test.go @@ -62,67 +62,122 @@ func TestOrganizationsNestedError(t *testing.T) { }, withPrivateTestDatabase(p)) } -func TestOrganizationsPermissionDenied(t *testing.T) { +func TestOrganizationsPermissions(t *testing.T) { p := &storetest.Population{} usr1 := p.NewUser() org1 := p.NewOrganization(usr1.GetOrganizationOrUserIdentifiers()) + readOnlyAdmin := p.NewUser() + readOnlyAdmin.Admin = true + readOnlyAdminKey, _ := p.NewAPIKey(readOnlyAdmin.GetEntityIdentifiers(), ttnpb.AllReadAdminRights.GetRights()...) + readOnlyAdminKeyCreds := rpcCreds(readOnlyAdminKey) + t.Parallel() a, ctx := test.New(t) testWithIdentityServer(t, func(_ *IdentityServer, cc *grpc.ClientConn) { reg := ttnpb.NewOrganizationRegistryClient(cc) - _, err := reg.Create(ctx, &ttnpb.CreateOrganizationRequest{ - Organization: &ttnpb.Organization{ - Ids: &ttnpb.OrganizationIdentifiers{OrganizationId: "foo-org"}, - }, - Collaborator: usr1.GetOrganizationOrUserIdentifiers(), - }) - if a.So(err, should.NotBeNil) { - a.So(errors.IsPermissionDenied(err), should.BeTrue) - } + t.Run("Invalid credentials", func(t *testing.T) { // nolint:paralleltest + _, err := reg.Create(ctx, &ttnpb.CreateOrganizationRequest{ + Organization: &ttnpb.Organization{ + Ids: &ttnpb.OrganizationIdentifiers{OrganizationId: "foo-org"}, + }, + Collaborator: usr1.GetOrganizationOrUserIdentifiers(), + }) + if a.So(err, should.NotBeNil) { + a.So(errors.IsPermissionDenied(err), should.BeTrue) + } - _, err = reg.Get(ctx, &ttnpb.GetOrganizationRequest{ - OrganizationIds: org1.GetIds(), - FieldMask: ttnpb.FieldMask("name"), - }) - if a.So(err, should.NotBeNil) { - a.So(errors.IsUnauthenticated(err), should.BeTrue) - } + _, err = reg.Get(ctx, &ttnpb.GetOrganizationRequest{ + OrganizationIds: org1.GetIds(), + FieldMask: ttnpb.FieldMask("name"), + }) + if a.So(err, should.NotBeNil) { + a.So(errors.IsUnauthenticated(err), should.BeTrue) + } - listRes, err := reg.List(ctx, &ttnpb.ListOrganizationsRequest{ - FieldMask: ttnpb.FieldMask("name"), - }) - a.So(err, should.BeNil) - if a.So(listRes, should.NotBeNil) { - a.So(listRes.Organizations, should.BeEmpty) - } + listRes, err := reg.List(ctx, &ttnpb.ListOrganizationsRequest{ + FieldMask: ttnpb.FieldMask("name"), + }) + a.So(err, should.BeNil) + if a.So(listRes, should.NotBeNil) { + a.So(listRes.Organizations, should.BeEmpty) + } - _, err = reg.List(ctx, &ttnpb.ListOrganizationsRequest{ - Collaborator: usr1.GetOrganizationOrUserIdentifiers(), - FieldMask: ttnpb.FieldMask("name"), - }) - if a.So(err, should.NotBeNil) { - a.So(errors.IsPermissionDenied(err), should.BeTrue) - } + _, err = reg.List(ctx, &ttnpb.ListOrganizationsRequest{ + Collaborator: usr1.GetOrganizationOrUserIdentifiers(), + FieldMask: ttnpb.FieldMask("name"), + }) + if a.So(err, should.NotBeNil) { + a.So(errors.IsPermissionDenied(err), should.BeTrue) + } - _, err = reg.Update(ctx, &ttnpb.UpdateOrganizationRequest{ - Organization: &ttnpb.Organization{ - Ids: org1.GetIds(), - Name: "Updated Name", - }, - FieldMask: ttnpb.FieldMask("name"), + _, err = reg.Update(ctx, &ttnpb.UpdateOrganizationRequest{ + Organization: &ttnpb.Organization{ + Ids: org1.GetIds(), + Name: "Updated Name", + }, + FieldMask: ttnpb.FieldMask("name"), + }) + if a.So(err, should.NotBeNil) { + a.So(errors.IsPermissionDenied(err), should.BeTrue) + } + + _, err = reg.Delete(ctx, org1.GetIds()) + if a.So(err, should.NotBeNil) { + a.So(errors.IsPermissionDenied(err), should.BeTrue) + } }) - if a.So(err, should.NotBeNil) { - a.So(errors.IsPermissionDenied(err), should.BeTrue) - } - _, err = reg.Delete(ctx, org1.GetIds()) - if a.So(err, should.NotBeNil) { - a.So(errors.IsPermissionDenied(err), should.BeTrue) - } - }) + t.Run("Admin read-only", func(t *testing.T) { // nolint:paralleltest + _, err := reg.Create(ctx, &ttnpb.CreateOrganizationRequest{ + Organization: &ttnpb.Organization{ + Ids: &ttnpb.OrganizationIdentifiers{OrganizationId: "foo-org"}, + }, + Collaborator: usr1.GetOrganizationOrUserIdentifiers(), + }, readOnlyAdminKeyCreds) + if a.So(err, should.NotBeNil) { + a.So(errors.IsPermissionDenied(err), should.BeTrue) + } + + _, err = reg.Get(ctx, &ttnpb.GetOrganizationRequest{ + OrganizationIds: org1.GetIds(), + FieldMask: ttnpb.FieldMask("name"), + }, readOnlyAdminKeyCreds) + a.So(errors.IsPermissionDenied(err), should.BeFalse) + + listRes, err := reg.List(ctx, &ttnpb.ListOrganizationsRequest{ + FieldMask: ttnpb.FieldMask("name"), + }, readOnlyAdminKeyCreds) + a.So(err, should.BeNil) + if a.So(listRes, should.NotBeNil) { + a.So(listRes.Organizations, should.BeEmpty) + } + + _, err = reg.List(ctx, &ttnpb.ListOrganizationsRequest{ + Collaborator: usr1.GetOrganizationOrUserIdentifiers(), + FieldMask: ttnpb.FieldMask("name"), + }, readOnlyAdminKeyCreds) + a.So(errors.IsPermissionDenied(err), should.BeFalse) + + _, err = reg.Update(ctx, &ttnpb.UpdateOrganizationRequest{ + Organization: &ttnpb.Organization{ + Ids: org1.GetIds(), + Name: "Updated Name", + }, + FieldMask: ttnpb.FieldMask("name"), + }, readOnlyAdminKeyCreds) + if a.So(err, should.NotBeNil) { + a.So(errors.IsPermissionDenied(err), should.BeTrue) + } + + _, err = reg.Delete(ctx, org1.GetIds(), readOnlyAdminKeyCreds) + if a.So(err, should.NotBeNil) { + a.So(errors.IsPermissionDenied(err), should.BeTrue) + } + }) + }, withPrivateTestDatabase(p)) } func TestOrganizationsCRUD(t *testing.T) { From 7cdbfc0d61007a122b5d2184f99ddb28ad80b627 Mon Sep 17 00:00:00 2001 From: Nicholas Cristofaro Date: Mon, 25 Nov 2024 16:08:33 -0300 Subject: [PATCH 34/40] is: Add read-only admin tests to user_access --- pkg/identityserver/user_access_test.go | 119 +++++++++++++++---------- 1 file changed, 71 insertions(+), 48 deletions(-) diff --git a/pkg/identityserver/user_access_test.go b/pkg/identityserver/user_access_test.go index bb09beaa12..8cd95ce333 100644 --- a/pkg/identityserver/user_access_test.go +++ b/pkg/identityserver/user_access_test.go @@ -26,6 +26,77 @@ import ( "google.golang.org/grpc" ) +func TestUserAPIKeysPermissions(t *testing.T) { // nolint:gocyclo + p := &storetest.Population{} + + readOnlyAdmin := p.NewUser() + readOnlyAdmin.Admin = true + readOnlyAdminKey, _ := p.NewAPIKey(readOnlyAdmin.GetEntityIdentifiers(), ttnpb.AllReadAdminRights.GetRights()...) + readOnlyAdminKeyCreds := rpcCreds(readOnlyAdminKey) + + usr1 := p.NewUser() + usr1Key, _ := p.NewAPIKey(usr1.GetEntityIdentifiers(), + ttnpb.Right_RIGHT_USER_INFO, + ttnpb.Right_RIGHT_USER_APPLICATIONS_LIST, + ) + usr1Creds := rpcCreds(usr1Key) + + t.Parallel() + a, ctx := test.New(t) + + testWithIdentityServer(t, func(is *IdentityServer, cc *grpc.ClientConn) { + is.config.AdminRights.All = true + + reg := ttnpb.NewUserAccessClient(cc) + + for _, opts := range [][]grpc.CallOption{nil, {usr1Creds}, {readOnlyAdminKeyCreds}} { + created, err := reg.CreateAPIKey(ctx, &ttnpb.CreateUserAPIKeyRequest{ + UserIds: usr1.GetIds(), + Name: "api-key-name", + Rights: []ttnpb.Right{ttnpb.Right_RIGHT_USER_INFO}, + }, opts...) + if a.So(err, should.NotBeNil) && a.So(errors.IsPermissionDenied(err), should.BeTrue) { + a.So(created, should.BeNil) + } + + list, err := reg.ListAPIKeys(ctx, &ttnpb.ListUserAPIKeysRequest{ + UserIds: usr1.GetIds(), + }, opts...) + if a.So(err, should.NotBeNil) && a.So(errors.IsPermissionDenied(err), should.BeTrue) { + a.So(list, should.BeNil) + } + + got, err := reg.GetAPIKey(ctx, &ttnpb.GetUserAPIKeyRequest{ + UserIds: usr1.GetIds(), + KeyId: usr1Key.GetId(), + }, opts...) + if a.So(err, should.NotBeNil) && a.So(errors.IsPermissionDenied(err), should.BeTrue) { + a.So(got, should.BeNil) + } + + updated, err := reg.UpdateAPIKey(ctx, &ttnpb.UpdateUserAPIKeyRequest{ + UserIds: usr1.GetIds(), + ApiKey: &ttnpb.APIKey{ + Id: usr1Key.GetId(), + Name: "api-key-name-updated", + }, + FieldMask: ttnpb.FieldMask("name"), + }, opts...) + if a.So(err, should.NotBeNil) && a.So(errors.IsPermissionDenied(err), should.BeTrue) { + a.So(updated, should.BeNil) + } + + _, err = reg.DeleteAPIKey(ctx, &ttnpb.DeleteUserAPIKeyRequest{ + UserIds: usr1.GetIds(), + KeyId: usr1Key.GetId(), + }, opts...) + if !a.So(errors.IsPermissionDenied(err), should.BeTrue) { + t.FailNow() + } + } + }, withPrivateTestDatabase(p)) +} + func TestUserAPIKeys(t *testing.T) { // nolint:gocyclo p := &storetest.Population{} @@ -39,7 +110,6 @@ func TestUserAPIKeys(t *testing.T) { // nolint:gocyclo ttnpb.Right_RIGHT_USER_INFO, ttnpb.Right_RIGHT_USER_APPLICATIONS_LIST, ) - usr1Creds := rpcCreds(usr1Key) limitedKey, _ := p.NewAPIKey(usr1.GetEntityIdentifiers(), ttnpb.Right_RIGHT_USER_INFO, ttnpb.Right_RIGHT_USER_SETTINGS_BASIC, @@ -142,53 +212,6 @@ func TestUserAPIKeys(t *testing.T) { // nolint:gocyclo }) } - // API Key CRUD with different invalid credentials. - for _, opts := range [][]grpc.CallOption{nil, {usr1Creds}} { - created, err := reg.CreateAPIKey(ctx, &ttnpb.CreateUserAPIKeyRequest{ - UserIds: usr1.GetIds(), - Name: "api-key-name", - Rights: []ttnpb.Right{ttnpb.Right_RIGHT_USER_INFO}, - }, opts...) - if a.So(err, should.NotBeNil) && a.So(errors.IsPermissionDenied(err), should.BeTrue) { - a.So(created, should.BeNil) - } - - list, err := reg.ListAPIKeys(ctx, &ttnpb.ListUserAPIKeysRequest{ - UserIds: usr1.GetIds(), - }, opts...) - if a.So(err, should.NotBeNil) && a.So(errors.IsPermissionDenied(err), should.BeTrue) { - a.So(list, should.BeNil) - } - - got, err := reg.GetAPIKey(ctx, &ttnpb.GetUserAPIKeyRequest{ - UserIds: usr1.GetIds(), - KeyId: usr1Key.GetId(), - }, opts...) - if a.So(err, should.NotBeNil) && a.So(errors.IsPermissionDenied(err), should.BeTrue) { - a.So(got, should.BeNil) - } - - updated, err := reg.UpdateAPIKey(ctx, &ttnpb.UpdateUserAPIKeyRequest{ - UserIds: usr1.GetIds(), - ApiKey: &ttnpb.APIKey{ - Id: usr1Key.GetId(), - Name: "api-key-name-updated", - }, - FieldMask: ttnpb.FieldMask("name"), - }, opts...) - if a.So(err, should.NotBeNil) && a.So(errors.IsPermissionDenied(err), should.BeTrue) { - a.So(updated, should.BeNil) - } - - _, err = reg.DeleteAPIKey(ctx, &ttnpb.DeleteUserAPIKeyRequest{ - UserIds: usr1.GetIds(), - KeyId: usr1Key.GetId(), - }, opts...) - if !a.So(errors.IsPermissionDenied(err), should.BeTrue) { - t.FailNow() - } - } - // API Key CRUD with different valid credentials. for _, opts := range [][]grpc.CallOption{{adminCreds}, {limitedCreds}} { created, err := reg.CreateAPIKey(ctx, &ttnpb.CreateUserAPIKeyRequest{ From 5b5a36922ffe80dbd905fadf5392d58b24658301 Mon Sep 17 00:00:00 2001 From: Nicholas Cristofaro Date: Mon, 25 Nov 2024 16:10:44 -0300 Subject: [PATCH 35/40] is: Add read-only admin tests to user_bookmark_registry --- .../user_bookmark_registry_test.go | 139 +++++++++++++----- 1 file changed, 100 insertions(+), 39 deletions(-) diff --git a/pkg/identityserver/user_bookmark_registry_test.go b/pkg/identityserver/user_bookmark_registry_test.go index 0ae64b59cc..d5768fad76 100644 --- a/pkg/identityserver/user_bookmark_registry_test.go +++ b/pkg/identityserver/user_bookmark_registry_test.go @@ -26,9 +26,7 @@ import ( "google.golang.org/grpc" ) -func TestUsersBookmarksOperations(t *testing.T) { - t.Parallel() - +func TestUsersBookmarksPermissions(t *testing.T) { p := &storetest.Population{} usr1 := p.NewUser() @@ -40,24 +38,114 @@ func TestUsersBookmarksOperations(t *testing.T) { app1 := p.NewApplication(usr1.GetOrganizationOrUserIdentifiers()) app2 := p.NewApplication(usr1.GetOrganizationOrUserIdentifiers()) - key, _ := p.NewAPIKey(usr1.GetEntityIdentifiers(), ttnpb.Right_RIGHT_ALL) - creds := rpcCreds(key) - keyWithoutRights, _ := p.NewAPIKey(usr1.GetEntityIdentifiers()) credsWithoutRights := rpcCreds(keyWithoutRights) + readOnlyAdmin := p.NewUser() + readOnlyAdmin.Admin = true + readOnlyAdminKey, _ := p.NewAPIKey(readOnlyAdmin.GetEntityIdentifiers(), ttnpb.AllReadAdminRights.GetRights()...) + readOnlyAdminKeyCreds := rpcCreds(readOnlyAdminKey) + + t.Parallel() + a, ctx := test.New(t) + testWithIdentityServer(t, func(_ *IdentityServer, cc *grpc.ClientConn) { reg := ttnpb.NewUserBookmarkRegistryClient(cc) - t.Run("Create/WithoutRights", func(t *testing.T) { // nolint:paralleltest - a, ctx := test.New(t) - got, err := reg.Create(ctx, &ttnpb.CreateUserBookmarkRequest{ + t.Run("Invalid credentials", func(t *testing.T) { // nolint:paralleltest + for _, opts := range [][]grpc.CallOption{nil, {credsWithoutRights}} { + _, err := reg.Create(ctx, &ttnpb.CreateUserBookmarkRequest{ + UserIds: usr1.Ids, + EntityIds: app1.GetEntityIdentifiers(), + }, opts...) + if a.So(err, should.NotBeNil) { + a.So(errors.IsPermissionDenied(err), should.BeTrue) + } + + _, err = reg.List(ctx, &ttnpb.ListUserBookmarksRequest{ + UserIds: usr1.Ids, + }, opts...) + if a.So(err, should.NotBeNil) { + a.So(errors.IsPermissionDenied(err), should.BeTrue) + } + + _, err = reg.Delete(ctx, &ttnpb.DeleteUserBookmarkRequest{ + UserIds: usr1.Ids, + EntityIds: app1.GetEntityIdentifiers(), + }, opts...) + if a.So(err, should.NotBeNil) { + a.So(errors.IsPermissionDenied(err), should.BeTrue) + } + + _, err = reg.BatchDelete(ctx, &ttnpb.BatchDeleteUserBookmarksRequest{ + UserIds: usr1.Ids, + EntityIds: []*ttnpb.EntityIdentifiers{ + app1.GetEntityIdentifiers(), + app2.GetEntityIdentifiers(), + }, + }, opts...) + if a.So(err, should.NotBeNil) { + a.So(errors.IsPermissionDenied(err), should.BeTrue) + } + } + }) + + t.Run("Admin read-only", func(t *testing.T) { // nolint:paralleltest + _, err := reg.Create(ctx, &ttnpb.CreateUserBookmarkRequest{ UserIds: usr1.Ids, EntityIds: app1.GetEntityIdentifiers(), - }, credsWithoutRights) - a.So(got, should.BeNil) - a.So(errors.IsPermissionDenied(err), should.BeTrue) + }, readOnlyAdminKeyCreds) + if a.So(err, should.NotBeNil) { + a.So(errors.IsPermissionDenied(err), should.BeTrue) + } + + _, err = reg.List(ctx, &ttnpb.ListUserBookmarksRequest{ + UserIds: usr1.Ids, + }, readOnlyAdminKeyCreds) + a.So(errors.IsPermissionDenied(err), should.BeFalse) + + _, err = reg.Delete(ctx, &ttnpb.DeleteUserBookmarkRequest{ + UserIds: usr1.Ids, + EntityIds: app1.GetEntityIdentifiers(), + }, readOnlyAdminKeyCreds) + if a.So(err, should.NotBeNil) { + a.So(errors.IsPermissionDenied(err), should.BeTrue) + } + + _, err = reg.BatchDelete(ctx, &ttnpb.BatchDeleteUserBookmarksRequest{ + UserIds: usr1.Ids, + EntityIds: []*ttnpb.EntityIdentifiers{ + app1.GetEntityIdentifiers(), + app2.GetEntityIdentifiers(), + }, + }, readOnlyAdminKeyCreds) + if a.So(err, should.NotBeNil) { + a.So(errors.IsPermissionDenied(err), should.BeTrue) + } }) + }, withPrivateTestDatabase(p)) +} + +func TestUsersBookmarksOperations(t *testing.T) { + t.Parallel() + + p := &storetest.Population{} + + usr1 := p.NewUser() + usr1.Password = "OldPassword" + usr1.PrimaryEmailAddress = "user-1@email.com" + validatedAtTime := time.Now().Truncate(time.Millisecond) + usr1.PrimaryEmailAddressValidatedAt = ttnpb.ProtoTime(&validatedAtTime) + + app1 := p.NewApplication(usr1.GetOrganizationOrUserIdentifiers()) + app2 := p.NewApplication(usr1.GetOrganizationOrUserIdentifiers()) + + key, _ := p.NewAPIKey(usr1.GetEntityIdentifiers(), ttnpb.Right_RIGHT_ALL) + creds := rpcCreds(key) + + testWithIdentityServer(t, func(_ *IdentityServer, cc *grpc.ClientConn) { + reg := ttnpb.NewUserBookmarkRegistryClient(cc) + t.Run("Create", func(t *testing.T) { // nolint:paralleltest a, ctx := test.New(t) got, err := reg.Create(ctx, &ttnpb.CreateUserBookmarkRequest{ @@ -99,14 +187,6 @@ func TestUsersBookmarksOperations(t *testing.T) { a.So(got, should.Resemble, &ttnpb.UserBookmark{UserIds: usr1.Ids, EntityIds: app2.GetEntityIdentifiers()}) }) - t.Run("FindBookmarks/WithoutRights", func(t *testing.T) { // nolint:paralleltest - a, ctx := test.New(t) - got, err := reg.List(ctx, &ttnpb.ListUserBookmarksRequest{ - UserIds: usr1.Ids, - }, credsWithoutRights) - a.So(got, should.BeNil) - a.So(errors.IsPermissionDenied(err), should.BeTrue) - }) t.Run("FindBookmarks/HasEntityType", func(t *testing.T) { // nolint:paralleltest a, ctx := test.New(t) @@ -162,14 +242,6 @@ func TestUsersBookmarksOperations(t *testing.T) { } }) - t.Run("Delete/WithoutRights", func(t *testing.T) { // nolint:paralleltest - a, ctx := test.New(t) - _, err := reg.Delete(ctx, &ttnpb.DeleteUserBookmarkRequest{ - UserIds: usr1.Ids, - EntityIds: app1.GetEntityIdentifiers(), - }, credsWithoutRights) - a.So(errors.IsPermissionDenied(err), should.BeTrue) - }) t.Run("Delete", func(t *testing.T) { // nolint:paralleltest a, ctx := test.New(t) _, err := reg.Delete(ctx, &ttnpb.DeleteUserBookmarkRequest{ @@ -192,17 +264,6 @@ func TestUsersBookmarksOperations(t *testing.T) { } }) - t.Run("BatchDelete/WithoutRights", func(t *testing.T) { // nolint:paralleltest - a, ctx := test.New(t) - _, err := reg.BatchDelete(ctx, &ttnpb.BatchDeleteUserBookmarksRequest{ - UserIds: usr1.Ids, - EntityIds: []*ttnpb.EntityIdentifiers{ - app1.GetEntityIdentifiers(), - app2.GetEntityIdentifiers(), - }, - }, credsWithoutRights) - a.So(errors.IsPermissionDenied(err), should.BeTrue) - }) t.Run("BatchDelete", func(t *testing.T) { // nolint:paralleltest a, ctx := test.New(t) _, err := reg.BatchDelete(ctx, &ttnpb.BatchDeleteUserBookmarksRequest{ From d4fdd78cfe3629d6e9636d0ad52d0c371b591e81 Mon Sep 17 00:00:00 2001 From: Nicholas Cristofaro Date: Mon, 25 Nov 2024 16:11:45 -0300 Subject: [PATCH 36/40] is: Add read-only admin tests to user_registry --- pkg/identityserver/user_registry_test.go | 60 ++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/pkg/identityserver/user_registry_test.go b/pkg/identityserver/user_registry_test.go index 47adc90cce..2994ba1726 100644 --- a/pkg/identityserver/user_registry_test.go +++ b/pkg/identityserver/user_registry_test.go @@ -239,6 +239,66 @@ func TestUserUpdateInvalidPassword(t *testing.T) { }, withPrivateTestDatabase(p)) } +func TestUsersCRUDReadOnlyAdmin(t *testing.T) { + p := &storetest.Population{} + + readOnlyAdmin := p.NewUser() + readOnlyAdmin.Admin = true + readOnlyAdminKey, _ := p.NewAPIKey(readOnlyAdmin.GetEntityIdentifiers(), ttnpb.AllReadAdminRights.GetRights()...) + readOnlyAdminCreds := rpcCreds(readOnlyAdminKey) + + usr1 := p.NewUser() + usr1.Attributes = map[string]string{"foo": "bar"} + + t.Parallel() + a, ctx := test.New(t) + + testWithIdentityServer(t, func(_ *IdentityServer, cc *grpc.ClientConn) { + reg := ttnpb.NewUserRegistryClient(cc) + + // Fetch only public safe fields. + got, err := reg.Get(ctx, &ttnpb.GetUserRequest{ + UserIds: usr1.GetIds(), + FieldMask: ttnpb.FieldMask("ids"), + }, readOnlyAdminCreds) + if a.So(err, should.BeNil) { + a.So(got.GetIds(), should.Resemble, usr1.GetIds()) + a.So(got.Attributes, should.BeEmpty) + } + + // Fetch non-public fields. + got, err = reg.Get(ctx, &ttnpb.GetUserRequest{ + UserIds: usr1.GetIds(), + FieldMask: ttnpb.FieldMask("attributes"), + }, readOnlyAdminCreds) + if a.So(err, should.BeNil) { + a.So(got.GetIds(), should.Resemble, usr1.GetIds()) + a.So(got.GetAttributes(), should.Resemble, usr1.Attributes) + } + + _, err = reg.Update(ctx, &ttnpb.UpdateUserRequest{ + User: &ttnpb.User{ + Ids: usr1.GetIds(), + Name: "Updated Name", + }, + FieldMask: ttnpb.FieldMask("name"), + }, readOnlyAdminCreds) + if a.So(err, should.NotBeNil) { + a.So(errors.IsPermissionDenied(err), should.BeTrue) + } + + _, err = reg.Delete(ctx, usr1.GetIds(), readOnlyAdminCreds) + if a.So(err, should.NotBeNil) { + a.So(errors.IsPermissionDenied(err), should.BeTrue) + } + + _, err = reg.Purge(ctx, usr1.GetIds(), readOnlyAdminCreds) + if a.So(err, should.NotBeNil) { + a.So(errors.IsPermissionDenied(err), should.BeTrue) + } + }, withPrivateTestDatabase(p)) +} + func TestUsersCRUD(t *testing.T) { t.Parallel() From 708eb2aaf4833a85c33101ed150bcad97aeccc80 Mon Sep 17 00:00:00 2001 From: Nicholas Cristofaro Date: Mon, 25 Nov 2024 16:13:26 -0300 Subject: [PATCH 37/40] is: Add read-only admin tests to user_session_registry --- .../user_session_registry_test.go | 34 ++++++++++++------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/pkg/identityserver/user_session_registry_test.go b/pkg/identityserver/user_session_registry_test.go index 0f86ed0378..f0cd771bfb 100644 --- a/pkg/identityserver/user_session_registry_test.go +++ b/pkg/identityserver/user_session_registry_test.go @@ -34,11 +34,18 @@ func TestUserSessionsRegistry(t *testing.T) { p := &storetest.Population{} usr1 := p.NewUser() + key, _ := p.NewAPIKey(usr1.GetEntityIdentifiers(), ttnpb.Right_RIGHT_ALL) creds := rpcCreds(key) + keyWithoutRights, _ := p.NewAPIKey(usr1.GetEntityIdentifiers()) credsWithoutRights := rpcCreds(keyWithoutRights) + readOnlyAdmin := p.NewUser() + readOnlyAdmin.Admin = true + readOnlyAdminKey, _ := p.NewAPIKey(readOnlyAdmin.GetEntityIdentifiers(), ttnpb.AllReadAdminRights.GetRights()...) + readOnlyAdminKeyCreds := rpcCreds(readOnlyAdminKey) + a, ctx := test.New(t) randomUUID := uuid.NewString() @@ -46,19 +53,22 @@ func TestUserSessionsRegistry(t *testing.T) { testWithIdentityServer(t, func(is *IdentityServer, cc *grpc.ClientConn) { reg := ttnpb.NewUserSessionRegistryClient(cc) - _, err := reg.List(ctx, &ttnpb.ListUserSessionsRequest{ - UserIds: usr1.GetIds(), - }, credsWithoutRights) - if a.So(err, should.NotBeNil) { - a.So(errors.IsPermissionDenied(err), should.BeTrue) - } + // Invalid credentials + for _, opts := range [][]grpc.CallOption{nil, {credsWithoutRights}, {readOnlyAdminKeyCreds}} { + _, err := reg.List(ctx, &ttnpb.ListUserSessionsRequest{ + UserIds: usr1.GetIds(), + }, opts...) + if a.So(err, should.NotBeNil) { + a.So(errors.IsPermissionDenied(err), should.BeTrue) + } - _, err = reg.Delete(ctx, &ttnpb.UserSessionIdentifiers{ - UserIds: usr1.GetIds(), - SessionId: randomUUID, - }, credsWithoutRights) - if a.So(err, should.NotBeNil) { - a.So(errors.IsPermissionDenied(err), should.BeTrue) + _, err = reg.Delete(ctx, &ttnpb.UserSessionIdentifiers{ + UserIds: usr1.GetIds(), + SessionId: randomUUID, + }, opts...) + if a.So(err, should.NotBeNil) { + a.So(errors.IsPermissionDenied(err), should.BeTrue) + } } sessions, err := reg.List(ctx, &ttnpb.ListUserSessionsRequest{ From f48342b2f14d9fd3c42aea7d5562dbb8c2291397 Mon Sep 17 00:00:00 2001 From: Nicholas Cristofaro Date: Mon, 25 Nov 2024 18:08:43 -0300 Subject: [PATCH 38/40] dev: Add CHANGELOG --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index afaee5b1ca..ea5b683a35 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,10 @@ For details about compatibility between different releases, see the **Commitment - Support for managing MAC settings profiles. - This feature is experimental and subject to change. - Support pausing webhook in the edit webhook view in console +- Add more specific rights for user operations. + - The rights added were for listing and creating rights. + - Admin validation associated with these operations remains. +- Add purge rights for application, organizations, Oauth clients, gateways and user operations. ### Changed From 00d70335f81c67510d71e65dbdca6b0867aa2b5b Mon Sep 17 00:00:00 2001 From: Nicholas Cristofaro Date: Wed, 27 Nov 2024 08:01:05 -0300 Subject: [PATCH 39/40] dev: Fix universal_rights intersection conditions --- pkg/ttnpb/identityserver.go | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/pkg/ttnpb/identityserver.go b/pkg/ttnpb/identityserver.go index ffddf666b8..30ef03a434 100644 --- a/pkg/ttnpb/identityserver.go +++ b/pkg/ttnpb/identityserver.go @@ -14,6 +14,10 @@ package ttnpb +// SupportUserID is the userID used for creating the support user and for validation of operation in which this user +// should be present. +const SupportUserID = "support" + // GetEntityIdentifiers returns the EntityIdentifiers for the used access method. func (m *AuthInfoResponse) GetEntityIdentifiers() *EntityIdentifiers { if m == nil { @@ -39,22 +43,30 @@ func (m *AuthInfoResponse) GetRights() []Right { } var rights []Right + var limitRights bool + switch accessMethod := m.GetAccessMethod().(type) { case *AuthInfoResponse_ApiKey: + if accessMethod.ApiKey.GetEntityIds().GetUserIds().GetUserId() == SupportUserID { + limitRights = true + } rights = accessMethod.ApiKey.GetApiKey().GetRights() case *AuthInfoResponse_OauthAccessToken: + if accessMethod.OauthAccessToken.GetUserIds().GetUserId() == SupportUserID { + limitRights = true + } rights = accessMethod.OauthAccessToken.GetRights() case *AuthInfoResponse_UserSession: + if accessMethod.UserSession.GetUserIds().GetUserId() == SupportUserID { + limitRights = true + } rights = RightsFrom(Right_RIGHT_ALL).Implied().GetRights() case *AuthInfoResponse_GatewayToken_: rights = accessMethod.GatewayToken.GetRights() } - // Limit standard rights with the UniversalRights. There are two possibilities here. - // - // 1. User is an admin which has all rights and therefore the conditional is moot. - // 2. User has its own set of universal rights, which should limit their ability to perform operations. - if universalRights := m.GetUniversalRights(); universalRights != nil { + universalRights := m.GetUniversalRights() + if universalRights != nil && limitRights { return RightsFrom(rights...).Intersect(universalRights).GetRights() } From 6d1ebfdf3513c3a5d6e58420ae160c9d75e675cb Mon Sep 17 00:00:00 2001 From: Nicholas Cristofaro Date: Wed, 27 Nov 2024 08:02:27 -0300 Subject: [PATCH 40/40] is: Update notification filters to user SupportUserID constant --- pkg/identityserver/email.go | 2 +- pkg/identityserver/notification_registry.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/identityserver/email.go b/pkg/identityserver/email.go index 9407a67554..d19b0b353e 100644 --- a/pkg/identityserver/email.go +++ b/pkg/identityserver/email.go @@ -105,7 +105,7 @@ func (is *IdentityServer) SendNotificationEmailToUsers(ctx context.Context, noti // Skips over the possible `support` user. // This user can only be created via the API endpoints defined in the tenant access service. - if receiver.Ids.IDString() == "support" { + if receiver.Ids.IDString() == ttnpb.SupportUserID { continue } diff --git a/pkg/identityserver/notification_registry.go b/pkg/identityserver/notification_registry.go index 6eb9f0b2c2..83db4aa81f 100644 --- a/pkg/identityserver/notification_registry.go +++ b/pkg/identityserver/notification_registry.go @@ -347,7 +347,7 @@ func (is *IdentityServer) notifyAdminsInternal(ctx context.Context, req *ttnpb.C for i, receiver := range receivers { // Skips over the possible `support` user. // This user can only be created via the API endpoints defined in the tenant access service. - if receiver.Ids.IDString() == "support" { + if receiver.Ids.IDString() == ttnpb.SupportUserID { continue } receiverUserIDs[i] = receiver.Ids