()
| 72 | } |
| 73 | |
| 74 | func (r *RootCmd) shareWorkspace() *serpent.Command { |
| 75 | var ( |
| 76 | users []string |
| 77 | groups []string |
| 78 | |
| 79 | // Username regex taken from codersdk/name.go |
| 80 | nameRoleRegex = regexp.MustCompile(`(^[a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)*)+(?::([A-Za-z0-9-]+))?`) |
| 81 | ) |
| 82 | |
| 83 | cmd := &serpent.Command{ |
| 84 | Use: "add <workspace> --user <user>:<role> --group <group>:<role>", |
| 85 | Aliases: []string{"share"}, |
| 86 | Short: "Share a workspace with a user or group.", |
| 87 | Options: serpent.OptionSet{ |
| 88 | { |
| 89 | Name: "user", |
| 90 | Description: "A comma separated list of users to share the workspace with.", |
| 91 | Flag: "user", |
| 92 | Value: serpent.StringArrayOf(&users), |
| 93 | }, { |
| 94 | Name: "group", |
| 95 | Description: "A comma separated list of groups to share the workspace with.", |
| 96 | Flag: "group", |
| 97 | Value: serpent.StringArrayOf(&groups), |
| 98 | }, |
| 99 | }, |
| 100 | Middleware: serpent.Chain( |
| 101 | serpent.RequireNArgs(1), |
| 102 | ), |
| 103 | Handler: func(inv *serpent.Invocation) error { |
| 104 | client, err := r.InitClient(inv) |
| 105 | if err != nil { |
| 106 | return err |
| 107 | } |
| 108 | |
| 109 | if len(users) == 0 && len(groups) == 0 { |
| 110 | return xerrors.New("at least one user or group must be provided") |
| 111 | } |
| 112 | |
| 113 | workspace, err := client.ResolveWorkspace(inv.Context(), inv.Args[0]) |
| 114 | if err != nil { |
| 115 | return xerrors.Errorf("could not fetch the workspace %s: %w", inv.Args[0], err) |
| 116 | } |
| 117 | |
| 118 | userRoleStrings := make([][2]string, len(users)) |
| 119 | for index, user := range users { |
| 120 | userAndRole := nameRoleRegex.FindStringSubmatch(user) |
| 121 | if userAndRole == nil { |
| 122 | return xerrors.Errorf("invalid user format %q: must match pattern 'username:role'", user) |
| 123 | } |
| 124 | |
| 125 | userRoleStrings[index] = [2]string{userAndRole[1], userAndRole[2]} |
| 126 | } |
| 127 | |
| 128 | groupRoleStrings := make([][2]string, len(groups)) |
| 129 | for index, group := range groups { |
| 130 | groupAndRole := nameRoleRegex.FindStringSubmatch(group) |
| 131 | if groupAndRole == nil { |
no test coverage detected