diff --git a/cmd/root.go b/cmd/root.go index c5bcb37..6719e81 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -14,6 +14,7 @@ import ( "github.com/pbufio/pbuf-cli/internal/modules" "github.com/pbufio/pbuf-cli/internal/registry" "github.com/spf13/cobra" + "google.golang.org/grpc" ) // NewRootCmd creates cobra root command via function @@ -60,16 +61,20 @@ func NewRootCmd() *cobra.Command { } if modulesConfig.HasRegistry() { - var registryClient v1.RegistryClient + var conn grpc.ClientConnInterface if modulesConfig.Registry.Insecure { - registryClient = registry.NewInsecureClient(modulesConfig, netrcAuth) + conn = registry.NewInsecureConn(modulesConfig, netrcAuth) } else { - registryClient = registry.NewSecureClient(modulesConfig, netrcAuth) + conn = registry.NewSecureConn(modulesConfig, netrcAuth) } + registryClient := v1.NewRegistryClient(conn) + usersClient := v1.NewUserServiceClient(conn) + rootCmd.AddCommand(NewModuleCmd(modulesConfig, registryClient)) rootCmd.AddCommand(NewVendorCmd(modulesConfig, netrcAuth, registryClient)) rootCmd.AddCommand(NewAuthCmd(modulesConfig, usr, netrcAuth)) + rootCmd.AddCommand(NewUsersCmd(modulesConfig, usersClient)) } else { rootCmd.AddCommand(NewVendorCmd(modulesConfig, netrcAuth, nil)) } diff --git a/cmd/users.go b/cmd/users.go new file mode 100644 index 0000000..dd82af1 --- /dev/null +++ b/cmd/users.go @@ -0,0 +1,332 @@ +package cmd + +import ( + "encoding/json" + "errors" + "fmt" + "log" + "strings" + + v1 "github.com/pbufio/pbuf-cli/gen/pbuf-registry/v1" + "github.com/pbufio/pbuf-cli/internal/model" + "github.com/spf13/cobra" +) + +func NewUsersCmd(_ *model.Config, client v1.UserServiceClient) *cobra.Command { + usersCmd := &cobra.Command{ + Use: "users", + Short: "Users", + Long: "Users is a command to manage users, bots, and permissions", + RunE: func(cmd *cobra.Command, args []string) error { + return cmd.Help() + }, + } + + usersCmd.AddCommand(newCreateUserCmd(client)) + usersCmd.AddCommand(newListUsersCmd(client)) + usersCmd.AddCommand(newGetUserCmd(client)) + usersCmd.AddCommand(newUpdateUserCmd(client)) + usersCmd.AddCommand(newDeleteUserCmd(client)) + usersCmd.AddCommand(newRegenerateTokenCmd(client)) + usersCmd.AddCommand(newGrantPermissionCmd(client)) + usersCmd.AddCommand(newRevokePermissionCmd(client)) + usersCmd.AddCommand(newListUserPermissionsCmd(client)) + + return usersCmd +} + +func newCreateUserCmd(client v1.UserServiceClient) *cobra.Command { + createCmd := &cobra.Command{ + Use: "create [name]", + Short: "Create", + Long: "Create is a command to create a user or bot", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + name := args[0] + userTypeStr, err := cmd.Flags().GetString("type") + if err != nil { + return err + } + userType, err := parseUserType(userTypeStr) + if err != nil { + return err + } + + resp, err := client.CreateUser(cmd.Context(), &v1.CreateUserRequest{ + Name: name, + Type: userType, + }) + if err != nil { + return err + } + + return printJSON(resp) + }, + } + + createCmd.Flags().String("type", "user", "user type: user|bot") + return createCmd +} + +func newListUsersCmd(client v1.UserServiceClient) *cobra.Command { + listCmd := &cobra.Command{ + Use: "list", + Short: "List", + Long: "List is a command to list users and bots", + Args: cobra.ExactArgs(0), + RunE: func(cmd *cobra.Command, args []string) error { + pageSize, err := cmd.Flags().GetInt32("page-size") + if err != nil { + return err + } + page, err := cmd.Flags().GetInt32("page") + if err != nil { + return err + } + + resp, err := client.ListUsers(cmd.Context(), &v1.ListUsersRequest{ + PageSize: pageSize, + Page: page, + }) + if err != nil { + return err + } + + return printJSON(resp) + }, + } + + listCmd.Flags().Int32("page-size", 50, "max number of users to return") + listCmd.Flags().Int32("page", 0, "page number (0-indexed)") + return listCmd +} + +func newGetUserCmd(client v1.UserServiceClient) *cobra.Command { + getCmd := &cobra.Command{ + Use: "get [id]", + Short: "Get", + Long: "Get is a command to get a user or bot by id", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + id := args[0] + user, err := client.GetUser(cmd.Context(), &v1.GetUserRequest{Id: id}) + if err != nil { + return err + } + return printJSON(user) + }, + } + + return getCmd +} + +func newUpdateUserCmd(client v1.UserServiceClient) *cobra.Command { + updateCmd := &cobra.Command{ + Use: "update [id]", + Short: "Update", + Long: "Update is a command to update a user or bot", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + id := args[0] + name, err := cmd.Flags().GetString("name") + if err != nil { + return err + } + active, err := cmd.Flags().GetBool("active") + if err != nil { + return err + } + inactive, err := cmd.Flags().GetBool("inactive") + if err != nil { + return err + } + + if active && inactive { + return errors.New("only one of --active or --inactive can be set") + } + if name == "" && !active && !inactive { + return errors.New("nothing to update: specify --name, --active, or --inactive") + } + + isActive := false + switch { + case active: + isActive = true + case inactive: + isActive = false + default: + // Server always applies IsActive from request; preserve current value if not explicitly set. + user, err := client.GetUser(cmd.Context(), &v1.GetUserRequest{Id: id}) + if err != nil { + return err + } + isActive = user.IsActive + } + + updated, err := client.UpdateUser(cmd.Context(), &v1.UpdateUserRequest{ + Id: id, + Name: name, + IsActive: isActive, + }) + if err != nil { + return err + } + return printJSON(updated) + }, + } + + updateCmd.Flags().String("name", "", "new name") + updateCmd.Flags().Bool("active", false, "set user active") + updateCmd.Flags().Bool("inactive", false, "set user inactive") + return updateCmd +} + +func newDeleteUserCmd(client v1.UserServiceClient) *cobra.Command { + deleteCmd := &cobra.Command{ + Use: "delete [id]", + Short: "Delete", + Long: "Delete is a command to delete a user or bot", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + id := args[0] + resp, err := client.DeleteUser(cmd.Context(), &v1.DeleteUserRequest{Id: id}) + if err != nil { + return err + } + return printJSON(resp) + }, + } + + return deleteCmd +} + +func newRegenerateTokenCmd(client v1.UserServiceClient) *cobra.Command { + regenCmd := &cobra.Command{ + Use: "regenerate-token [id]", + Short: "Regenerate token", + Long: "Regenerate token is a command to regenerate a user or bot token", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + id := args[0] + resp, err := client.RegenerateToken(cmd.Context(), &v1.RegenerateTokenRequest{Id: id}) + if err != nil { + return err + } + return printJSON(resp) + }, + } + + return regenCmd +} + +func newGrantPermissionCmd(client v1.UserServiceClient) *cobra.Command { + grantCmd := &cobra.Command{ + Use: "grant-permission [user_id] [module_name]", + Short: "Grant permission", + Long: "Grant permission is a command to grant permission to a user or bot", + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + userID := args[0] + moduleName := args[1] + permissionStr, err := cmd.Flags().GetString("permission") + if err != nil { + return err + } + permission, err := parsePermission(permissionStr) + if err != nil { + return err + } + + resp, err := client.GrantPermission(cmd.Context(), &v1.GrantPermissionRequest{ + UserId: userID, + ModuleName: moduleName, + Permission: permission, + }) + if err != nil { + return err + } + return printJSON(resp) + }, + } + + grantCmd.Flags().String("permission", "", "permission: read|write|admin") + _ = grantCmd.MarkFlagRequired("permission") + return grantCmd +} + +func newRevokePermissionCmd(client v1.UserServiceClient) *cobra.Command { + revokeCmd := &cobra.Command{ + Use: "revoke-permission [user_id] [module_name]", + Short: "Revoke permission", + Long: "Revoke permission is a command to revoke permission from a user or bot", + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + userID := args[0] + moduleName := args[1] + resp, err := client.RevokePermission(cmd.Context(), &v1.RevokePermissionRequest{ + UserId: userID, + ModuleName: moduleName, + }) + if err != nil { + return err + } + return printJSON(resp) + }, + } + + return revokeCmd +} + +func newListUserPermissionsCmd(client v1.UserServiceClient) *cobra.Command { + listCmd := &cobra.Command{ + Use: "list-permissions [user_id]", + Short: "List permissions", + Long: "List permissions is a command to list permissions for a user or bot", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + userID := args[0] + resp, err := client.ListUserPermissions(cmd.Context(), &v1.ListUserPermissionsRequest{UserId: userID}) + if err != nil { + return err + } + return printJSON(resp) + }, + } + + return listCmd +} + +func parseUserType(s string) (v1.UserType, error) { + s = strings.TrimSpace(strings.ToLower(s)) + switch s { + case "", "user": + return v1.UserType_USER_TYPE_USER, nil + case "bot": + return v1.UserType_USER_TYPE_BOT, nil + default: + return v1.UserType_USER_TYPE_UNSPECIFIED, fmt.Errorf("unknown user type %q (expected user|bot)", s) + } +} + +func parsePermission(s string) (v1.Permission, error) { + s = strings.TrimSpace(strings.ToLower(s)) + switch s { + case "read": + return v1.Permission_PERMISSION_READ, nil + case "write": + return v1.Permission_PERMISSION_WRITE, nil + case "admin": + return v1.Permission_PERMISSION_ADMIN, nil + default: + return v1.Permission_PERMISSION_UNSPECIFIED, fmt.Errorf("unknown permission %q (expected read|write|admin)", s) + } +} + +func printJSON(v any) error { + marshalled, err := json.MarshalIndent(v, "", " ") + if err != nil { + return err + } + log.Printf("%+v", string(marshalled)) + return nil +} diff --git a/gen/pbuf-registry/v1/users.pb.go b/gen/pbuf-registry/v1/users.pb.go new file mode 100644 index 0000000..997ea07 --- /dev/null +++ b/gen/pbuf-registry/v1/users.pb.go @@ -0,0 +1,1309 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.11 +// protoc (unknown) +// source: pbuf-registry/v1/users.proto + +package v1 + +import ( + _ "google.golang.org/genproto/googleapis/api/annotations" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// UserType defines the type of user +type UserType int32 + +const ( + UserType_USER_TYPE_UNSPECIFIED UserType = 0 + UserType_USER_TYPE_USER UserType = 1 + UserType_USER_TYPE_BOT UserType = 2 +) + +// Enum value maps for UserType. +var ( + UserType_name = map[int32]string{ + 0: "USER_TYPE_UNSPECIFIED", + 1: "USER_TYPE_USER", + 2: "USER_TYPE_BOT", + } + UserType_value = map[string]int32{ + "USER_TYPE_UNSPECIFIED": 0, + "USER_TYPE_USER": 1, + "USER_TYPE_BOT": 2, + } +) + +func (x UserType) Enum() *UserType { + p := new(UserType) + *p = x + return p +} + +func (x UserType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (UserType) Descriptor() protoreflect.EnumDescriptor { + return file_pbuf_registry_v1_users_proto_enumTypes[0].Descriptor() +} + +func (UserType) Type() protoreflect.EnumType { + return &file_pbuf_registry_v1_users_proto_enumTypes[0] +} + +func (x UserType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use UserType.Descriptor instead. +func (UserType) EnumDescriptor() ([]byte, []int) { + return file_pbuf_registry_v1_users_proto_rawDescGZIP(), []int{0} +} + +// Permission defines the permission level +type Permission int32 + +const ( + Permission_PERMISSION_UNSPECIFIED Permission = 0 + Permission_PERMISSION_READ Permission = 1 + Permission_PERMISSION_WRITE Permission = 2 + Permission_PERMISSION_ADMIN Permission = 3 +) + +// Enum value maps for Permission. +var ( + Permission_name = map[int32]string{ + 0: "PERMISSION_UNSPECIFIED", + 1: "PERMISSION_READ", + 2: "PERMISSION_WRITE", + 3: "PERMISSION_ADMIN", + } + Permission_value = map[string]int32{ + "PERMISSION_UNSPECIFIED": 0, + "PERMISSION_READ": 1, + "PERMISSION_WRITE": 2, + "PERMISSION_ADMIN": 3, + } +) + +func (x Permission) Enum() *Permission { + p := new(Permission) + *p = x + return p +} + +func (x Permission) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Permission) Descriptor() protoreflect.EnumDescriptor { + return file_pbuf_registry_v1_users_proto_enumTypes[1].Descriptor() +} + +func (Permission) Type() protoreflect.EnumType { + return &file_pbuf_registry_v1_users_proto_enumTypes[1] +} + +func (x Permission) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Permission.Descriptor instead. +func (Permission) EnumDescriptor() ([]byte, []int) { + return file_pbuf_registry_v1_users_proto_rawDescGZIP(), []int{1} +} + +// User represents a user or bot in the system +type User struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The unique identifier of the user + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // The name of the user + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + // The type of the user (user or bot) + Type UserType `protobuf:"varint,3,opt,name=type,proto3,enum=pbufregistry.v1.UserType" json:"type,omitempty"` + // Whether the user is active + IsActive bool `protobuf:"varint,4,opt,name=is_active,json=isActive,proto3" json:"is_active,omitempty"` + // When the user was created + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + // When the user was last updated + UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *User) Reset() { + *x = User{} + mi := &file_pbuf_registry_v1_users_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *User) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*User) ProtoMessage() {} + +func (x *User) ProtoReflect() protoreflect.Message { + mi := &file_pbuf_registry_v1_users_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use User.ProtoReflect.Descriptor instead. +func (*User) Descriptor() ([]byte, []int) { + return file_pbuf_registry_v1_users_proto_rawDescGZIP(), []int{0} +} + +func (x *User) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *User) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *User) GetType() UserType { + if x != nil { + return x.Type + } + return UserType_USER_TYPE_UNSPECIFIED +} + +func (x *User) GetIsActive() bool { + if x != nil { + return x.IsActive + } + return false +} + +func (x *User) GetCreatedAt() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +func (x *User) GetUpdatedAt() *timestamppb.Timestamp { + if x != nil { + return x.UpdatedAt + } + return nil +} + +// ACLEntry represents a permission entry +type ACLEntry struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The unique identifier of the ACL entry + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // The user ID this permission belongs to + UserId string `protobuf:"bytes,2,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + // The module name ("*" for all modules) + ModuleName string `protobuf:"bytes,3,opt,name=module_name,json=moduleName,proto3" json:"module_name,omitempty"` + // The permission level + Permission Permission `protobuf:"varint,4,opt,name=permission,proto3,enum=pbufregistry.v1.Permission" json:"permission,omitempty"` + // When the permission was granted + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ACLEntry) Reset() { + *x = ACLEntry{} + mi := &file_pbuf_registry_v1_users_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ACLEntry) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ACLEntry) ProtoMessage() {} + +func (x *ACLEntry) ProtoReflect() protoreflect.Message { + mi := &file_pbuf_registry_v1_users_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ACLEntry.ProtoReflect.Descriptor instead. +func (*ACLEntry) Descriptor() ([]byte, []int) { + return file_pbuf_registry_v1_users_proto_rawDescGZIP(), []int{1} +} + +func (x *ACLEntry) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *ACLEntry) GetUserId() string { + if x != nil { + return x.UserId + } + return "" +} + +func (x *ACLEntry) GetModuleName() string { + if x != nil { + return x.ModuleName + } + return "" +} + +func (x *ACLEntry) GetPermission() Permission { + if x != nil { + return x.Permission + } + return Permission_PERMISSION_UNSPECIFIED +} + +func (x *ACLEntry) GetCreatedAt() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +// CreateUserRequest is the request for creating a user or bot +type CreateUserRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The name of the user + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // The type of the user + Type UserType `protobuf:"varint,2,opt,name=type,proto3,enum=pbufregistry.v1.UserType" json:"type,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CreateUserRequest) Reset() { + *x = CreateUserRequest{} + mi := &file_pbuf_registry_v1_users_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CreateUserRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateUserRequest) ProtoMessage() {} + +func (x *CreateUserRequest) ProtoReflect() protoreflect.Message { + mi := &file_pbuf_registry_v1_users_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateUserRequest.ProtoReflect.Descriptor instead. +func (*CreateUserRequest) Descriptor() ([]byte, []int) { + return file_pbuf_registry_v1_users_proto_rawDescGZIP(), []int{2} +} + +func (x *CreateUserRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *CreateUserRequest) GetType() UserType { + if x != nil { + return x.Type + } + return UserType_USER_TYPE_UNSPECIFIED +} + +// CreateUserResponse is the response for creating a user or bot +type CreateUserResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The created user + User *User `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"` + // The generated token (only returned once) + Token string `protobuf:"bytes,2,opt,name=token,proto3" json:"token,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CreateUserResponse) Reset() { + *x = CreateUserResponse{} + mi := &file_pbuf_registry_v1_users_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CreateUserResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateUserResponse) ProtoMessage() {} + +func (x *CreateUserResponse) ProtoReflect() protoreflect.Message { + mi := &file_pbuf_registry_v1_users_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateUserResponse.ProtoReflect.Descriptor instead. +func (*CreateUserResponse) Descriptor() ([]byte, []int) { + return file_pbuf_registry_v1_users_proto_rawDescGZIP(), []int{3} +} + +func (x *CreateUserResponse) GetUser() *User { + if x != nil { + return x.User + } + return nil +} + +func (x *CreateUserResponse) GetToken() string { + if x != nil { + return x.Token + } + return "" +} + +// ListUsersRequest is the request for listing users +type ListUsersRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The maximum number of users to return + PageSize int32 `protobuf:"varint,1,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"` + // The page number (0-indexed) + Page int32 `protobuf:"varint,2,opt,name=page,proto3" json:"page,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListUsersRequest) Reset() { + *x = ListUsersRequest{} + mi := &file_pbuf_registry_v1_users_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListUsersRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListUsersRequest) ProtoMessage() {} + +func (x *ListUsersRequest) ProtoReflect() protoreflect.Message { + mi := &file_pbuf_registry_v1_users_proto_msgTypes[4] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListUsersRequest.ProtoReflect.Descriptor instead. +func (*ListUsersRequest) Descriptor() ([]byte, []int) { + return file_pbuf_registry_v1_users_proto_rawDescGZIP(), []int{4} +} + +func (x *ListUsersRequest) GetPageSize() int32 { + if x != nil { + return x.PageSize + } + return 0 +} + +func (x *ListUsersRequest) GetPage() int32 { + if x != nil { + return x.Page + } + return 0 +} + +// ListUsersResponse is the response for listing users +type ListUsersResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The list of users + Users []*User `protobuf:"bytes,1,rep,name=users,proto3" json:"users,omitempty"` + // The total number of users + Total int32 `protobuf:"varint,2,opt,name=total,proto3" json:"total,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListUsersResponse) Reset() { + *x = ListUsersResponse{} + mi := &file_pbuf_registry_v1_users_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListUsersResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListUsersResponse) ProtoMessage() {} + +func (x *ListUsersResponse) ProtoReflect() protoreflect.Message { + mi := &file_pbuf_registry_v1_users_proto_msgTypes[5] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListUsersResponse.ProtoReflect.Descriptor instead. +func (*ListUsersResponse) Descriptor() ([]byte, []int) { + return file_pbuf_registry_v1_users_proto_rawDescGZIP(), []int{5} +} + +func (x *ListUsersResponse) GetUsers() []*User { + if x != nil { + return x.Users + } + return nil +} + +func (x *ListUsersResponse) GetTotal() int32 { + if x != nil { + return x.Total + } + return 0 +} + +// GetUserRequest is the request for getting a user +type GetUserRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The ID of the user + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetUserRequest) Reset() { + *x = GetUserRequest{} + mi := &file_pbuf_registry_v1_users_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetUserRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetUserRequest) ProtoMessage() {} + +func (x *GetUserRequest) ProtoReflect() protoreflect.Message { + mi := &file_pbuf_registry_v1_users_proto_msgTypes[6] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetUserRequest.ProtoReflect.Descriptor instead. +func (*GetUserRequest) Descriptor() ([]byte, []int) { + return file_pbuf_registry_v1_users_proto_rawDescGZIP(), []int{6} +} + +func (x *GetUserRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +// UpdateUserRequest is the request for updating a user +type UpdateUserRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The ID of the user + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // The new name (optional) + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + // Whether the user is active (optional) + IsActive bool `protobuf:"varint,3,opt,name=is_active,json=isActive,proto3" json:"is_active,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UpdateUserRequest) Reset() { + *x = UpdateUserRequest{} + mi := &file_pbuf_registry_v1_users_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdateUserRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateUserRequest) ProtoMessage() {} + +func (x *UpdateUserRequest) ProtoReflect() protoreflect.Message { + mi := &file_pbuf_registry_v1_users_proto_msgTypes[7] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateUserRequest.ProtoReflect.Descriptor instead. +func (*UpdateUserRequest) Descriptor() ([]byte, []int) { + return file_pbuf_registry_v1_users_proto_rawDescGZIP(), []int{7} +} + +func (x *UpdateUserRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *UpdateUserRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *UpdateUserRequest) GetIsActive() bool { + if x != nil { + return x.IsActive + } + return false +} + +// DeleteUserRequest is the request for deleting a user +type DeleteUserRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The ID of the user + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DeleteUserRequest) Reset() { + *x = DeleteUserRequest{} + mi := &file_pbuf_registry_v1_users_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DeleteUserRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteUserRequest) ProtoMessage() {} + +func (x *DeleteUserRequest) ProtoReflect() protoreflect.Message { + mi := &file_pbuf_registry_v1_users_proto_msgTypes[8] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteUserRequest.ProtoReflect.Descriptor instead. +func (*DeleteUserRequest) Descriptor() ([]byte, []int) { + return file_pbuf_registry_v1_users_proto_rawDescGZIP(), []int{8} +} + +func (x *DeleteUserRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +// DeleteUserResponse is the response for deleting a user +type DeleteUserResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The ID of the deleted user + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DeleteUserResponse) Reset() { + *x = DeleteUserResponse{} + mi := &file_pbuf_registry_v1_users_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DeleteUserResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteUserResponse) ProtoMessage() {} + +func (x *DeleteUserResponse) ProtoReflect() protoreflect.Message { + mi := &file_pbuf_registry_v1_users_proto_msgTypes[9] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteUserResponse.ProtoReflect.Descriptor instead. +func (*DeleteUserResponse) Descriptor() ([]byte, []int) { + return file_pbuf_registry_v1_users_proto_rawDescGZIP(), []int{9} +} + +func (x *DeleteUserResponse) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +// RegenerateTokenRequest is the request for regenerating a token +type RegenerateTokenRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The ID of the user + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RegenerateTokenRequest) Reset() { + *x = RegenerateTokenRequest{} + mi := &file_pbuf_registry_v1_users_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RegenerateTokenRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RegenerateTokenRequest) ProtoMessage() {} + +func (x *RegenerateTokenRequest) ProtoReflect() protoreflect.Message { + mi := &file_pbuf_registry_v1_users_proto_msgTypes[10] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RegenerateTokenRequest.ProtoReflect.Descriptor instead. +func (*RegenerateTokenRequest) Descriptor() ([]byte, []int) { + return file_pbuf_registry_v1_users_proto_rawDescGZIP(), []int{10} +} + +func (x *RegenerateTokenRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +// RegenerateTokenResponse is the response for regenerating a token +type RegenerateTokenResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The new token + Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RegenerateTokenResponse) Reset() { + *x = RegenerateTokenResponse{} + mi := &file_pbuf_registry_v1_users_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RegenerateTokenResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RegenerateTokenResponse) ProtoMessage() {} + +func (x *RegenerateTokenResponse) ProtoReflect() protoreflect.Message { + mi := &file_pbuf_registry_v1_users_proto_msgTypes[11] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RegenerateTokenResponse.ProtoReflect.Descriptor instead. +func (*RegenerateTokenResponse) Descriptor() ([]byte, []int) { + return file_pbuf_registry_v1_users_proto_rawDescGZIP(), []int{11} +} + +func (x *RegenerateTokenResponse) GetToken() string { + if x != nil { + return x.Token + } + return "" +} + +// GrantPermissionRequest is the request for granting a permission +type GrantPermissionRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The ID of the user + UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + // The module name ("*" for all modules) + ModuleName string `protobuf:"bytes,2,opt,name=module_name,json=moduleName,proto3" json:"module_name,omitempty"` + // The permission level + Permission Permission `protobuf:"varint,3,opt,name=permission,proto3,enum=pbufregistry.v1.Permission" json:"permission,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GrantPermissionRequest) Reset() { + *x = GrantPermissionRequest{} + mi := &file_pbuf_registry_v1_users_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GrantPermissionRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GrantPermissionRequest) ProtoMessage() {} + +func (x *GrantPermissionRequest) ProtoReflect() protoreflect.Message { + mi := &file_pbuf_registry_v1_users_proto_msgTypes[12] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GrantPermissionRequest.ProtoReflect.Descriptor instead. +func (*GrantPermissionRequest) Descriptor() ([]byte, []int) { + return file_pbuf_registry_v1_users_proto_rawDescGZIP(), []int{12} +} + +func (x *GrantPermissionRequest) GetUserId() string { + if x != nil { + return x.UserId + } + return "" +} + +func (x *GrantPermissionRequest) GetModuleName() string { + if x != nil { + return x.ModuleName + } + return "" +} + +func (x *GrantPermissionRequest) GetPermission() Permission { + if x != nil { + return x.Permission + } + return Permission_PERMISSION_UNSPECIFIED +} + +// GrantPermissionResponse is the response for granting a permission +type GrantPermissionResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The created ACL entry + Entry *ACLEntry `protobuf:"bytes,1,opt,name=entry,proto3" json:"entry,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GrantPermissionResponse) Reset() { + *x = GrantPermissionResponse{} + mi := &file_pbuf_registry_v1_users_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GrantPermissionResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GrantPermissionResponse) ProtoMessage() {} + +func (x *GrantPermissionResponse) ProtoReflect() protoreflect.Message { + mi := &file_pbuf_registry_v1_users_proto_msgTypes[13] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GrantPermissionResponse.ProtoReflect.Descriptor instead. +func (*GrantPermissionResponse) Descriptor() ([]byte, []int) { + return file_pbuf_registry_v1_users_proto_rawDescGZIP(), []int{13} +} + +func (x *GrantPermissionResponse) GetEntry() *ACLEntry { + if x != nil { + return x.Entry + } + return nil +} + +// RevokePermissionRequest is the request for revoking a permission +type RevokePermissionRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The ID of the user + UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + // The module name + ModuleName string `protobuf:"bytes,2,opt,name=module_name,json=moduleName,proto3" json:"module_name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RevokePermissionRequest) Reset() { + *x = RevokePermissionRequest{} + mi := &file_pbuf_registry_v1_users_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RevokePermissionRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RevokePermissionRequest) ProtoMessage() {} + +func (x *RevokePermissionRequest) ProtoReflect() protoreflect.Message { + mi := &file_pbuf_registry_v1_users_proto_msgTypes[14] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RevokePermissionRequest.ProtoReflect.Descriptor instead. +func (*RevokePermissionRequest) Descriptor() ([]byte, []int) { + return file_pbuf_registry_v1_users_proto_rawDescGZIP(), []int{14} +} + +func (x *RevokePermissionRequest) GetUserId() string { + if x != nil { + return x.UserId + } + return "" +} + +func (x *RevokePermissionRequest) GetModuleName() string { + if x != nil { + return x.ModuleName + } + return "" +} + +// RevokePermissionResponse is the response for revoking a permission +type RevokePermissionResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Success indicator + Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RevokePermissionResponse) Reset() { + *x = RevokePermissionResponse{} + mi := &file_pbuf_registry_v1_users_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RevokePermissionResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RevokePermissionResponse) ProtoMessage() {} + +func (x *RevokePermissionResponse) ProtoReflect() protoreflect.Message { + mi := &file_pbuf_registry_v1_users_proto_msgTypes[15] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RevokePermissionResponse.ProtoReflect.Descriptor instead. +func (*RevokePermissionResponse) Descriptor() ([]byte, []int) { + return file_pbuf_registry_v1_users_proto_rawDescGZIP(), []int{15} +} + +func (x *RevokePermissionResponse) GetSuccess() bool { + if x != nil { + return x.Success + } + return false +} + +// ListUserPermissionsRequest is the request for listing user permissions +type ListUserPermissionsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The ID of the user + UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListUserPermissionsRequest) Reset() { + *x = ListUserPermissionsRequest{} + mi := &file_pbuf_registry_v1_users_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListUserPermissionsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListUserPermissionsRequest) ProtoMessage() {} + +func (x *ListUserPermissionsRequest) ProtoReflect() protoreflect.Message { + mi := &file_pbuf_registry_v1_users_proto_msgTypes[16] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListUserPermissionsRequest.ProtoReflect.Descriptor instead. +func (*ListUserPermissionsRequest) Descriptor() ([]byte, []int) { + return file_pbuf_registry_v1_users_proto_rawDescGZIP(), []int{16} +} + +func (x *ListUserPermissionsRequest) GetUserId() string { + if x != nil { + return x.UserId + } + return "" +} + +// ListUserPermissionsResponse is the response for listing user permissions +type ListUserPermissionsResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The list of permissions + Permissions []*ACLEntry `protobuf:"bytes,1,rep,name=permissions,proto3" json:"permissions,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListUserPermissionsResponse) Reset() { + *x = ListUserPermissionsResponse{} + mi := &file_pbuf_registry_v1_users_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListUserPermissionsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListUserPermissionsResponse) ProtoMessage() {} + +func (x *ListUserPermissionsResponse) ProtoReflect() protoreflect.Message { + mi := &file_pbuf_registry_v1_users_proto_msgTypes[17] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListUserPermissionsResponse.ProtoReflect.Descriptor instead. +func (*ListUserPermissionsResponse) Descriptor() ([]byte, []int) { + return file_pbuf_registry_v1_users_proto_rawDescGZIP(), []int{17} +} + +func (x *ListUserPermissionsResponse) GetPermissions() []*ACLEntry { + if x != nil { + return x.Permissions + } + return nil +} + +var File_pbuf_registry_v1_users_proto protoreflect.FileDescriptor + +const file_pbuf_registry_v1_users_proto_rawDesc = "" + + "\n" + + "\x1cpbuf-registry/v1/users.proto\x12\x0fpbufregistry.v1\x1a\x1cgoogle/api/annotations.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\xec\x01\n" + + "\x04User\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" + + "\x04name\x18\x02 \x01(\tR\x04name\x12-\n" + + "\x04type\x18\x03 \x01(\x0e2\x19.pbufregistry.v1.UserTypeR\x04type\x12\x1b\n" + + "\tis_active\x18\x04 \x01(\bR\bisActive\x129\n" + + "\n" + + "created_at\x18\x05 \x01(\v2\x1a.google.protobuf.TimestampR\tcreatedAt\x129\n" + + "\n" + + "updated_at\x18\x06 \x01(\v2\x1a.google.protobuf.TimestampR\tupdatedAt\"\xcc\x01\n" + + "\bACLEntry\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12\x17\n" + + "\auser_id\x18\x02 \x01(\tR\x06userId\x12\x1f\n" + + "\vmodule_name\x18\x03 \x01(\tR\n" + + "moduleName\x12;\n" + + "\n" + + "permission\x18\x04 \x01(\x0e2\x1b.pbufregistry.v1.PermissionR\n" + + "permission\x129\n" + + "\n" + + "created_at\x18\x05 \x01(\v2\x1a.google.protobuf.TimestampR\tcreatedAt\"V\n" + + "\x11CreateUserRequest\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\x12-\n" + + "\x04type\x18\x02 \x01(\x0e2\x19.pbufregistry.v1.UserTypeR\x04type\"U\n" + + "\x12CreateUserResponse\x12)\n" + + "\x04user\x18\x01 \x01(\v2\x15.pbufregistry.v1.UserR\x04user\x12\x14\n" + + "\x05token\x18\x02 \x01(\tR\x05token\"C\n" + + "\x10ListUsersRequest\x12\x1b\n" + + "\tpage_size\x18\x01 \x01(\x05R\bpageSize\x12\x12\n" + + "\x04page\x18\x02 \x01(\x05R\x04page\"V\n" + + "\x11ListUsersResponse\x12+\n" + + "\x05users\x18\x01 \x03(\v2\x15.pbufregistry.v1.UserR\x05users\x12\x14\n" + + "\x05total\x18\x02 \x01(\x05R\x05total\" \n" + + "\x0eGetUserRequest\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\"T\n" + + "\x11UpdateUserRequest\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" + + "\x04name\x18\x02 \x01(\tR\x04name\x12\x1b\n" + + "\tis_active\x18\x03 \x01(\bR\bisActive\"#\n" + + "\x11DeleteUserRequest\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\"$\n" + + "\x12DeleteUserResponse\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\"(\n" + + "\x16RegenerateTokenRequest\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\"/\n" + + "\x17RegenerateTokenResponse\x12\x14\n" + + "\x05token\x18\x01 \x01(\tR\x05token\"\x8f\x01\n" + + "\x16GrantPermissionRequest\x12\x17\n" + + "\auser_id\x18\x01 \x01(\tR\x06userId\x12\x1f\n" + + "\vmodule_name\x18\x02 \x01(\tR\n" + + "moduleName\x12;\n" + + "\n" + + "permission\x18\x03 \x01(\x0e2\x1b.pbufregistry.v1.PermissionR\n" + + "permission\"J\n" + + "\x17GrantPermissionResponse\x12/\n" + + "\x05entry\x18\x01 \x01(\v2\x19.pbufregistry.v1.ACLEntryR\x05entry\"S\n" + + "\x17RevokePermissionRequest\x12\x17\n" + + "\auser_id\x18\x01 \x01(\tR\x06userId\x12\x1f\n" + + "\vmodule_name\x18\x02 \x01(\tR\n" + + "moduleName\"4\n" + + "\x18RevokePermissionResponse\x12\x18\n" + + "\asuccess\x18\x01 \x01(\bR\asuccess\"5\n" + + "\x1aListUserPermissionsRequest\x12\x17\n" + + "\auser_id\x18\x01 \x01(\tR\x06userId\"Z\n" + + "\x1bListUserPermissionsResponse\x12;\n" + + "\vpermissions\x18\x01 \x03(\v2\x19.pbufregistry.v1.ACLEntryR\vpermissions*L\n" + + "\bUserType\x12\x19\n" + + "\x15USER_TYPE_UNSPECIFIED\x10\x00\x12\x12\n" + + "\x0eUSER_TYPE_USER\x10\x01\x12\x11\n" + + "\rUSER_TYPE_BOT\x10\x02*i\n" + + "\n" + + "Permission\x12\x1a\n" + + "\x16PERMISSION_UNSPECIFIED\x10\x00\x12\x13\n" + + "\x0fPERMISSION_READ\x10\x01\x12\x14\n" + + "\x10PERMISSION_WRITE\x10\x02\x12\x14\n" + + "\x10PERMISSION_ADMIN\x10\x032\xf2\b\n" + + "\vUserService\x12k\n" + + "\n" + + "CreateUser\x12\".pbufregistry.v1.CreateUserRequest\x1a#.pbufregistry.v1.CreateUserResponse\"\x14\x82\xd3\xe4\x93\x02\x0e:\x01*\"\t/v1/users\x12e\n" + + "\tListUsers\x12!.pbufregistry.v1.ListUsersRequest\x1a\".pbufregistry.v1.ListUsersResponse\"\x11\x82\xd3\xe4\x93\x02\v\x12\t/v1/users\x12Y\n" + + "\aGetUser\x12\x1f.pbufregistry.v1.GetUserRequest\x1a\x15.pbufregistry.v1.User\"\x16\x82\xd3\xe4\x93\x02\x10\x12\x0e/v1/users/{id}\x12b\n" + + "\n" + + "UpdateUser\x12\".pbufregistry.v1.UpdateUserRequest\x1a\x15.pbufregistry.v1.User\"\x19\x82\xd3\xe4\x93\x02\x13:\x01*\x1a\x0e/v1/users/{id}\x12m\n" + + "\n" + + "DeleteUser\x12\".pbufregistry.v1.DeleteUserRequest\x1a#.pbufregistry.v1.DeleteUserResponse\"\x16\x82\xd3\xe4\x93\x02\x10*\x0e/v1/users/{id}\x12\x90\x01\n" + + "\x0fRegenerateToken\x12'.pbufregistry.v1.RegenerateTokenRequest\x1a(.pbufregistry.v1.RegenerateTokenResponse\"*\x82\xd3\xe4\x93\x02$:\x01*\"\x1f/v1/users/{id}/regenerate-token\x12\x90\x01\n" + + "\x0fGrantPermission\x12'.pbufregistry.v1.GrantPermissionRequest\x1a(.pbufregistry.v1.GrantPermissionResponse\"*\x82\xd3\xe4\x93\x02$:\x01*\"\x1f/v1/users/{user_id}/permissions\x12\x9e\x01\n" + + "\x10RevokePermission\x12(.pbufregistry.v1.RevokePermissionRequest\x1a).pbufregistry.v1.RevokePermissionResponse\"5\x82\xd3\xe4\x93\x02/*-/v1/users/{user_id}/permissions/{module_name}\x12\x99\x01\n" + + "\x13ListUserPermissions\x12+.pbufregistry.v1.ListUserPermissionsRequest\x1a,.pbufregistry.v1.ListUserPermissionsResponse\"'\x82\xd3\xe4\x93\x02!\x12\x1f/v1/users/{user_id}/permissionsB4Z2github.com/pbufio/pbuf-cli/gen/pbuf-registry/v1;v1b\x06proto3" + +var ( + file_pbuf_registry_v1_users_proto_rawDescOnce sync.Once + file_pbuf_registry_v1_users_proto_rawDescData []byte +) + +func file_pbuf_registry_v1_users_proto_rawDescGZIP() []byte { + file_pbuf_registry_v1_users_proto_rawDescOnce.Do(func() { + file_pbuf_registry_v1_users_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_pbuf_registry_v1_users_proto_rawDesc), len(file_pbuf_registry_v1_users_proto_rawDesc))) + }) + return file_pbuf_registry_v1_users_proto_rawDescData +} + +var file_pbuf_registry_v1_users_proto_enumTypes = make([]protoimpl.EnumInfo, 2) +var file_pbuf_registry_v1_users_proto_msgTypes = make([]protoimpl.MessageInfo, 18) +var file_pbuf_registry_v1_users_proto_goTypes = []any{ + (UserType)(0), // 0: pbufregistry.v1.UserType + (Permission)(0), // 1: pbufregistry.v1.Permission + (*User)(nil), // 2: pbufregistry.v1.User + (*ACLEntry)(nil), // 3: pbufregistry.v1.ACLEntry + (*CreateUserRequest)(nil), // 4: pbufregistry.v1.CreateUserRequest + (*CreateUserResponse)(nil), // 5: pbufregistry.v1.CreateUserResponse + (*ListUsersRequest)(nil), // 6: pbufregistry.v1.ListUsersRequest + (*ListUsersResponse)(nil), // 7: pbufregistry.v1.ListUsersResponse + (*GetUserRequest)(nil), // 8: pbufregistry.v1.GetUserRequest + (*UpdateUserRequest)(nil), // 9: pbufregistry.v1.UpdateUserRequest + (*DeleteUserRequest)(nil), // 10: pbufregistry.v1.DeleteUserRequest + (*DeleteUserResponse)(nil), // 11: pbufregistry.v1.DeleteUserResponse + (*RegenerateTokenRequest)(nil), // 12: pbufregistry.v1.RegenerateTokenRequest + (*RegenerateTokenResponse)(nil), // 13: pbufregistry.v1.RegenerateTokenResponse + (*GrantPermissionRequest)(nil), // 14: pbufregistry.v1.GrantPermissionRequest + (*GrantPermissionResponse)(nil), // 15: pbufregistry.v1.GrantPermissionResponse + (*RevokePermissionRequest)(nil), // 16: pbufregistry.v1.RevokePermissionRequest + (*RevokePermissionResponse)(nil), // 17: pbufregistry.v1.RevokePermissionResponse + (*ListUserPermissionsRequest)(nil), // 18: pbufregistry.v1.ListUserPermissionsRequest + (*ListUserPermissionsResponse)(nil), // 19: pbufregistry.v1.ListUserPermissionsResponse + (*timestamppb.Timestamp)(nil), // 20: google.protobuf.Timestamp +} +var file_pbuf_registry_v1_users_proto_depIdxs = []int32{ + 0, // 0: pbufregistry.v1.User.type:type_name -> pbufregistry.v1.UserType + 20, // 1: pbufregistry.v1.User.created_at:type_name -> google.protobuf.Timestamp + 20, // 2: pbufregistry.v1.User.updated_at:type_name -> google.protobuf.Timestamp + 1, // 3: pbufregistry.v1.ACLEntry.permission:type_name -> pbufregistry.v1.Permission + 20, // 4: pbufregistry.v1.ACLEntry.created_at:type_name -> google.protobuf.Timestamp + 0, // 5: pbufregistry.v1.CreateUserRequest.type:type_name -> pbufregistry.v1.UserType + 2, // 6: pbufregistry.v1.CreateUserResponse.user:type_name -> pbufregistry.v1.User + 2, // 7: pbufregistry.v1.ListUsersResponse.users:type_name -> pbufregistry.v1.User + 1, // 8: pbufregistry.v1.GrantPermissionRequest.permission:type_name -> pbufregistry.v1.Permission + 3, // 9: pbufregistry.v1.GrantPermissionResponse.entry:type_name -> pbufregistry.v1.ACLEntry + 3, // 10: pbufregistry.v1.ListUserPermissionsResponse.permissions:type_name -> pbufregistry.v1.ACLEntry + 4, // 11: pbufregistry.v1.UserService.CreateUser:input_type -> pbufregistry.v1.CreateUserRequest + 6, // 12: pbufregistry.v1.UserService.ListUsers:input_type -> pbufregistry.v1.ListUsersRequest + 8, // 13: pbufregistry.v1.UserService.GetUser:input_type -> pbufregistry.v1.GetUserRequest + 9, // 14: pbufregistry.v1.UserService.UpdateUser:input_type -> pbufregistry.v1.UpdateUserRequest + 10, // 15: pbufregistry.v1.UserService.DeleteUser:input_type -> pbufregistry.v1.DeleteUserRequest + 12, // 16: pbufregistry.v1.UserService.RegenerateToken:input_type -> pbufregistry.v1.RegenerateTokenRequest + 14, // 17: pbufregistry.v1.UserService.GrantPermission:input_type -> pbufregistry.v1.GrantPermissionRequest + 16, // 18: pbufregistry.v1.UserService.RevokePermission:input_type -> pbufregistry.v1.RevokePermissionRequest + 18, // 19: pbufregistry.v1.UserService.ListUserPermissions:input_type -> pbufregistry.v1.ListUserPermissionsRequest + 5, // 20: pbufregistry.v1.UserService.CreateUser:output_type -> pbufregistry.v1.CreateUserResponse + 7, // 21: pbufregistry.v1.UserService.ListUsers:output_type -> pbufregistry.v1.ListUsersResponse + 2, // 22: pbufregistry.v1.UserService.GetUser:output_type -> pbufregistry.v1.User + 2, // 23: pbufregistry.v1.UserService.UpdateUser:output_type -> pbufregistry.v1.User + 11, // 24: pbufregistry.v1.UserService.DeleteUser:output_type -> pbufregistry.v1.DeleteUserResponse + 13, // 25: pbufregistry.v1.UserService.RegenerateToken:output_type -> pbufregistry.v1.RegenerateTokenResponse + 15, // 26: pbufregistry.v1.UserService.GrantPermission:output_type -> pbufregistry.v1.GrantPermissionResponse + 17, // 27: pbufregistry.v1.UserService.RevokePermission:output_type -> pbufregistry.v1.RevokePermissionResponse + 19, // 28: pbufregistry.v1.UserService.ListUserPermissions:output_type -> pbufregistry.v1.ListUserPermissionsResponse + 20, // [20:29] is the sub-list for method output_type + 11, // [11:20] is the sub-list for method input_type + 11, // [11:11] is the sub-list for extension type_name + 11, // [11:11] is the sub-list for extension extendee + 0, // [0:11] is the sub-list for field type_name +} + +func init() { file_pbuf_registry_v1_users_proto_init() } +func file_pbuf_registry_v1_users_proto_init() { + if File_pbuf_registry_v1_users_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_pbuf_registry_v1_users_proto_rawDesc), len(file_pbuf_registry_v1_users_proto_rawDesc)), + NumEnums: 2, + NumMessages: 18, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_pbuf_registry_v1_users_proto_goTypes, + DependencyIndexes: file_pbuf_registry_v1_users_proto_depIdxs, + EnumInfos: file_pbuf_registry_v1_users_proto_enumTypes, + MessageInfos: file_pbuf_registry_v1_users_proto_msgTypes, + }.Build() + File_pbuf_registry_v1_users_proto = out.File + file_pbuf_registry_v1_users_proto_goTypes = nil + file_pbuf_registry_v1_users_proto_depIdxs = nil +} diff --git a/gen/pbuf-registry/v1/users_grpc.pb.go b/gen/pbuf-registry/v1/users_grpc.pb.go new file mode 100644 index 0000000..96953d7 --- /dev/null +++ b/gen/pbuf-registry/v1/users_grpc.pb.go @@ -0,0 +1,447 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.6.0 +// - protoc (unknown) +// source: pbuf-registry/v1/users.proto + +package v1 + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 + +const ( + UserService_CreateUser_FullMethodName = "/pbufregistry.v1.UserService/CreateUser" + UserService_ListUsers_FullMethodName = "/pbufregistry.v1.UserService/ListUsers" + UserService_GetUser_FullMethodName = "/pbufregistry.v1.UserService/GetUser" + UserService_UpdateUser_FullMethodName = "/pbufregistry.v1.UserService/UpdateUser" + UserService_DeleteUser_FullMethodName = "/pbufregistry.v1.UserService/DeleteUser" + UserService_RegenerateToken_FullMethodName = "/pbufregistry.v1.UserService/RegenerateToken" + UserService_GrantPermission_FullMethodName = "/pbufregistry.v1.UserService/GrantPermission" + UserService_RevokePermission_FullMethodName = "/pbufregistry.v1.UserService/RevokePermission" + UserService_ListUserPermissions_FullMethodName = "/pbufregistry.v1.UserService/ListUserPermissions" +) + +// UserServiceClient is the client API for UserService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +// +// UserService manages users, bots, and their permissions +type UserServiceClient interface { + // Create a new user or bot + CreateUser(ctx context.Context, in *CreateUserRequest, opts ...grpc.CallOption) (*CreateUserResponse, error) + // List all users and bots + ListUsers(ctx context.Context, in *ListUsersRequest, opts ...grpc.CallOption) (*ListUsersResponse, error) + // Get a user or bot by ID + GetUser(ctx context.Context, in *GetUserRequest, opts ...grpc.CallOption) (*User, error) + // Update a user or bot + UpdateUser(ctx context.Context, in *UpdateUserRequest, opts ...grpc.CallOption) (*User, error) + // Delete a user or bot + DeleteUser(ctx context.Context, in *DeleteUserRequest, opts ...grpc.CallOption) (*DeleteUserResponse, error) + // Regenerate a user or bot token + RegenerateToken(ctx context.Context, in *RegenerateTokenRequest, opts ...grpc.CallOption) (*RegenerateTokenResponse, error) + // Grant permission to a user or bot + GrantPermission(ctx context.Context, in *GrantPermissionRequest, opts ...grpc.CallOption) (*GrantPermissionResponse, error) + // Revoke permission from a user or bot + RevokePermission(ctx context.Context, in *RevokePermissionRequest, opts ...grpc.CallOption) (*RevokePermissionResponse, error) + // List permissions for a user or bot + ListUserPermissions(ctx context.Context, in *ListUserPermissionsRequest, opts ...grpc.CallOption) (*ListUserPermissionsResponse, error) +} + +type userServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewUserServiceClient(cc grpc.ClientConnInterface) UserServiceClient { + return &userServiceClient{cc} +} + +func (c *userServiceClient) CreateUser(ctx context.Context, in *CreateUserRequest, opts ...grpc.CallOption) (*CreateUserResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(CreateUserResponse) + err := c.cc.Invoke(ctx, UserService_CreateUser_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *userServiceClient) ListUsers(ctx context.Context, in *ListUsersRequest, opts ...grpc.CallOption) (*ListUsersResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ListUsersResponse) + err := c.cc.Invoke(ctx, UserService_ListUsers_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *userServiceClient) GetUser(ctx context.Context, in *GetUserRequest, opts ...grpc.CallOption) (*User, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(User) + err := c.cc.Invoke(ctx, UserService_GetUser_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *userServiceClient) UpdateUser(ctx context.Context, in *UpdateUserRequest, opts ...grpc.CallOption) (*User, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(User) + err := c.cc.Invoke(ctx, UserService_UpdateUser_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *userServiceClient) DeleteUser(ctx context.Context, in *DeleteUserRequest, opts ...grpc.CallOption) (*DeleteUserResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(DeleteUserResponse) + err := c.cc.Invoke(ctx, UserService_DeleteUser_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *userServiceClient) RegenerateToken(ctx context.Context, in *RegenerateTokenRequest, opts ...grpc.CallOption) (*RegenerateTokenResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(RegenerateTokenResponse) + err := c.cc.Invoke(ctx, UserService_RegenerateToken_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *userServiceClient) GrantPermission(ctx context.Context, in *GrantPermissionRequest, opts ...grpc.CallOption) (*GrantPermissionResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(GrantPermissionResponse) + err := c.cc.Invoke(ctx, UserService_GrantPermission_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *userServiceClient) RevokePermission(ctx context.Context, in *RevokePermissionRequest, opts ...grpc.CallOption) (*RevokePermissionResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(RevokePermissionResponse) + err := c.cc.Invoke(ctx, UserService_RevokePermission_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *userServiceClient) ListUserPermissions(ctx context.Context, in *ListUserPermissionsRequest, opts ...grpc.CallOption) (*ListUserPermissionsResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ListUserPermissionsResponse) + err := c.cc.Invoke(ctx, UserService_ListUserPermissions_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +// UserServiceServer is the server API for UserService service. +// All implementations must embed UnimplementedUserServiceServer +// for forward compatibility. +// +// UserService manages users, bots, and their permissions +type UserServiceServer interface { + // Create a new user or bot + CreateUser(context.Context, *CreateUserRequest) (*CreateUserResponse, error) + // List all users and bots + ListUsers(context.Context, *ListUsersRequest) (*ListUsersResponse, error) + // Get a user or bot by ID + GetUser(context.Context, *GetUserRequest) (*User, error) + // Update a user or bot + UpdateUser(context.Context, *UpdateUserRequest) (*User, error) + // Delete a user or bot + DeleteUser(context.Context, *DeleteUserRequest) (*DeleteUserResponse, error) + // Regenerate a user or bot token + RegenerateToken(context.Context, *RegenerateTokenRequest) (*RegenerateTokenResponse, error) + // Grant permission to a user or bot + GrantPermission(context.Context, *GrantPermissionRequest) (*GrantPermissionResponse, error) + // Revoke permission from a user or bot + RevokePermission(context.Context, *RevokePermissionRequest) (*RevokePermissionResponse, error) + // List permissions for a user or bot + ListUserPermissions(context.Context, *ListUserPermissionsRequest) (*ListUserPermissionsResponse, error) + mustEmbedUnimplementedUserServiceServer() +} + +// UnimplementedUserServiceServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedUserServiceServer struct{} + +func (UnimplementedUserServiceServer) CreateUser(context.Context, *CreateUserRequest) (*CreateUserResponse, error) { + return nil, status.Error(codes.Unimplemented, "method CreateUser not implemented") +} +func (UnimplementedUserServiceServer) ListUsers(context.Context, *ListUsersRequest) (*ListUsersResponse, error) { + return nil, status.Error(codes.Unimplemented, "method ListUsers not implemented") +} +func (UnimplementedUserServiceServer) GetUser(context.Context, *GetUserRequest) (*User, error) { + return nil, status.Error(codes.Unimplemented, "method GetUser not implemented") +} +func (UnimplementedUserServiceServer) UpdateUser(context.Context, *UpdateUserRequest) (*User, error) { + return nil, status.Error(codes.Unimplemented, "method UpdateUser not implemented") +} +func (UnimplementedUserServiceServer) DeleteUser(context.Context, *DeleteUserRequest) (*DeleteUserResponse, error) { + return nil, status.Error(codes.Unimplemented, "method DeleteUser not implemented") +} +func (UnimplementedUserServiceServer) RegenerateToken(context.Context, *RegenerateTokenRequest) (*RegenerateTokenResponse, error) { + return nil, status.Error(codes.Unimplemented, "method RegenerateToken not implemented") +} +func (UnimplementedUserServiceServer) GrantPermission(context.Context, *GrantPermissionRequest) (*GrantPermissionResponse, error) { + return nil, status.Error(codes.Unimplemented, "method GrantPermission not implemented") +} +func (UnimplementedUserServiceServer) RevokePermission(context.Context, *RevokePermissionRequest) (*RevokePermissionResponse, error) { + return nil, status.Error(codes.Unimplemented, "method RevokePermission not implemented") +} +func (UnimplementedUserServiceServer) ListUserPermissions(context.Context, *ListUserPermissionsRequest) (*ListUserPermissionsResponse, error) { + return nil, status.Error(codes.Unimplemented, "method ListUserPermissions not implemented") +} +func (UnimplementedUserServiceServer) mustEmbedUnimplementedUserServiceServer() {} +func (UnimplementedUserServiceServer) testEmbeddedByValue() {} + +// UnsafeUserServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to UserServiceServer will +// result in compilation errors. +type UnsafeUserServiceServer interface { + mustEmbedUnimplementedUserServiceServer() +} + +func RegisterUserServiceServer(s grpc.ServiceRegistrar, srv UserServiceServer) { + // If the following call panics, it indicates UnimplementedUserServiceServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } + s.RegisterService(&UserService_ServiceDesc, srv) +} + +func _UserService_CreateUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateUserRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServiceServer).CreateUser(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: UserService_CreateUser_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServiceServer).CreateUser(ctx, req.(*CreateUserRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _UserService_ListUsers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListUsersRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServiceServer).ListUsers(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: UserService_ListUsers_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServiceServer).ListUsers(ctx, req.(*ListUsersRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _UserService_GetUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetUserRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServiceServer).GetUser(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: UserService_GetUser_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServiceServer).GetUser(ctx, req.(*GetUserRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _UserService_UpdateUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateUserRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServiceServer).UpdateUser(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: UserService_UpdateUser_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServiceServer).UpdateUser(ctx, req.(*UpdateUserRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _UserService_DeleteUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteUserRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServiceServer).DeleteUser(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: UserService_DeleteUser_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServiceServer).DeleteUser(ctx, req.(*DeleteUserRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _UserService_RegenerateToken_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RegenerateTokenRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServiceServer).RegenerateToken(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: UserService_RegenerateToken_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServiceServer).RegenerateToken(ctx, req.(*RegenerateTokenRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _UserService_GrantPermission_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GrantPermissionRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServiceServer).GrantPermission(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: UserService_GrantPermission_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServiceServer).GrantPermission(ctx, req.(*GrantPermissionRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _UserService_RevokePermission_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RevokePermissionRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServiceServer).RevokePermission(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: UserService_RevokePermission_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServiceServer).RevokePermission(ctx, req.(*RevokePermissionRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _UserService_ListUserPermissions_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListUserPermissionsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServiceServer).ListUserPermissions(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: UserService_ListUserPermissions_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServiceServer).ListUserPermissions(ctx, req.(*ListUserPermissionsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// UserService_ServiceDesc is the grpc.ServiceDesc for UserService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var UserService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "pbufregistry.v1.UserService", + HandlerType: (*UserServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "CreateUser", + Handler: _UserService_CreateUser_Handler, + }, + { + MethodName: "ListUsers", + Handler: _UserService_ListUsers_Handler, + }, + { + MethodName: "GetUser", + Handler: _UserService_GetUser_Handler, + }, + { + MethodName: "UpdateUser", + Handler: _UserService_UpdateUser_Handler, + }, + { + MethodName: "DeleteUser", + Handler: _UserService_DeleteUser_Handler, + }, + { + MethodName: "RegenerateToken", + Handler: _UserService_RegenerateToken_Handler, + }, + { + MethodName: "GrantPermission", + Handler: _UserService_GrantPermission_Handler, + }, + { + MethodName: "RevokePermission", + Handler: _UserService_RevokePermission_Handler, + }, + { + MethodName: "ListUserPermissions", + Handler: _UserService_ListUserPermissions_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "pbuf-registry/v1/users.proto", +} diff --git a/internal/registry/client.go b/internal/registry/client.go index c86e643..df6c71e 100644 --- a/internal/registry/client.go +++ b/internal/registry/client.go @@ -17,6 +17,27 @@ import ( // NewInsecureClient generates insecure grpc client func NewInsecureClient(config *model.Config, netrcAuth *netrc.Netrc) v1.RegistryClient { + return v1.NewRegistryClient(NewInsecureConn(config, netrcAuth)) +} + +// NewSecureClient generates secure grpc client +// Should use TLS to secure the connection +func NewSecureClient(config *model.Config, netrcAuth *netrc.Netrc) v1.RegistryClient { + return v1.NewRegistryClient(NewSecureConn(config, netrcAuth)) +} + +// NewInsecureUserServiceClient generates insecure grpc client for UserService. +func NewInsecureUserServiceClient(config *model.Config, netrcAuth *netrc.Netrc) v1.UserServiceClient { + return v1.NewUserServiceClient(NewInsecureConn(config, netrcAuth)) +} + +// NewSecureUserServiceClient generates secure grpc client for UserService. +func NewSecureUserServiceClient(config *model.Config, netrcAuth *netrc.Netrc) v1.UserServiceClient { + return v1.NewUserServiceClient(NewSecureConn(config, netrcAuth)) +} + +// NewInsecureConn creates an insecure gRPC connection to registry. +func NewInsecureConn(config *model.Config, netrcAuth *netrc.Netrc) *grpc.ClientConn { addr := canonicalizeAddr(config.Registry.Addr) opts := []grpc.DialOption{ @@ -28,14 +49,16 @@ func NewInsecureClient(config *model.Config, netrcAuth *netrc.Netrc) v1.Registry opts = append(opts, grpc.WithPerRPCCredentials(perRPCCredentials)) } - grpcClient, _ := grpc.NewClient(addr, opts...) + grpcClient, err := grpc.NewClient(addr, opts...) + if err != nil { + log.Fatalf("failed to create grpc client: %v", err) + } - return v1.NewRegistryClient(grpcClient) + return grpcClient } -// NewSecureClient generates secure grpc client -// Should use TLS to secure the connection -func NewSecureClient(config *model.Config, netrcAuth *netrc.Netrc) v1.RegistryClient { +// NewSecureConn creates a secure (TLS) gRPC connection to registry. +func NewSecureConn(config *model.Config, netrcAuth *netrc.Netrc) *grpc.ClientConn { certPool, err := x509.SystemCertPool() if err != nil { log.Fatalf("failed to load system cert pool: %v", err) @@ -56,9 +79,12 @@ func NewSecureClient(config *model.Config, netrcAuth *netrc.Netrc) v1.RegistryCl opts = append(opts, grpc.WithPerRPCCredentials(perRPCCredentials)) } - grpcClient, _ := grpc.NewClient(addr, opts...) + grpcClient, err := grpc.NewClient(addr, opts...) + if err != nil { + log.Fatalf("failed to create grpc client: %v", err) + } - return v1.NewRegistryClient(grpcClient) + return grpcClient } // canonicalizeAddr check has the address port or not diff --git a/pbuf.yaml b/pbuf.yaml index 2429f24..2915123 100644 --- a/pbuf.yaml +++ b/pbuf.yaml @@ -5,7 +5,7 @@ registry: modules: - name: pbufio/pbuf-registry path: api/pbuf-registry - tag: v0.4.1 + tag: v0.5.0 out: third_party/pbuf-registry gen_out: gen/pbuf-registry - name: googleapis diff --git a/third_party/pbuf-registry/v1/users.proto b/third_party/pbuf-registry/v1/users.proto new file mode 100644 index 0000000..385f557 --- /dev/null +++ b/third_party/pbuf-registry/v1/users.proto @@ -0,0 +1,255 @@ +syntax = "proto3"; + +package pbufregistry.v1; + +import "google/api/annotations.proto"; +import "google/protobuf/timestamp.proto"; + +option go_package = "github.com/pbufio/pbuf-cli/gen/pbuf-registry/v1;v1"; + +// UserService manages users, bots, and their permissions +service UserService { + // Create a new user or bot + rpc CreateUser(CreateUserRequest) returns (CreateUserResponse) { + option (google.api.http) = { + post: "/v1/users" + body: "*" + }; + } + + // List all users and bots + rpc ListUsers(ListUsersRequest) returns (ListUsersResponse) { + option (google.api.http) = { + get: "/v1/users" + }; + } + + // Get a user or bot by ID + rpc GetUser(GetUserRequest) returns (User) { + option (google.api.http) = { + get: "/v1/users/{id}" + }; + } + + // Update a user or bot + rpc UpdateUser(UpdateUserRequest) returns (User) { + option (google.api.http) = { + put: "/v1/users/{id}" + body: "*" + }; + } + + // Delete a user or bot + rpc DeleteUser(DeleteUserRequest) returns (DeleteUserResponse) { + option (google.api.http) = { + delete: "/v1/users/{id}" + }; + } + + // Regenerate a user or bot token + rpc RegenerateToken(RegenerateTokenRequest) returns (RegenerateTokenResponse) { + option (google.api.http) = { + post: "/v1/users/{id}/regenerate-token" + body: "*" + }; + } + + // Grant permission to a user or bot + rpc GrantPermission(GrantPermissionRequest) returns (GrantPermissionResponse) { + option (google.api.http) = { + post: "/v1/users/{user_id}/permissions" + body: "*" + }; + } + + // Revoke permission from a user or bot + rpc RevokePermission(RevokePermissionRequest) returns (RevokePermissionResponse) { + option (google.api.http) = { + delete: "/v1/users/{user_id}/permissions/{module_name}" + }; + } + + // List permissions for a user or bot + rpc ListUserPermissions(ListUserPermissionsRequest) returns (ListUserPermissionsResponse) { + option (google.api.http) = { + get: "/v1/users/{user_id}/permissions" + }; + } +} + +// User represents a user or bot in the system +message User { + // The unique identifier of the user + string id = 1; + + // The name of the user + string name = 2; + + // The type of the user (user or bot) + UserType type = 3; + + // Whether the user is active + bool is_active = 4; + + // When the user was created + google.protobuf.Timestamp created_at = 5; + + // When the user was last updated + google.protobuf.Timestamp updated_at = 6; +} + +// UserType defines the type of user +enum UserType { + USER_TYPE_UNSPECIFIED = 0; + USER_TYPE_USER = 1; + USER_TYPE_BOT = 2; +} + +// Permission defines the permission level +enum Permission { + PERMISSION_UNSPECIFIED = 0; + PERMISSION_READ = 1; + PERMISSION_WRITE = 2; + PERMISSION_ADMIN = 3; +} + +// ACLEntry represents a permission entry +message ACLEntry { + // The unique identifier of the ACL entry + string id = 1; + + // The user ID this permission belongs to + string user_id = 2; + + // The module name ("*" for all modules) + string module_name = 3; + + // The permission level + Permission permission = 4; + + // When the permission was granted + google.protobuf.Timestamp created_at = 5; +} + +// CreateUserRequest is the request for creating a user or bot +message CreateUserRequest { + // The name of the user + string name = 1; + + // The type of the user + UserType type = 2; +} + +// CreateUserResponse is the response for creating a user or bot +message CreateUserResponse { + // The created user + User user = 1; + + // The generated token (only returned once) + string token = 2; +} + +// ListUsersRequest is the request for listing users +message ListUsersRequest { + // The maximum number of users to return + int32 page_size = 1; + + // The page number (0-indexed) + int32 page = 2; +} + +// ListUsersResponse is the response for listing users +message ListUsersResponse { + // The list of users + repeated User users = 1; + + // The total number of users + int32 total = 2; +} + +// GetUserRequest is the request for getting a user +message GetUserRequest { + // The ID of the user + string id = 1; +} + +// UpdateUserRequest is the request for updating a user +message UpdateUserRequest { + // The ID of the user + string id = 1; + + // The new name (optional) + string name = 2; + + // Whether the user is active (optional) + bool is_active = 3; +} + +// DeleteUserRequest is the request for deleting a user +message DeleteUserRequest { + // The ID of the user + string id = 1; +} + +// DeleteUserResponse is the response for deleting a user +message DeleteUserResponse { + // The ID of the deleted user + string id = 1; +} + +// RegenerateTokenRequest is the request for regenerating a token +message RegenerateTokenRequest { + // The ID of the user + string id = 1; +} + +// RegenerateTokenResponse is the response for regenerating a token +message RegenerateTokenResponse { + // The new token + string token = 1; +} + +// GrantPermissionRequest is the request for granting a permission +message GrantPermissionRequest { + // The ID of the user + string user_id = 1; + + // The module name ("*" for all modules) + string module_name = 2; + + // The permission level + Permission permission = 3; +} + +// GrantPermissionResponse is the response for granting a permission +message GrantPermissionResponse { + // The created ACL entry + ACLEntry entry = 1; +} + +// RevokePermissionRequest is the request for revoking a permission +message RevokePermissionRequest { + // The ID of the user + string user_id = 1; + + // The module name + string module_name = 2; +} + +// RevokePermissionResponse is the response for revoking a permission +message RevokePermissionResponse { + // Success indicator + bool success = 1; +} + +// ListUserPermissionsRequest is the request for listing user permissions +message ListUserPermissionsRequest { + // The ID of the user + string user_id = 1; +} + +// ListUserPermissionsResponse is the response for listing user permissions +message ListUserPermissionsResponse { + // The list of permissions + repeated ACLEntry permissions = 1; +}