Skip to content

Commit 6df3dba

Browse files
geovannewashingtongustavosbarreto
authored andcommitted
refactor(cli): replace bind() with explicit field assignment
Remove the reflection-based bind() helper and replace it with direct struct field assignment in each command handler. This eliminates a hidden coupling between struct field declaration order and CLI argument position, and fixes a latent runtime panic caused by calling SetString() on authorizer.Role, a named string type that reflection does not treat as a plain string. Also validates the role argument early in memberAdd, returning a clear error message instead of silently passing RoleInvalid downstream, and fixes cobra.RangeArgs(2, 4) to cobra.RangeArgs(2, 3) in namespaceCreate since --type is a flag, not a positional argument.
1 parent 672e4d5 commit 6df3dba

3 files changed

Lines changed: 35 additions & 61 deletions

File tree

cli/cmd/cmd.go

Lines changed: 0 additions & 23 deletions
This file was deleted.

cli/cmd/namespace.go

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66

77
"github.com/shellhub-io/shellhub/cli/pkg/inputs"
88
"github.com/shellhub-io/shellhub/cli/services"
9+
"github.com/shellhub-io/shellhub/pkg/api/authorizer"
910
"github.com/shellhub-io/shellhub/pkg/uuid"
1011
"github.com/spf13/cobra"
1112
)
@@ -38,25 +39,23 @@ func namespaceCreate(service services.Services) *cobra.Command {
3839
Long: `Creates a new namespace in the system using the provided namespace name, associated owner's username, and an optional tenant ID and Type.
3940
The owner must be a valid username within the system. If a tenant ID is provided, it should be in UUID format.`,
4041
Example: `cli namespace create dev john_doe --type=team`,
41-
Args: cobra.RangeArgs(2, 4),
42+
Args: cobra.RangeArgs(2, 3),
4243
RunE: func(cmd *cobra.Command, args []string) error {
43-
// Avoid panic when TenantID isn't provided.
44-
45-
if len(args) == 2 {
46-
args = append(args, "")
44+
namespaceType, err := cmd.Flags().GetString("type")
45+
if err != nil {
46+
return err
4747
}
4848

49-
var input inputs.NamespaceCreate
50-
51-
if err := bind(args, &input); err != nil {
52-
return err
49+
input := inputs.NamespaceCreate{
50+
Namespace: args[0],
51+
Owner: args[1],
52+
TenantID: "",
53+
Type: namespaceType,
5354
}
5455

55-
typeNamespace, err := cmd.Flags().GetString("type")
56-
if err != nil {
57-
return err
56+
if len(args) == 3 {
57+
input.TenantID = args[2]
5858
}
59-
input.Type = typeNamespace
6059

6160
namespace, err := service.NamespaceCreate(cmd.Context(), &input)
6261
if err != nil {
@@ -86,10 +85,8 @@ func namespaceDelete(service services.Services) *cobra.Command {
8685
Example: `cli namespace delete dev`,
8786
Args: cobra.ExactArgs(1),
8887
RunE: func(cmd *cobra.Command, args []string) error {
89-
var input inputs.NamespaceDelete
90-
91-
if err := bind(args, &input); err != nil {
92-
return err
88+
input := inputs.NamespaceDelete{
89+
Namespace: args[0],
9390
}
9491

9592
if err := service.NamespaceDelete(cmd.Context(), &input); err != nil {
@@ -328,10 +325,15 @@ and the role indicates the permissions that the member will have within that nam
328325
Example: `cli member add myuser mynamespace observer`,
329326
Args: cobra.ExactArgs(3),
330327
RunE: func(cmd *cobra.Command, args []string) error {
331-
var input inputs.MemberAdd
328+
role := authorizer.RoleFromString(args[2])
329+
if role == authorizer.RoleInvalid {
330+
return fmt.Errorf("invalid role %q, valid roles are: owner, administrator, operator, observer", args[2])
331+
}
332332

333-
if err := bind(args, &input); err != nil {
334-
return err
333+
input := inputs.MemberAdd{
334+
Username: args[0],
335+
Namespace: args[1],
336+
Role: role,
335337
}
336338

337339
namespace, err := service.NamespaceAddMember(cmd.Context(), &input)
@@ -359,10 +361,9 @@ The username identifies the member to be removed, and the namespace specifies wh
359361
Example: `cli member remove john_doe dev`,
360362
Args: cobra.ExactArgs(2),
361363
RunE: func(cmd *cobra.Command, args []string) error {
362-
var input inputs.MemberRemove
363-
364-
if err := bind(args, &input); err != nil {
365-
return err
364+
input := inputs.MemberRemove{
365+
Username: args[0],
366+
Namespace: args[1],
366367
}
367368

368369
namespace, err := service.NamespaceRemoveMember(cmd.Context(), &input)

cli/cmd/user.go

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,13 @@ The username must be unique, and the password must meet the system's security re
4141
Example: `cli user create john_doe Secret123!- john.doe@test.com
4242
cli user create john_doe Secret123!- john.doe@test.com --admin`,
4343
RunE: func(cmd *cobra.Command, args []string) error {
44-
var input inputs.UserCreate
45-
46-
if err := bind(args, &input); err != nil {
47-
return err
44+
input := inputs.UserCreate{
45+
Username: args[0],
46+
Password: args[1],
47+
Email: args[2],
48+
Admin: admin,
4849
}
4950

50-
input.Admin = admin
51-
5251
user, err := service.UserCreate(cmd.Context(), &input)
5352
if err != nil {
5453
return err
@@ -75,10 +74,9 @@ func userResetPassword(service services.Services) *cobra.Command {
7574
Long: `Updates the password for an existing user identified by the given username.`,
7675
Example: `cli user password john_doe Secret123!-`,
7776
RunE: func(cmd *cobra.Command, args []string) error {
78-
var input inputs.UserUpdate
79-
80-
if err := bind(args, &input); err != nil {
81-
return err
77+
input := inputs.UserUpdate{
78+
Username: args[0],
79+
Password: args[1],
8280
}
8381

8482
if err := service.UserUpdate(cmd.Context(), &input); err != nil {
@@ -101,10 +99,8 @@ func userDelete(service services.Services) *cobra.Command {
10199
Long: `Deletes a user and all associated data from the system based on the provided username.`,
102100
Example: `cli user delete john_doe`,
103101
RunE: func(cmd *cobra.Command, args []string) error {
104-
var input inputs.UserDelete
105-
106-
if err := bind(args, &input); err != nil {
107-
return err
102+
input := inputs.UserDelete{
103+
Username: args[0],
108104
}
109105

110106
if err := service.UserDelete(cmd.Context(), &input); err != nil {

0 commit comments

Comments
 (0)