diff --git a/cmd/mstorectl/accountcmd/acccmd.go b/cmd/mstorectl/accountcmd/acccmd.go new file mode 100644 index 0000000..39735ae --- /dev/null +++ b/cmd/mstorectl/accountcmd/acccmd.go @@ -0,0 +1,112 @@ +/* + * Copyright 2026 Oleg Borodin + * + * This work is published and licensed under a Creative Commons + * Attribution-NonCommercial-NoDerivatives 4.0 International License. + * + * Distribution of this work is permitted, but commercial use and + * modifications are strictly prohibited. + */ +package accountcmd + +import ( + "github.com/spf13/cobra" + "github.com/spf13/viper" +) + +const ( + uuidRegex = `^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$` + defaultHostname = "localhost:1025" +) + +type AccountUtil struct { + createAccountParams CreateAccountParams + updateAccountParams UpdateAccountParams + getAccountParams GetAccountParams + deleteAccountParams DeleteAccountParams + listAccountsParams ListAccountsParams + commonAccountParams CommonAccountParams +} + +type CommonAccountParams struct { + Username string + Password string + Hostname string + Timeout uint64 + SkipTLSVerify bool +} + +func (util *AccountUtil) MakeAccountCmds() *cobra.Command { + var subCmd = &cobra.Command{ + Use: "accounts", + Short: "Account operations", + Aliases: []string{"account"}, + } + const defaultTimeout uint64 = 10 + + subCmd.PersistentFlags().StringVarP(&util.commonAccountParams.Username, "user", "U", util.commonAccountParams.Username, "Username") + subCmd.PersistentFlags().StringVarP(&util.commonAccountParams.Password, "pass", "P", util.commonAccountParams.Password, "Password") + subCmd.PersistentFlags().StringVarP(&util.commonAccountParams.Hostname, "host", "X", defaultHostname, "Hostname") + subCmd.PersistentFlags().Uint64VarP(&util.commonAccountParams.Timeout, "timeout", "T", defaultTimeout, "Operation timeout") + subCmd.PersistentFlags().BoolVarP(&util.commonAccountParams.SkipTLSVerify, "skipVerify", "S", true, "Skip server certificate verify") + subCmd.MarkFlagsRequiredTogether("user", "pass") + + vi := viper.New() + vi.SetEnvPrefix("mstore") + vi.BindEnv("user") + vi.BindEnv("pass") + util.commonAccountParams.Username = vi.GetString("user") + util.commonAccountParams.Password = vi.GetString("pass") + + // CreateAccount + var createAccountCmd = &cobra.Command{ + Use: "create [user:pass@]hostname[:port] username password", + Short: "Create user account", + Args: cobra.ExactArgs(3), + Run: util.CreateAccount, + } + subCmd.AddCommand(createAccountCmd) + + // GetAccount + var getAccountCmd = &cobra.Command{ + Use: "get [user:pass@]hostname[:port] accountId|username", + Short: "Get account info", + Args: cobra.ExactArgs(2), + Run: util.GetAccount, + } + subCmd.AddCommand(getAccountCmd) + + // UpdateAccount + var updateAccountCmd = &cobra.Command{ + Use: "update [user:pass@]hostname[:port] username|accounId", + Short: "Update account parameters", + Args: cobra.ExactArgs(2), + Run: util.UpdateAccount, + } + updateAccountCmd.Flags().StringVarP(&util.updateAccountParams.NewUsername, "newname", "u", "", "New username") + updateAccountCmd.Flags().StringVarP(&util.updateAccountParams.NewPassword, "newpass", "p", "", "New password") + updateAccountCmd.MarkFlagsOneRequired("newname", "newpass") + subCmd.AddCommand(updateAccountCmd) + + // DeleteAccount + var deleteAccountCmd = &cobra.Command{ + Use: "delete [user:pass@]hostname[:port] username|accountId", + Short: "Delete account", + Args: cobra.ExactArgs(2), + Run: util.DeleteAccount, + } + subCmd.AddCommand(deleteAccountCmd) + + // ListAccount + var listAccountsCmd = &cobra.Command{ + Use: "list [user:pass@]hostname[:port]", + Short: "list accounts", + Args: cobra.ExactArgs(1), + Run: util.ListAccounts, + } + listAccountsCmd.Flags().BoolVarP(&util.listAccountsParams.Detail, "detail", "d", false, "Show detail information") + listAccountsCmd.Flags().StringVarP(&util.listAccountsParams.Regex, "regex", "r", "", "Output regexp for usernames") + subCmd.AddCommand(listAccountsCmd) + + return subCmd +} diff --git a/cmd/mstorectl/accountcmd/accountcmd.go b/cmd/mstorectl/accountcmd/accountcmd.go deleted file mode 100644 index c71d6e3..0000000 --- a/cmd/mstorectl/accountcmd/accountcmd.go +++ /dev/null @@ -1,362 +0,0 @@ -/* - * Copyright 2026 Oleg Borodin - * - * This work is published and licensed under a Creative Commons - * Attribution-NonCommercial-NoDerivatives 4.0 International License. - * - * Distribution of this work is permitted, but commercial use and - * modifications are strictly prohibited. - */ -package accountcmd - -import ( - "context" - "regexp" - "strings" - "time" - - "github.com/spf13/cobra" - "github.com/spf13/viper" - - "mstore/pkg/client" - "mstore/pkg/descr" - "mstore/pkg/terms" -) - -const ( - uuidRegex = `^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$` - defaultHostname = "localhost:1025" -) - -type AccountUtil struct { - createAccountParams CreateAccountParams - updateAccountParams UpdateAccountParams - getAccountParams GetAccountParams - deleteAccountParams DeleteAccountParams - listAccountsParams ListAccountsParams - commonAccountParams CommonAccountParams -} - -type CommonAccountParams struct { - Username string - Password string - Hostname string - Timeout uint64 - SkipTLSVerify bool -} - -func (util *AccountUtil) CreateAccountCmds() *cobra.Command { - var subCmd = &cobra.Command{ - Use: "accounts", - Short: "Account operations", - Aliases: []string{"account"}, - } - const defaultTimeout uint64 = 10 - - subCmd.PersistentFlags().StringVarP(&util.commonAccountParams.Username, "user", "U", util.commonAccountParams.Username, "Username") - subCmd.PersistentFlags().StringVarP(&util.commonAccountParams.Password, "pass", "P", util.commonAccountParams.Password, "Password") - subCmd.PersistentFlags().StringVarP(&util.commonAccountParams.Hostname, "host", "X", defaultHostname, "Hostname") - subCmd.PersistentFlags().Uint64VarP(&util.commonAccountParams.Timeout, "timeout", "T", defaultTimeout, "Operation timeout") - subCmd.PersistentFlags().BoolVarP(&util.commonAccountParams.SkipTLSVerify, "skipVerify", "S", true, "Skip server certificate verify") - subCmd.MarkFlagsRequiredTogether("user", "pass") - - vi := viper.New() - vi.SetEnvPrefix("mstore") - vi.BindEnv("user") - vi.BindEnv("pass") - util.commonAccountParams.Username = vi.GetString("user") - util.commonAccountParams.Password = vi.GetString("pass") - - // CreateAccount - var createAccountCmd = &cobra.Command{ - Use: "create [user:pass@]hostname[:port] username password", - Short: "Create user account", - Args: cobra.ExactArgs(3), - Run: util.CreateAccount, - } - subCmd.AddCommand(createAccountCmd) - - // GetAccount - var getAccountCmd = &cobra.Command{ - Use: "get [user:pass@]hostname[:port] accountId|username", - Short: "Get account info", - Args: cobra.ExactArgs(2), - Run: util.GetAccount, - } - subCmd.AddCommand(getAccountCmd) - - // UpdateAccount - var updateAccountCmd = &cobra.Command{ - Use: "update [user:pass@]hostname[:port] username|accounId", - Short: "Update account parameters", - Args: cobra.ExactArgs(2), - Run: util.UpdateAccount, - } - updateAccountCmd.Flags().StringVarP(&util.updateAccountParams.NewUsername, "newname", "u", "", "New username") - updateAccountCmd.Flags().StringVarP(&util.updateAccountParams.NewPassword, "newpass", "p", "", "New password") - updateAccountCmd.MarkFlagsOneRequired("newname", "newpass") - subCmd.AddCommand(updateAccountCmd) - - // DeleteAccount - var deleteAccountCmd = &cobra.Command{ - Use: "delete [user:pass@]hostname[:port] username|accountId", - Short: "Delete account", - Args: cobra.ExactArgs(2), - Run: util.DeleteAccount, - } - subCmd.AddCommand(deleteAccountCmd) - - // ListAccount - var listAccountsCmd = &cobra.Command{ - Use: "list [user:pass@]hostname[:port]", - Short: "list accounts", - Args: cobra.ExactArgs(1), - Run: util.ListAccounts, - } - listAccountsCmd.Flags().BoolVarP(&util.listAccountsParams.Detail, "detail", "d", false, "Show detail information") - listAccountsCmd.Flags().StringVarP(&util.listAccountsParams.Regex, "regex", "r", "", "Output regexp for usernames") - subCmd.AddCommand(listAccountsCmd) - - return subCmd -} - -// CreateAccount -type CreateAccountParams struct { - NewUsername string - NewPassword string -} -type CreateAccountResult struct { - AccountID string `yaml:"accountId"` - Grants map[string]string `yaml:"grantsIds,omitempty"` -} - -func (util *AccountUtil) CreateAccount(cmd *cobra.Command, args []string) { - util.commonAccountParams.Hostname = args[0] - util.createAccountParams.NewUsername = args[1] - util.createAccountParams.NewPassword = args[2] - res, err := util.createAccount(&util.commonAccountParams, &util.createAccountParams) - printResponse(res, err) -} - -func (util *AccountUtil) createAccount(common *CommonAccountParams, params *CreateAccountParams) (*CreateAccountResult, error) { - var err error - res := &CreateAccountResult{ - Grants: make(map[string]string, 0), - } - hostname, err := packUserinfo(common.Hostname, common.Username, common.Password) - if err != nil { - return res, err - } - timeout := time.Duration(common.Timeout) * time.Second - ctx, _ := context.WithTimeout(context.Background(), timeout) - accountID, err := client.NewClient(common.SkipTLSVerify).CreateAccount(ctx, hostname, params.NewUsername, params.NewPassword) - if err != nil { - return res, err - } - - fullRights := []string{ - terms.RightWriteAccounts, - terms.RightReadAccounts, - terms.RightWriteFiles, - terms.RightReadFiles, - terms.RightWriteImages, - terms.RightReadImages, - } - for _, right := range fullRights { - id, err := client.NewClient(common.SkipTLSVerify).CreateGrantByAccountID(ctx, hostname, accountID, right, ".*") - if err != nil { - return res, err - } - res.Grants[id] = right - } - res.AccountID = accountID - return res, err -} - -// UpdateAccount -type UpdateAccountParams struct { - Timeout uint64 - AccountID string - NewUsername string - NewPassword string -} -type UpdateAccountResult struct { - File *descr.File `yaml:"file,omitempty"` -} - -func (util *AccountUtil) UpdateAccount(cmd *cobra.Command, args []string) { - util.commonAccountParams.Hostname = args[0] - util.updateAccountParams.AccountID = args[1] - res, err := util.updateAccount(&util.commonAccountParams, &util.updateAccountParams) - printResponse(res, err) -} - -func (util *AccountUtil) updateAccount(common *CommonAccountParams, params *UpdateAccountParams) (*UpdateAccountResult, error) { - var err error - res := &UpdateAccountResult{} - hostname, err := packUserinfo(common.Hostname, common.Username, common.Password) - if err != nil { - return res, err - } - timeout := time.Duration(common.Timeout) * time.Second - ctx, _ := context.WithTimeout(context.Background(), timeout) - re := regexp.MustCompile(uuidRegex) - id := strings.ToLower(params.AccountID) - if re.MatchString(id) { - err = client.NewClient(common.SkipTLSVerify).UpdateAccountByID(ctx, hostname, id, params.NewUsername, params.NewPassword) - } else { - err = client.NewClient(common.SkipTLSVerify).UpdateAccountByName(ctx, hostname, params.AccountID, params.NewUsername, params.NewPassword) - } - if err != nil { - return res, err - } - return res, err -} - -// Get file -type GetAccountParams struct { - Timeout uint64 - AccountID string -} - -func (util *AccountUtil) GetAccount(cmd *cobra.Command, args []string) { - util.commonAccountParams.Hostname = args[0] - util.getAccountParams.AccountID = args[1] - res, err := util.getAccount(&util.commonAccountParams, &util.getAccountParams) - printResponse(res, err) -} - -type GetAccountResult struct { - Account *descr.AccountShort `yaml:"account,omitempty"` -} - -func (util *AccountUtil) getAccount(common *CommonAccountParams, params *GetAccountParams) (*GetAccountResult, error) { - var err error - res := &GetAccountResult{} - hostname, err := packUserinfo(common.Hostname, common.Username, common.Password) - if err != nil { - return res, err - } - timeout := time.Duration(common.Timeout) * time.Second - ctx, _ := context.WithTimeout(context.Background(), timeout) - opRes := &descr.AccountShort{} - - re := regexp.MustCompile(uuidRegex) - id := strings.ToLower(params.AccountID) - if re.MatchString(id) { - opRes, err = client.NewClient(common.SkipTLSVerify).GetAccountByID(ctx, hostname, id) - } else { - opRes, err = client.NewClient(common.SkipTLSVerify).GetAccountByName(ctx, hostname, params.AccountID) - } - if err != nil { - return res, err - } - res.Account = opRes - return res, err -} - -// DeleteAccount -type DeleteAccountParams struct { - AccountID string - Timeout uint64 -} - -type DeleteAccountResult struct{} - -func (util *AccountUtil) DeleteAccount(cmd *cobra.Command, args []string) { - util.commonAccountParams.Hostname = args[0] - util.deleteAccountParams.AccountID = args[1] - res, err := util.deleteAccount(&util.commonAccountParams, &util.deleteAccountParams) - printResponse(res, err) -} -func (util *AccountUtil) deleteAccount(common *CommonAccountParams, params *DeleteAccountParams) (*DeleteAccountResult, error) { - var err error - res := &DeleteAccountResult{} - hostname, err := packUserinfo(common.Hostname, common.Username, common.Password) - if err != nil { - return res, err - } - timeout := time.Duration(common.Timeout) * time.Second - ctx, _ := context.WithTimeout(context.Background(), timeout) - re := regexp.MustCompile(uuidRegex) - id := strings.ToLower(params.AccountID) - if re.MatchString(id) { - err = client.NewClient(common.SkipTLSVerify).DeleteAccountByID(ctx, hostname, id) - } else { - err = client.NewClient(common.SkipTLSVerify).DeleteAccountByName(ctx, hostname, params.AccountID) - } - if err != nil { - return res, err - } - return res, err -} - -// ListAccounts -type ListAccountsParams struct { - Timeout uint64 - Detail bool - Regex string -} - -type Userinfo struct { - Username string `yaml:"username,omitempty"` - AccountID string `yaml:"accountId,omitempty"` - Rights map[string]string `yaml:"rights,omitempty"` -} - -type ListAccountsResult struct { - Accounts []descr.AccountShort `yaml:"accounts,omitempty"` - Users []Userinfo `yaml:"users,omitempty"` -} - -func (util *AccountUtil) ListAccounts(cmd *cobra.Command, args []string) { - util.commonAccountParams.Hostname = args[0] - res, err := util.listAccounts(&util.commonAccountParams, &util.listAccountsParams) - printResponse(res, err) -} -func (util *AccountUtil) listAccounts(common *CommonAccountParams, params *ListAccountsParams) (*ListAccountsResult, error) { - var err error - res := &ListAccountsResult{} - hostname, err := packUserinfo(common.Hostname, common.Username, common.Password) - if err != nil { - return res, err - } - outRe, err := regexp.Compile(params.Regex) - if err != nil { - return res, err - } - - timeout := time.Duration(common.Timeout) * time.Second - ctx, _ := context.WithTimeout(context.Background(), timeout) - accounts, err := client.NewClient(common.SkipTLSVerify).ListAccounts(ctx, hostname) - if err != nil { - return res, err - } - outAccounts := make([]descr.AccountShort, 0) - if params.Regex != "" { - for _, item := range accounts { - if outRe.MatchString(item.Username) { - outAccounts = append(outAccounts, item) - } - } - } else { - outAccounts = accounts - } - if params.Detail { - res.Accounts = outAccounts - } else { - res.Users = make([]Userinfo, 0) - for _, account := range outAccounts { - userinfo := Userinfo{ - Username: account.Username, - AccountID: account.ID, - Rights: make(map[string]string, 0), - } - for _, grant := range account.Grants { - userinfo.Rights[grant.ID] = grant.Right - } - res.Users = append(res.Users, userinfo) - } - } - return res, err -} diff --git a/cmd/mstorectl/accountcmd/createacc.go b/cmd/mstorectl/accountcmd/createacc.go new file mode 100644 index 0000000..f87df74 --- /dev/null +++ b/cmd/mstorectl/accountcmd/createacc.go @@ -0,0 +1,78 @@ +/* + * Copyright 2026 Oleg Borodin + * + * This work is published and licensed under a Creative Commons + * Attribution-NonCommercial-NoDerivatives 4.0 International License. + * + * Distribution of this work is permitted, but commercial use and + * modifications are strictly prohibited. + */ +package accountcmd + +import ( + "context" + "time" + + "github.com/spf13/cobra" + + "mstore/pkg/accntcli" + "mstore/pkg/terms" +) + +// CreateAccount +type CreateAccountParams struct { + NewUsername string + NewPassword string +} +type CreateAccountResult struct { + AccountID string `yaml:"accountId"` + Grants map[string]string `yaml:"grantsIds,omitempty"` +} + +func (util *AccountUtil) CreateAccount(cmd *cobra.Command, args []string) { + util.commonAccountParams.Hostname = args[0] + util.createAccountParams.NewUsername = args[1] + util.createAccountParams.NewPassword = args[2] + res, err := util.createAccount(&util.commonAccountParams, &util.createAccountParams) + printResponse(res, err) +} + +func (util *AccountUtil) createAccount(common *CommonAccountParams, params *CreateAccountParams) (*CreateAccountResult, error) { + var err error + res := &CreateAccountResult{ + Grants: make(map[string]string, 0), + } + + timeout := time.Duration(common.Timeout) * time.Second + ctx, _ := context.WithTimeout(context.Background(), timeout) + ref, err := accntcli.ParseHostinfo(common.Hostname) + if err != nil { + return res, err + } + ref.SetUserinfo(common.Username, common.Password) + mw := accntcli.NewBasicAuthMiddleware(ref.Userinfo()) + cli := accntcli.NewClient(nil, mw) + + accountID, err := cli.CreateAccount(ctx, ref.Host(), params.NewUsername, params.NewPassword) + if err != nil { + return res, err + } + + fullRights := []string{ + terms.RightWriteAccounts, + terms.RightReadAccounts, + terms.RightWriteFiles, + terms.RightReadFiles, + terms.RightWriteImages, + terms.RightReadImages, + } + for _, right := range fullRights { + id, err := cli.CreateGrantByAccountID(ctx, ref.Host(), accountID, right, ".*") + if err != nil { + return res, err + } + res.Grants[id] = right + } + res.AccountID = accountID + return res, err +} diff --git a/cmd/mstorectl/accountcmd/creategrant.go b/cmd/mstorectl/accountcmd/creategrant.go new file mode 100644 index 0000000..4d0b516 --- /dev/null +++ b/cmd/mstorectl/accountcmd/creategrant.go @@ -0,0 +1,69 @@ +/* + * Copyright 2026 Oleg Borodin + * + * This work is published and licensed under a Creative Commons + * Attribution-NonCommercial-NoDerivatives 4.0 International License. + * + * Distribution of this work is permitted, but commercial use and + * modifications are strictly prohibited. + */ +package accountcmd + +import ( + "context" + "regexp" + "strings" + "time" + + "github.com/spf13/cobra" + + "mstore/pkg/accntcli" +) + +// CreateGrant +type CreateGrantParams struct { + AccountID string + Right string + Pattern string +} +type CreateGrantResult struct { + GrantID string `yaml:"grantId"` +} + +func (util *GrantUtil) CreateGrant(cmd *cobra.Command, args []string) { + util.commonGrantParams.Hostname = args[0] + util.createGrantParams.AccountID = args[1] + util.createGrantParams.Right = args[2] + util.createGrantParams.Pattern = args[3] + res, err := util.createGrant(&util.commonGrantParams, &util.createGrantParams) + printResponse(res, err) +} + +func (util *GrantUtil) createGrant(common *CommonGrantParams, params *CreateGrantParams) (*CreateGrantResult, error) { + var err error + res := &CreateGrantResult{} + + timeout := time.Duration(common.Timeout) * time.Second + ctx, _ := context.WithTimeout(context.Background(), timeout) + ref, err := accntcli.ParseHostinfo(common.Hostname) + if err != nil { + return res, err + } + ref.SetUserinfo(common.Username, common.Password) + mw := accntcli.NewBasicAuthMiddleware(ref.Userinfo()) + cli := accntcli.NewClient(nil, mw) + + re := regexp.MustCompile(uuidRegex) + id := strings.ToLower(params.AccountID) + var opres string + if re.MatchString(id) { + opres, err = cli.CreateGrantByAccountID(ctx, ref.Host(), id, params.Right, params.Pattern) + } else { + opres, err = cli.CreateGrantByUsername(ctx, ref.Host(), params.AccountID, params.Right, params.Pattern) + } + if err != nil { + return res, err + } + res.GrantID = opres + return res, err +} diff --git a/cmd/mstorectl/accountcmd/delacc.go b/cmd/mstorectl/accountcmd/delacc.go new file mode 100644 index 0000000..029bccc --- /dev/null +++ b/cmd/mstorectl/accountcmd/delacc.go @@ -0,0 +1,62 @@ +/* + * Copyright 2026 Oleg Borodin + * + * This work is published and licensed under a Creative Commons + * Attribution-NonCommercial-NoDerivatives 4.0 International License. + * + * Distribution of this work is permitted, but commercial use and + * modifications are strictly prohibited. + */ +package accountcmd + +import ( + "context" + "regexp" + "strings" + "time" + + "github.com/spf13/cobra" + + "mstore/pkg/accntcli" +) + +// DeleteAccount +type DeleteAccountParams struct { + AccountID string + Timeout uint64 +} + +type DeleteAccountResult struct{} + +func (util *AccountUtil) DeleteAccount(cmd *cobra.Command, args []string) { + util.commonAccountParams.Hostname = args[0] + util.deleteAccountParams.AccountID = args[1] + res, err := util.deleteAccount(&util.commonAccountParams, &util.deleteAccountParams) + printResponse(res, err) +} +func (util *AccountUtil) deleteAccount(common *CommonAccountParams, params *DeleteAccountParams) (*DeleteAccountResult, error) { + var err error + res := &DeleteAccountResult{} + + timeout := time.Duration(common.Timeout) * time.Second + ctx, _ := context.WithTimeout(context.Background(), timeout) + ref, err := accntcli.ParseHostinfo(common.Hostname) + if err != nil { + return res, err + } + ref.SetUserinfo(common.Username, common.Password) + mw := accntcli.NewBasicAuthMiddleware(ref.Userinfo()) + cli := accntcli.NewClient(nil, mw) + + re := regexp.MustCompile(uuidRegex) + id := strings.ToLower(params.AccountID) + if re.MatchString(id) { + err = cli.DeleteAccountByID(ctx, ref.Host(), id) + } else { + err = cli.DeleteAccountByName(ctx, ref.Host(), params.AccountID) + } + if err != nil { + return res, err + } + return res, err +} diff --git a/cmd/mstorectl/accountcmd/delgrant.go b/cmd/mstorectl/accountcmd/delgrant.go new file mode 100644 index 0000000..cc46210 --- /dev/null +++ b/cmd/mstorectl/accountcmd/delgrant.go @@ -0,0 +1,55 @@ +/* + * Copyright 2026 Oleg Borodin + * + * This work is published and licensed under a Creative Commons + * Attribution-NonCommercial-NoDerivatives 4.0 International License. + * + * Distribution of this work is permitted, but commercial use and + * modifications are strictly prohibited. + */ +package accountcmd + +import ( + "context" + "strings" + "time" + + "github.com/spf13/cobra" + + "mstore/pkg/accntcli" +) + +// DeleteGrant +type DeleteGrantParams struct { + GrantID string +} + +type DeleteGrantResult struct{} + +func (util *GrantUtil) DeleteGrant(cmd *cobra.Command, args []string) { + util.commonGrantParams.Hostname = args[0] + util.deleteGrantParams.GrantID = args[1] + res, err := util.deleteGrant(&util.commonGrantParams, &util.deleteGrantParams) + printResponse(res, err) +} +func (util *GrantUtil) deleteGrant(common *CommonGrantParams, params *DeleteGrantParams) (*DeleteGrantResult, error) { + var err error + res := &DeleteGrantResult{} + + timeout := time.Duration(common.Timeout) * time.Second + ctx, _ := context.WithTimeout(context.Background(), timeout) + ref, err := accntcli.ParseHostinfo(common.Hostname) + if err != nil { + return res, err + } + ref.SetUserinfo(common.Username, common.Password) + mw := accntcli.NewBasicAuthMiddleware(ref.Userinfo()) + cli := accntcli.NewClient(nil, mw) + + id := strings.ToLower(params.GrantID) + err = cli.DeleteGrant(ctx, ref.Host(), id) + if err != nil { + return res, err + } + return res, err +} diff --git a/cmd/mstorectl/accountcmd/getacc.go b/cmd/mstorectl/accountcmd/getacc.go new file mode 100644 index 0000000..1bf549a --- /dev/null +++ b/cmd/mstorectl/accountcmd/getacc.go @@ -0,0 +1,67 @@ +/* + * Copyright 2026 Oleg Borodin + * + * This work is published and licensed under a Creative Commons + * Attribution-NonCommercial-NoDerivatives 4.0 International License. + * + * Distribution of this work is permitted, but commercial use and + * modifications are strictly prohibited. + */ +package accountcmd + +import ( + "context" + "regexp" + "strings" + "time" + + "github.com/spf13/cobra" + + "mstore/pkg/accntcli" + "mstore/pkg/descr" +) + +// GetAccount +type GetAccountParams struct { + Timeout uint64 + AccountID string +} + +func (util *AccountUtil) GetAccount(cmd *cobra.Command, args []string) { + util.commonAccountParams.Hostname = args[0] + util.getAccountParams.AccountID = args[1] + res, err := util.getAccount(&util.commonAccountParams, &util.getAccountParams) + printResponse(res, err) +} + +type GetAccountResult struct { + Account *descr.AccountShort `yaml:"account,omitempty"` +} + +func (util *AccountUtil) getAccount(common *CommonAccountParams, params *GetAccountParams) (*GetAccountResult, error) { + var err error + res := &GetAccountResult{} + opres := &descr.AccountShort{} + re := regexp.MustCompile(uuidRegex) + id := strings.ToLower(params.AccountID) + + timeout := time.Duration(common.Timeout) * time.Second + ctx, _ := context.WithTimeout(context.Background(), timeout) + ref, err := accntcli.ParseHostinfo(common.Hostname) + if err != nil { + return res, err + } + ref.SetUserinfo(common.Username, common.Password) + mw := accntcli.NewBasicAuthMiddleware(ref.Userinfo()) + cli := accntcli.NewClient(nil, mw) + if re.MatchString(id) { + opres, err = cli.GetAccountByID(ctx, ref.Host(), id) + } else { + opres, err = cli.GetAccountByName(ctx, ref.Host(), params.AccountID) + } + if err != nil { + return res, err + } + res.Account = opres + return res, err +} diff --git a/cmd/mstorectl/accountcmd/getgrant.go b/cmd/mstorectl/accountcmd/getgrant.go new file mode 100644 index 0000000..21c6f41 --- /dev/null +++ b/cmd/mstorectl/accountcmd/getgrant.go @@ -0,0 +1,62 @@ +/* + * Copyright 2026 Oleg Borodin + * + * This work is published and licensed under a Creative Commons + * Attribution-NonCommercial-NoDerivatives 4.0 International License. + * + * Distribution of this work is permitted, but commercial use and + * modifications are strictly prohibited. + */ +package accountcmd + +import ( + "context" + "strings" + "time" + + "github.com/spf13/cobra" + + "mstore/pkg/accntcli" + "mstore/pkg/descr" +) + +// GetGrant +type GetGrantParams struct { + GrantID string +} + +type GetGrantResult struct { + Grant *descr.Grant `yaml:"grant,omitempty"` +} + +func (util *GrantUtil) GetGrant(cmd *cobra.Command, args []string) { + util.commonGrantParams.Hostname = args[0] + util.getGrantParams.GrantID = args[1] + + res, err := util.getGrant(&util.commonGrantParams, &util.getGrantParams) + printResponse(res, err) +} + +func (util *GrantUtil) getGrant(common *CommonGrantParams, params *GetGrantParams) (*GetGrantResult, error) { + var err error + res := &GetGrantResult{} + opres := &descr.Grant{} + + timeout := time.Duration(common.Timeout) * time.Second + ctx, _ := context.WithTimeout(context.Background(), timeout) + ref, err := accntcli.ParseHostinfo(common.Hostname) + if err != nil { + return res, err + } + ref.SetUserinfo(common.Username, common.Password) + mw := accntcli.NewBasicAuthMiddleware(ref.Userinfo()) + cli := accntcli.NewClient(nil, mw) + + id := strings.ToLower(params.GrantID) + opres, err = cli.GetGrant(ctx, ref.Host(), id) + if err != nil { + return res, err + } + res.Grant = opres + return res, err +} diff --git a/cmd/mstorectl/accountcmd/grantcmd.go b/cmd/mstorectl/accountcmd/grantcmd.go index 4dc74ba..e6b6fd3 100644 --- a/cmd/mstorectl/accountcmd/grantcmd.go +++ b/cmd/mstorectl/accountcmd/grantcmd.go @@ -10,19 +10,11 @@ package accountcmd import ( - "context" - "regexp" - "strings" - "time" - "github.com/spf13/cobra" "github.com/spf13/viper" - - "mstore/pkg/client" - "mstore/pkg/descr" ) -func (util *GrantUtil) CreateGrantCmds() *cobra.Command { +func (util *GrantUtil) MakeGrantCmds() *cobra.Command { var subCmd = &cobra.Command{ Use: "grants", Short: "Grant operations", @@ -110,6 +102,7 @@ type CommonGrantParams struct { SkipTLSVerify bool } +/* // CreateGrant type CreateGrantParams struct { AccountID string @@ -132,24 +125,30 @@ func (util *GrantUtil) CreateGrant(cmd *cobra.Command, args []string) { func (util *GrantUtil) createGrant(common *CommonGrantParams, params *CreateGrantParams) (*CreateGrantResult, error) { var err error res := &CreateGrantResult{} - hostname, err := packUserinfo(common.Hostname, common.Username, common.Password) - if err != nil { - return res, err - } + timeout := time.Duration(common.Timeout) * time.Second ctx, _ := context.WithTimeout(context.Background(), timeout) - re := regexp.MustCompile(uuidRegex) + ref, err := accntcli.ParseHostinfo(common.Hostname) + if err != nil { + return res, err + } + ref.SetUserinfo(common.Username, common.Password) + mw := accntcli.NewBasicAuthMiddleware(ref.Userinfo()) + cli := accntcli.NewClient(nil, mw) + + + re := regexp.MustCompile(uuidRegex) id := strings.ToLower(params.AccountID) - var operRes string + var opres string if re.MatchString(id) { - operRes, err = client.NewClient(common.SkipTLSVerify).CreateGrantByAccountID(ctx, hostname, id, params.Right, params.Pattern) + opres, err = cli.CreateGrantByAccountID(ctx, ref.Host(), id, params.Right, params.Pattern) } else { - operRes, err = client.NewClient(common.SkipTLSVerify).CreateGrantByUsername(ctx, hostname, params.AccountID, params.Right, params.Pattern) + opres, err = cli.CreateGrantByUsername(ctx, ref.Host(), params.AccountID, params.Right, params.Pattern) } if err != nil { return res, err } - res.GrantID = operRes + res.GrantID = opres return res, err } @@ -171,14 +170,20 @@ func (util *GrantUtil) UpdateGrant(cmd *cobra.Command, args []string) { func (util *GrantUtil) updateGrant(common *CommonGrantParams, params *UpdateGrantParams) (*UpdateGrantResult, error) { var err error res := &UpdateGrantResult{} - hostname, err := packUserinfo(common.Hostname, common.Username, common.Password) + + timeout := time.Duration(common.Timeout) * time.Second + ctx, _ := context.WithTimeout(context.Background(), timeout) + ref, err := accntcli.ParseHostinfo(common.Hostname) if err != nil { return res, err } - timeout := time.Duration(common.Timeout) * time.Second - ctx, _ := context.WithTimeout(context.Background(), timeout) + ref.SetUserinfo(common.Username, common.Password) + mw := accntcli.NewBasicAuthMiddleware(ref.Userinfo()) + cli := accntcli.NewClient(nil, mw) + + id := strings.ToLower(params.GrantID) - err = client.NewClient(common.SkipTLSVerify).UpdateGrant(ctx, hostname, id, params.Pattern) + err = cli.UpdateGrant(ctx, ref.Host(), id, params.Pattern) if err != nil { return res, err } @@ -205,20 +210,24 @@ func (util *GrantUtil) GetGrant(cmd *cobra.Command, args []string) { func (util *GrantUtil) getGrant(common *CommonGrantParams, params *GetGrantParams) (*GetGrantResult, error) { var err error res := &GetGrantResult{} - hostname, err := packUserinfo(common.Hostname, common.Username, common.Password) - if err != nil { - return res, err - } + opres := &descr.Grant{} + timeout := time.Duration(common.Timeout) * time.Second ctx, _ := context.WithTimeout(context.Background(), timeout) - opRes := &descr.Grant{} - - id := strings.ToLower(params.GrantID) - opRes, err = client.NewClient(common.SkipTLSVerify).GetGrant(ctx, hostname, id) + ref, err := accntcli.ParseHostinfo(common.Hostname) if err != nil { return res, err } - res.Grant = opRes + ref.SetUserinfo(common.Username, common.Password) + mw := accntcli.NewBasicAuthMiddleware(ref.Userinfo()) + cli := accntcli.NewClient(nil, mw) + + id := strings.ToLower(params.GrantID) + opres, err = cli.GetGrant(ctx, ref.Host(), id) + if err != nil { + return res, err + } + res.Grant = opres return res, err } @@ -238,14 +247,19 @@ func (util *GrantUtil) DeleteGrant(cmd *cobra.Command, args []string) { func (util *GrantUtil) deleteGrant(common *CommonGrantParams, params *DeleteGrantParams) (*DeleteGrantResult, error) { var err error res := &DeleteGrantResult{} - hostname, err := packUserinfo(common.Hostname, common.Username, common.Password) + + timeout := time.Duration(common.Timeout) * time.Second + ctx, _ := context.WithTimeout(context.Background(), timeout) + ref, err := accntcli.ParseHostinfo(common.Hostname) if err != nil { return res, err } - timeout := time.Duration(common.Timeout) * time.Second - ctx, _ := context.WithTimeout(context.Background(), timeout) + ref.SetUserinfo(common.Username, common.Password) + mw := accntcli.NewBasicAuthMiddleware(ref.Userinfo()) + cli := accntcli.NewClient(nil, mw) + id := strings.ToLower(params.GrantID) - err = client.NewClient(common.SkipTLSVerify).DeleteGrant(ctx, hostname, id) + err = cli.DeleteGrant(ctx, ref.Host(), id) if err != nil { return res, err } @@ -272,19 +286,24 @@ func (util *GrantUtil) ListGrants(cmd *cobra.Command, args []string) { func (util *GrantUtil) listGrants(common *CommonGrantParams, params *ListGrantsParams) (*ListGrantsResult, error) { var err error res := &ListGrantsResult{} - hostname, err := packUserinfo(common.Hostname, common.Username, common.Password) + + timeout := time.Duration(common.Timeout) * time.Second + ctx, _ := context.WithTimeout(context.Background(), timeout) + ref, err := accntcli.ParseHostinfo(common.Hostname) if err != nil { return res, err } - timeout := time.Duration(common.Timeout) * time.Second - ctx, _ := context.WithTimeout(context.Background(), timeout) + ref.SetUserinfo(common.Username, common.Password) + mw := accntcli.NewBasicAuthMiddleware(ref.Userinfo()) + cli := accntcli.NewClient(nil, mw) + grants := make([]descr.Grant, 0) re := regexp.MustCompile(uuidRegex) id := strings.ToLower(params.AccountID) if re.MatchString(id) { - grants, err = client.NewClient(common.SkipTLSVerify).ListGrantsByAccountID(ctx, hostname, id) + grants, err = cli.ListGrantsByAccountID(ctx, ref.Host(), id) } else { - grants, err = client.NewClient(common.SkipTLSVerify).ListGrantsByUsername(ctx, hostname, params.AccountID) + grants, err = cli.ListGrantsByUsername(ctx, ref.Host(), params.AccountID) } if err != nil { return res, err @@ -299,3 +318,4 @@ func (util *GrantUtil) listGrants(common *CommonGrantParams, params *ListGrantsP } return res, err } +*/ diff --git a/cmd/mstorectl/accountcmd/listacc.go b/cmd/mstorectl/accountcmd/listacc.go new file mode 100644 index 0000000..a47e036 --- /dev/null +++ b/cmd/mstorectl/accountcmd/listacc.go @@ -0,0 +1,96 @@ +/* + * Copyright 2026 Oleg Borodin + * + * This work is published and licensed under a Creative Commons + * Attribution-NonCommercial-NoDerivatives 4.0 International License. + * + * Distribution of this work is permitted, but commercial use and + * modifications are strictly prohibited. + */ +package accountcmd + +import ( + "context" + "regexp" + "time" + + "github.com/spf13/cobra" + + "mstore/pkg/accntcli" + "mstore/pkg/descr" +) + +// ListAccounts +type ListAccountsParams struct { + Timeout uint64 + Detail bool + Regex string +} + +type Userinfo struct { + Username string `yaml:"username,omitempty"` + AccountID string `yaml:"accountId,omitempty"` + Rights map[string]string `yaml:"rights,omitempty"` +} + +type ListAccountsResult struct { + Accounts []descr.AccountShort `yaml:"accounts,omitempty"` + Users []Userinfo `yaml:"users,omitempty"` +} + +func (util *AccountUtil) ListAccounts(cmd *cobra.Command, args []string) { + util.commonAccountParams.Hostname = args[0] + res, err := util.listAccounts(&util.commonAccountParams, &util.listAccountsParams) + printResponse(res, err) +} +func (util *AccountUtil) listAccounts(common *CommonAccountParams, params *ListAccountsParams) (*ListAccountsResult, error) { + var err error + res := &ListAccountsResult{} + + outregex, err := regexp.Compile(params.Regex) + if err != nil { + return res, err + } + + timeout := time.Duration(common.Timeout) * time.Second + ctx, _ := context.WithTimeout(context.Background(), timeout) + ref, err := accntcli.ParseHostinfo(common.Hostname) + if err != nil { + return res, err + } + ref.SetUserinfo(common.Username, common.Password) + mw := accntcli.NewBasicAuthMiddleware(ref.Userinfo()) + cli := accntcli.NewClient(nil, mw) + + accounts, err := cli.ListAccounts(ctx, ref.Host()) + if err != nil { + return res, err + } + outAccounts := make([]descr.AccountShort, 0) + if params.Regex != "" { + for _, item := range accounts { + if outregex.MatchString(item.Username) { + outAccounts = append(outAccounts, item) + } + } + } else { + outAccounts = accounts + } + if params.Detail { + res.Accounts = outAccounts + } else { + res.Users = make([]Userinfo, 0) + for _, account := range outAccounts { + userinfo := Userinfo{ + Username: account.Username, + AccountID: account.ID, + Rights: make(map[string]string, 0), + } + for _, grant := range account.Grants { + userinfo.Rights[grant.ID] = grant.Right + } + res.Users = append(res.Users, userinfo) + } + } + return res, err +} diff --git a/cmd/mstorectl/accountcmd/listgrant.go b/cmd/mstorectl/accountcmd/listgrant.go new file mode 100644 index 0000000..923925d --- /dev/null +++ b/cmd/mstorectl/accountcmd/listgrant.go @@ -0,0 +1,75 @@ +/* + * Copyright 2026 Oleg Borodin + * + * This work is published and licensed under a Creative Commons + * Attribution-NonCommercial-NoDerivatives 4.0 International License. + * + * Distribution of this work is permitted, but commercial use and + * modifications are strictly prohibited. + */ +package accountcmd + +import ( + "context" + "regexp" + "strings" + "time" + + "github.com/spf13/cobra" + + "mstore/pkg/accntcli" + "mstore/pkg/descr" +) + +// ListGrants +type ListGrantsParams struct { + Detail bool + AccountID string +} + +type ListGrantsResult struct { + Grants []descr.Grant `yaml:"grants,omitempty"` + Rights map[string]string `yaml:"rights,omitempty"` +} + +func (util *GrantUtil) ListGrants(cmd *cobra.Command, args []string) { + util.commonGrantParams.Hostname = args[0] + util.listGrantsParams.AccountID = args[1] + res, err := util.listGrants(&util.commonGrantParams, &util.listGrantsParams) + printResponse(res, err) +} +func (util *GrantUtil) listGrants(common *CommonGrantParams, params *ListGrantsParams) (*ListGrantsResult, error) { + var err error + res := &ListGrantsResult{} + + timeout := time.Duration(common.Timeout) * time.Second + ctx, _ := context.WithTimeout(context.Background(), timeout) + ref, err := accntcli.ParseHostinfo(common.Hostname) + if err != nil { + return res, err + } + ref.SetUserinfo(common.Username, common.Password) + mw := accntcli.NewBasicAuthMiddleware(ref.Userinfo()) + cli := accntcli.NewClient(nil, mw) + + grants := make([]descr.Grant, 0) + re := regexp.MustCompile(uuidRegex) + id := strings.ToLower(params.AccountID) + if re.MatchString(id) { + grants, err = cli.ListGrantsByAccountID(ctx, ref.Host(), id) + } else { + grants, err = cli.ListGrantsByUsername(ctx, ref.Host(), params.AccountID) + } + if err != nil { + return res, err + } + if params.Detail { + res.Grants = grants + } else { + res.Rights = make(map[string]string, 0) + for _, item := range grants { + res.Rights[item.ID] = item.Right + } + } + return res, err +} diff --git a/cmd/mstorectl/accountcmd/updacc.go b/cmd/mstorectl/accountcmd/updacc.go new file mode 100644 index 0000000..0aa47cf --- /dev/null +++ b/cmd/mstorectl/accountcmd/updacc.go @@ -0,0 +1,67 @@ +/* + * Copyright 2026 Oleg Borodin + * + * This work is published and licensed under a Creative Commons + * Attribution-NonCommercial-NoDerivatives 4.0 International License. + * + * Distribution of this work is permitted, but commercial use and + * modifications are strictly prohibited. + */ +package accountcmd + +import ( + "context" + "regexp" + "strings" + "time" + + "github.com/spf13/cobra" + + "mstore/pkg/accntcli" + "mstore/pkg/descr" +) + +// UpdateAccount +type UpdateAccountParams struct { + Timeout uint64 + AccountID string + NewUsername string + NewPassword string +} +type UpdateAccountResult struct { + File *descr.File `yaml:"file,omitempty"` +} + +func (util *AccountUtil) UpdateAccount(cmd *cobra.Command, args []string) { + util.commonAccountParams.Hostname = args[0] + util.updateAccountParams.AccountID = args[1] + res, err := util.updateAccount(&util.commonAccountParams, &util.updateAccountParams) + printResponse(res, err) +} + +func (util *AccountUtil) updateAccount(common *CommonAccountParams, params *UpdateAccountParams) (*UpdateAccountResult, error) { + var err error + res := &UpdateAccountResult{} + + timeout := time.Duration(common.Timeout) * time.Second + ctx, _ := context.WithTimeout(context.Background(), timeout) + ref, err := accntcli.ParseHostinfo(common.Hostname) + if err != nil { + return res, err + } + ref.SetUserinfo(common.Username, common.Password) + mw := accntcli.NewBasicAuthMiddleware(ref.Userinfo()) + cli := accntcli.NewClient(nil, mw) + + re := regexp.MustCompile(uuidRegex) + id := strings.ToLower(params.AccountID) + if re.MatchString(id) { + err = cli.UpdateAccountByID(ctx, ref.Host(), id, params.NewUsername, params.NewPassword) + } else { + err = cli.UpdateAccountByName(ctx, ref.Host(), params.AccountID, params.NewUsername, params.NewPassword) + } + if err != nil { + return res, err + } + return res, err +} diff --git a/cmd/mstorectl/accountcmd/updgrant.go b/cmd/mstorectl/accountcmd/updgrant.go new file mode 100644 index 0000000..7f8d7e1 --- /dev/null +++ b/cmd/mstorectl/accountcmd/updgrant.go @@ -0,0 +1,57 @@ +/* + * Copyright 2026 Oleg Borodin + * + * This work is published and licensed under a Creative Commons + * Attribution-NonCommercial-NoDerivatives 4.0 International License. + * + * Distribution of this work is permitted, but commercial use and + * modifications are strictly prohibited. + */ +package accountcmd + +import ( + "context" + "strings" + "time" + + "github.com/spf13/cobra" + + "mstore/pkg/accntcli" +) + +// UpdateGrant +type UpdateGrantParams struct { + GrantID string + Pattern string +} +type UpdateGrantResult struct{} + +func (util *GrantUtil) UpdateGrant(cmd *cobra.Command, args []string) { + util.commonGrantParams.Hostname = args[0] + util.updateGrantParams.GrantID = args[1] + util.updateGrantParams.Pattern = args[2] + res, err := util.updateGrant(&util.commonGrantParams, &util.updateGrantParams) + printResponse(res, err) +} + +func (util *GrantUtil) updateGrant(common *CommonGrantParams, params *UpdateGrantParams) (*UpdateGrantResult, error) { + var err error + res := &UpdateGrantResult{} + + timeout := time.Duration(common.Timeout) * time.Second + ctx, _ := context.WithTimeout(context.Background(), timeout) + ref, err := accntcli.ParseHostinfo(common.Hostname) + if err != nil { + return res, err + } + ref.SetUserinfo(common.Username, common.Password) + mw := accntcli.NewBasicAuthMiddleware(ref.Userinfo()) + cli := accntcli.NewClient(nil, mw) + + id := strings.ToLower(params.GrantID) + err = cli.UpdateGrant(ctx, ref.Host(), id, params.Pattern) + if err != nil { + return res, err + } + return res, err +} diff --git a/cmd/mstorectl/util.go b/cmd/mstorectl/util.go index f44e48e..8d0631a 100644 --- a/cmd/mstorectl/util.go +++ b/cmd/mstorectl/util.go @@ -52,8 +52,8 @@ func (util *Util) Build() error { rootCmd.AddCommand(util.MakeFileCmds()) rootCmd.AddCommand(util.MakeCollectionCmds()) rootCmd.AddCommand(util.CreateImageCmds()) - rootCmd.AddCommand(util.CreateAccountCmds()) - rootCmd.AddCommand(util.CreateGrantCmds()) + rootCmd.AddCommand(util.MakeAccountCmds()) + rootCmd.AddCommand(util.MakeGrantCmds()) util.rootCmd = rootCmd diff --git a/pkg/accntcli/account.go b/pkg/accntcli/account.go deleted file mode 100644 index fe304e0..0000000 --- a/pkg/accntcli/account.go +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Copyright 2026 Oleg Borodin - * - * This work is published and licensed under a Creative Commons - * Attribution-NonCommercial-NoDerivatives 4.0 International License. - * - * Distribution of this work is permitted, but commercial use and - * modifications are strictly prohibited. - */ -package accntcli - -import ( - "context" - "encoding/json" - "errors" - - "mstore/app/accoper" - "mstore/app/handler" - "mstore/pkg/descr" -) - -func (cli *Client) CreateAccount(ctx context.Context, host, user, pass string) (string, error) { - var err error - var res string - params := accoper.CreateAccountParams{ - Username: user, - Password: pass, - } - reqdata, err := json.Marshal(params) - if err != nil { - return res, err - } - respdata, err := cli.doHTTPCall(ctx, host, "accont", "create", reqdata) - if err != nil { - return res, err - } - response := handler.NewResponse[accoper.CreateAccountResult]() - err = json.Unmarshal(respdata, response) - if err != nil { - return res, err - } - if response.Error { - err = errors.New(response.Message) - return res, err - } - res = response.Result.AccountID - return res, err -} - -func (cli *Client) GetAccountByID(ctx context.Context, host, accountID string) (*descr.AccountShort, error) { - var err error - res := &descr.AccountShort{} - - params := accoper.GetAccountParams{ - AccountID: accountID, - } - reqdata, err := json.Marshal(params) - if err != nil { - return res, err - } - resdata, err := cli.doHTTPCall(ctx, host, "account", "get", reqdata) - if err != nil { - return res, err - } - - response := handler.NewResponse[accoper.GetAccountResult]() - err = json.Unmarshal(resdata, response) - if err != nil { - return res, err - } - if response.Error { - err = errors.New(response.Message) - return res, err - } - res = response.Result.Account - return res, err -} - -func (cli *Client) GetAccountByName(ctx context.Context, host, username string) (*descr.AccountShort, error) { - var err error - res := &descr.AccountShort{} - params := accoper.GetAccountParams{ - Username: username, - } - reqdata, err := json.Marshal(params) - if err != nil { - return res, err - } - resdata, err := cli.doHTTPCall(ctx, host, "account", "get", reqdata) - if err != nil { - return res, err - } - response := handler.NewResponse[accoper.GetAccountResult]() - err = json.Unmarshal(resdata, response) - if err != nil { - return res, err - } - if response.Error { - err = errors.New(response.Message) - return res, err - } - res = response.Result.Account - return res, err -} - -func (cli *Client) UpdateAccountByID(ctx context.Context, host string, accountID, newUsername, newPassword string) error { - var err error - params := accoper.UpdateAccountParams{ - AccountID: accountID, - NewUsername: newUsername, - NewPassword: newPassword, - } - reqdata, err := json.Marshal(params) - if err != nil { - return err - } - resdata, err := cli.doHTTPCall(ctx, host, "account", "update", reqdata) - if err != nil { - return err - } - response := handler.NewResponse[accoper.UpdateAccountResult]() - err = json.Unmarshal(resdata, response) - if err != nil { - return err - } - if response.Error { - err = errors.New(response.Message) - return err - } - return err -} - -func (cli *Client) UpdateAccountByName(ctx context.Context, host, username, newUsername, newPassword string) error { - var err error - params := accoper.UpdateAccountParams{ - Username: username, - NewUsername: newUsername, - NewPassword: newPassword, - } - reqdata, err := json.Marshal(params) - if err != nil { - return err - } - resdata, err := cli.doHTTPCall(ctx, host, "account", "update", reqdata) - if err != nil { - return err - } - response := handler.NewResponse[accoper.UpdateAccountResult]() - err = json.Unmarshal(resdata, response) - if err != nil { - return err - } - if response.Error { - err = errors.New(response.Message) - return err - } - return err -} - -func (cli *Client) DeleteAccountByName(ctx context.Context, host, username string) error { - var err error - - params := accoper.DeleteAccountParams{ - Username: username, - } - reqdata, err := json.Marshal(params) - if err != nil { - return err - } - resdata, err := cli.doHTTPCall(ctx, host, "account", "delete", reqdata) - if err != nil { - return err - } - response := handler.NewResponse[accoper.DeleteAccountResult]() - err = json.Unmarshal(resdata, response) - if err != nil { - return err - } - if response.Error { - err = errors.New(response.Message) - return err - } - return err -} - -func (cli *Client) DeleteAccountByID(ctx context.Context, host, accountID string) error { - var err error - params := accoper.DeleteAccountParams{ - AccountID: accountID, - } - reqdata, err := json.Marshal(params) - if err != nil { - return err - } - resdata, err := cli.doHTTPCall(ctx, host, "account", "delete", reqdata) - if err != nil { - return err - } - response := handler.NewResponse[accoper.DeleteAccountResult]() - err = json.Unmarshal(resdata, response) - if err != nil { - return err - } - if response.Error { - err = errors.New(response.Message) - return err - } - return err -} - -func (cli *Client) ListAccounts(ctx context.Context, host string) ([]descr.AccountShort, error) { - var err error - res := make([]descr.AccountShort, 0) - - params := accoper.ListAccountsParams{} - reqdata, err := json.Marshal(params) - if err != nil { - return res, err - } - resdata, err := cli.doHTTPCall(ctx, host, "accounts", "list", reqdata) - if err != nil { - return res, err - } - response := handler.NewResponse[accoper.ListAccountsResult]() - err = json.Unmarshal(resdata, response) - if err != nil { - return res, err - } - if response.Error { - err = errors.New(response.Message) - return res, err - } - res = response.Result.Accounts - return res, err -} diff --git a/pkg/accntcli/createacc.go b/pkg/accntcli/createacc.go new file mode 100644 index 0000000..df4b529 --- /dev/null +++ b/pkg/accntcli/createacc.go @@ -0,0 +1,38 @@ +package accntcli + +import ( + "context" + "encoding/json" + "errors" + + "mstore/app/accoper" + "mstore/app/handler" +) + +func (cli *Client) CreateAccount(ctx context.Context, host, user, pass string) (string, error) { + var err error + var res string + params := accoper.CreateAccountParams{ + Username: user, + Password: pass, + } + reqdata, err := json.Marshal(params) + if err != nil { + return res, err + } + respdata, err := cli.doHTTPCall(ctx, host, "accont", "create", reqdata) + if err != nil { + return res, err + } + response := handler.NewResponse[accoper.CreateAccountResult]() + err = json.Unmarshal(respdata, response) + if err != nil { + return res, err + } + if response.Error { + err = errors.New(response.Message) + return res, err + } + res = response.Result.AccountID + return res, err +} diff --git a/pkg/accntcli/creategrant.go b/pkg/accntcli/creategrant.go new file mode 100644 index 0000000..3b72f8d --- /dev/null +++ b/pkg/accntcli/creategrant.go @@ -0,0 +1,71 @@ +package accntcli + +import ( + "context" + "encoding/json" + "errors" + + "mstore/app/accoper" + "mstore/app/handler" +) + +func (cli *Client) CreateGrantByAccountID(ctx context.Context, host string, accountID, right, pattern string) (string, error) { + var err error + var res string + + params := accoper.CreateGrantParams{ + AccountID: accountID, + Right: right, + Pattern: pattern, + } + reqdata, err := json.Marshal(params) + if err != nil { + return res, err + } + respdata, err := cli.doHTTPCall(ctx, host, "grant", "create", reqdata) + if err != nil { + return res, err + } + + response := handler.NewResponse[accoper.CreateGrantResult]() + err = json.Unmarshal(respdata, response) + if err != nil { + return res, err + } + if response.Error { + err = errors.New(response.Message) + return res, err + } + res = response.Result.GrantID + return res, err +} + +func (cli *Client) CreateGrantByUsername(ctx context.Context, host, username string, right string, pattern string) (string, error) { + var err error + var res string + params := accoper.CreateGrantParams{ + Username: username, + Right: right, + Pattern: pattern, + } + reqdata, err := json.Marshal(params) + if err != nil { + return res, err + } + respdata, err := cli.doHTTPCall(ctx, host, "grant", "create", reqdata) + if err != nil { + return res, err + } + + response := handler.NewResponse[accoper.CreateGrantResult]() + err = json.Unmarshal(respdata, response) + if err != nil { + return res, err + } + if response.Error { + err = errors.New(response.Message) + return res, err + } + res = response.Result.GrantID + return res, err +} diff --git a/pkg/accntcli/delacc.go b/pkg/accntcli/delacc.go new file mode 100644 index 0000000..6456b7b --- /dev/null +++ b/pkg/accntcli/delacc.go @@ -0,0 +1,62 @@ +package accntcli + +import ( + "context" + "encoding/json" + "errors" + + "mstore/app/accoper" + "mstore/app/handler" +) + +func (cli *Client) DeleteAccountByName(ctx context.Context, host, username string) error { + var err error + + params := accoper.DeleteAccountParams{ + Username: username, + } + reqdata, err := json.Marshal(params) + if err != nil { + return err + } + resdata, err := cli.doHTTPCall(ctx, host, "account", "delete", reqdata) + if err != nil { + return err + } + response := handler.NewResponse[accoper.DeleteAccountResult]() + err = json.Unmarshal(resdata, response) + if err != nil { + return err + } + if response.Error { + err = errors.New(response.Message) + return err + } + return err +} + +func (cli *Client) DeleteAccountByID(ctx context.Context, host, accountID string) error { + var err error + + params := accoper.DeleteAccountParams{ + AccountID: accountID, + } + reqdata, err := json.Marshal(params) + if err != nil { + return err + } + resdata, err := cli.doHTTPCall(ctx, host, "account", "delete", reqdata) + if err != nil { + return err + } + response := handler.NewResponse[accoper.DeleteAccountResult]() + err = json.Unmarshal(resdata, response) + if err != nil { + return err + } + if response.Error { + err = errors.New(response.Message) + return err + } + return err +} diff --git a/pkg/accntcli/delgrant.go b/pkg/accntcli/delgrant.go new file mode 100644 index 0000000..d6fee75 --- /dev/null +++ b/pkg/accntcli/delgrant.go @@ -0,0 +1,36 @@ +package accntcli + +import ( + "context" + "encoding/json" + "errors" + + "mstore/app/accoper" + "mstore/app/handler" +) + +func (cli *Client) DeleteGrant(ctx context.Context, host, grantID string) error { + var err error + params := accoper.DeleteGrantParams{ + GrantID: grantID, + } + reqdata, err := json.Marshal(params) + if err != nil { + return err + } + respdata, err := cli.doHTTPCall(ctx, host, "grant", "delete", reqdata) + if err != nil { + return err + } + + response := handler.NewResponse[accoper.DeleteGrantResult]() + err = json.Unmarshal(respdata, response) + if err != nil { + return err + } + if response.Error { + err = errors.New(response.Message) + return err + } + return err +} diff --git a/pkg/accntcli/getacc.go b/pkg/accntcli/getacc.go new file mode 100644 index 0000000..dacac72 --- /dev/null +++ b/pkg/accntcli/getacc.go @@ -0,0 +1,67 @@ +package accntcli + +import ( + "context" + "encoding/json" + "errors" + + "mstore/app/accoper" + "mstore/app/handler" + "mstore/pkg/descr" +) + +func (cli *Client) GetAccountByName(ctx context.Context, host, username string) (*descr.AccountShort, error) { + var err error + res := &descr.AccountShort{} + params := accoper.GetAccountParams{ + Username: username, + } + reqdata, err := json.Marshal(params) + if err != nil { + return res, err + } + resdata, err := cli.doHTTPCall(ctx, host, "account", "get", reqdata) + if err != nil { + return res, err + } + response := handler.NewResponse[accoper.GetAccountResult]() + err = json.Unmarshal(resdata, response) + if err != nil { + return res, err + } + if response.Error { + err = errors.New(response.Message) + return res, err + } + res = response.Result.Account + return res, err +} + +func (cli *Client) GetAccountByID(ctx context.Context, host, accountID string) (*descr.AccountShort, error) { + var err error + res := &descr.AccountShort{} + + params := accoper.GetAccountParams{ + AccountID: accountID, + } + reqdata, err := json.Marshal(params) + if err != nil { + return res, err + } + resdata, err := cli.doHTTPCall(ctx, host, "account", "get", reqdata) + if err != nil { + return res, err + } + + response := handler.NewResponse[accoper.GetAccountResult]() + err = json.Unmarshal(resdata, response) + if err != nil { + return res, err + } + if response.Error { + err = errors.New(response.Message) + return res, err + } + res = response.Result.Account + return res, err +} diff --git a/pkg/accntcli/getgrant.go b/pkg/accntcli/getgrant.go new file mode 100644 index 0000000..0a8a859 --- /dev/null +++ b/pkg/accntcli/getgrant.go @@ -0,0 +1,39 @@ +package accntcli + +import ( + "context" + "encoding/json" + "errors" + + "mstore/app/accoper" + "mstore/app/handler" + "mstore/pkg/descr" +) + +func (cli *Client) GetGrant(ctx context.Context, host, grantID string) (*descr.Grant, error) { + var err error + res := &descr.Grant{} + params := accoper.GetGrantParams{ + GrantID: grantID, + } + reqdata, err := json.Marshal(params) + if err != nil { + return res, err + } + respdata, err := cli.doHTTPCall(ctx, host, "grant", "get", reqdata) + if err != nil { + return res, err + } + + response := handler.NewResponse[accoper.GetGrantResult]() + err = json.Unmarshal(respdata, response) + if err != nil { + return res, err + } + if response.Error { + err = errors.New(response.Message) + return res, err + } + res = response.Result.Grant + return res, err +} diff --git a/pkg/accntcli/grant.go b/pkg/accntcli/grant.go deleted file mode 100644 index 09c48f9..0000000 --- a/pkg/accntcli/grant.go +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright 2026 Oleg Borodin - * - * This work is published and licensed under a Creative Commons - * Attribution-NonCommercial-NoDerivatives 4.0 International License. - * - * Distribution of this work is permitted, but commercial use and - * modifications are strictly prohibited. - */ -package accntcli - -import ( - "context" - "encoding/json" - "errors" - - "mstore/app/accoper" - "mstore/app/handler" - "mstore/pkg/descr" -) - -func (cli *Client) CreateGrantByAccountID(ctx context.Context, host string, accountID, right, pattern string) (string, error) { - var err error - var res string - - params := accoper.CreateGrantParams{ - AccountID: accountID, - Right: right, - Pattern: pattern, - } - reqdata, err := json.Marshal(params) - if err != nil { - return res, err - } - respdata, err := cli.doHTTPCall(ctx, host, "grant", "create", reqdata) - if err != nil { - return res, err - } - - response := handler.NewResponse[accoper.CreateGrantResult]() - err = json.Unmarshal(respdata, response) - if err != nil { - return res, err - } - if response.Error { - err = errors.New(response.Message) - return res, err - } - res = response.Result.GrantID - return res, err -} - -func (cli *Client) CreateGrantByUsername(ctx context.Context, host, username string, right string, pattern string) (string, error) { - var err error - var res string - params := accoper.CreateGrantParams{ - Username: username, - Right: right, - Pattern: pattern, - } - reqdata, err := json.Marshal(params) - if err != nil { - return res, err - } - respdata, err := cli.doHTTPCall(ctx, host, "grant", "create", reqdata) - if err != nil { - return res, err - } - - response := handler.NewResponse[accoper.CreateGrantResult]() - err = json.Unmarshal(respdata, response) - if err != nil { - return res, err - } - if response.Error { - err = errors.New(response.Message) - return res, err - } - res = response.Result.GrantID - return res, err -} - -func (cli *Client) GetGrant(ctx context.Context, host, grantID string) (*descr.Grant, error) { - var err error - res := &descr.Grant{} - params := accoper.GetGrantParams{ - GrantID: grantID, - } - reqdata, err := json.Marshal(params) - if err != nil { - return res, err - } - respdata, err := cli.doHTTPCall(ctx, host, "grant", "get", reqdata) - if err != nil { - return res, err - } - - response := handler.NewResponse[accoper.GetGrantResult]() - err = json.Unmarshal(respdata, response) - if err != nil { - return res, err - } - if response.Error { - err = errors.New(response.Message) - return res, err - } - res = response.Result.Grant - return res, err -} - -func (cli *Client) UpdateGrant(ctx context.Context, host, grantID, newPattern string) error { - var err error - params := accoper.UpdateGrantParams{ - GrantID: grantID, - NewPattern: newPattern, - } - reqdata, err := json.Marshal(params) - if err != nil { - return err - } - respdata, err := cli.doHTTPCall(ctx, host, "grant", "update", reqdata) - if err != nil { - return err - } - response := handler.NewResponse[accoper.UpdateGrantResult]() - err = json.Unmarshal(respdata, response) - if err != nil { - return err - } - if response.Error { - err = errors.New(response.Message) - return err - } - return err -} - -func (cli *Client) DeleteGrant(ctx context.Context, host, grantID string) error { - var err error - params := accoper.DeleteGrantParams{ - GrantID: grantID, - } - reqdata, err := json.Marshal(params) - if err != nil { - return err - } - respdata, err := cli.doHTTPCall(ctx, host, "grant", "delete", reqdata) - if err != nil { - return err - } - - response := handler.NewResponse[accoper.DeleteGrantResult]() - err = json.Unmarshal(respdata, response) - if err != nil { - return err - } - if response.Error { - err = errors.New(response.Message) - return err - } - return err -} - -func (cli *Client) ListGrantsByAccountID(ctx context.Context, host, accountID string) ([]descr.Grant, error) { - var err error - res := make([]descr.Grant, 0) - params := accoper.ListGrantsParams{ - AccountID: accountID, - } - reqdata, err := json.Marshal(params) - if err != nil { - return res, err - } - respdata, err := cli.doHTTPCall(ctx, host, "grants", "list", reqdata) - if err != nil { - return res, err - } - response := handler.NewResponse[accoper.ListGrantsResult]() - err = json.Unmarshal(respdata, response) - if err != nil { - return res, err - } - if response.Error { - err = errors.New(response.Message) - return res, err - } - res = response.Result.Grants - return res, err -} - -func (cli *Client) ListGrantsByUsername(ctx context.Context, host, username string) ([]descr.Grant, error) { - var err error - res := make([]descr.Grant, 0) - params := accoper.ListGrantsParams{ - Username: username, - } - reqdata, err := json.Marshal(params) - if err != nil { - return res, err - } - respdata, err := cli.doHTTPCall(ctx, host, "grants", "list", reqdata) - if err != nil { - return res, err - } - - response := handler.NewResponse[accoper.ListGrantsResult]() - err = json.Unmarshal(respdata, response) - if err != nil { - return res, err - } - if response.Error { - err = errors.New(response.Message) - return res, err - } - res = response.Result.Grants - return res, err -} diff --git a/pkg/accntcli/service.go b/pkg/accntcli/httpcall.go similarity index 70% rename from pkg/accntcli/service.go rename to pkg/accntcli/httpcall.go index fb0270d..5c848eb 100644 --- a/pkg/accntcli/service.go +++ b/pkg/accntcli/httpcall.go @@ -12,43 +12,12 @@ package accntcli import ( "bytes" "context" - "encoding/json" - "errors" "fmt" "io" "net/http" "strconv" - - "mstore/app/handler" - "mstore/app/imageoper" ) -func (cli *Client) ServiceHello(ctx context.Context, host string) (bool, error) { - var res bool - var err error - - params := imageoper.SendHelloParams{} - reqdata, err := json.Marshal(params) - if err != nil { - return res, err - } - resdata, err := cli.doHTTPCall(ctx, host, "service", "hello", reqdata) - if err != nil { - return res, err - } - response := handler.Response[imageoper.SendHelloResult]{} - err = json.Unmarshal(resdata, &response) - if err != nil { - return res, err - } - if response.Error { - err = errors.New(response.Message) - return res, err - } - res = response.Result.Alive - return res, err -} - func (cli *Client) doHTTPCall(ctx context.Context, host, obj, oper string, req []byte) ([]byte, error) { var err error var res []byte diff --git a/pkg/accntcli/listacc.go b/pkg/accntcli/listacc.go new file mode 100644 index 0000000..6ceef2d --- /dev/null +++ b/pkg/accntcli/listacc.go @@ -0,0 +1,37 @@ +package accntcli + +import ( + "context" + "encoding/json" + "errors" + + "mstore/app/accoper" + "mstore/app/handler" + "mstore/pkg/descr" +) + +func (cli *Client) ListAccounts(ctx context.Context, host string) ([]descr.AccountShort, error) { + var err error + res := make([]descr.AccountShort, 0) + + params := accoper.ListAccountsParams{} + reqdata, err := json.Marshal(params) + if err != nil { + return res, err + } + resdata, err := cli.doHTTPCall(ctx, host, "accounts", "list", reqdata) + if err != nil { + return res, err + } + response := handler.NewResponse[accoper.ListAccountsResult]() + err = json.Unmarshal(resdata, response) + if err != nil { + return res, err + } + if response.Error { + err = errors.New(response.Message) + return res, err + } + res = response.Result.Accounts + return res, err +} diff --git a/pkg/accntcli/listgrants.go b/pkg/accntcli/listgrants.go new file mode 100644 index 0000000..df4061a --- /dev/null +++ b/pkg/accntcli/listgrants.go @@ -0,0 +1,66 @@ +package accntcli + +import ( + "context" + "encoding/json" + "errors" + + "mstore/app/accoper" + "mstore/app/handler" + "mstore/pkg/descr" +) + +func (cli *Client) ListGrantsByUsername(ctx context.Context, host, username string) ([]descr.Grant, error) { + var err error + res := make([]descr.Grant, 0) + params := accoper.ListGrantsParams{ + Username: username, + } + reqdata, err := json.Marshal(params) + if err != nil { + return res, err + } + respdata, err := cli.doHTTPCall(ctx, host, "grants", "list", reqdata) + if err != nil { + return res, err + } + + response := handler.NewResponse[accoper.ListGrantsResult]() + err = json.Unmarshal(respdata, response) + if err != nil { + return res, err + } + if response.Error { + err = errors.New(response.Message) + return res, err + } + res = response.Result.Grants + return res, err +} + +func (cli *Client) ListGrantsByAccountID(ctx context.Context, host, accountID string) ([]descr.Grant, error) { + var err error + res := make([]descr.Grant, 0) + params := accoper.ListGrantsParams{ + AccountID: accountID, + } + reqdata, err := json.Marshal(params) + if err != nil { + return res, err + } + respdata, err := cli.doHTTPCall(ctx, host, "grants", "list", reqdata) + if err != nil { + return res, err + } + response := handler.NewResponse[accoper.ListGrantsResult]() + err = json.Unmarshal(respdata, response) + if err != nil { + return res, err + } + if response.Error { + err = errors.New(response.Message) + return res, err + } + res = response.Result.Grants + return res, err +} diff --git a/pkg/accntcli/referer.go b/pkg/accntcli/referer.go index 36e637f..40396fa 100644 --- a/pkg/accntcli/referer.go +++ b/pkg/accntcli/referer.go @@ -34,6 +34,29 @@ func NewReferer(hostname, object, operation string) (*Referer, error) { return ref, err } +func ParseHostinfo(hostname string) (*Referer, error) { + ref := &Referer{} + if !strings.Contains(hostname, "://") { + hostname = "https://" + hostname + } + urlobj, err := url.Parse(hostname) + if err != nil { + return ref, err + } + if urlobj.User != nil { + ref.user = urlobj.User.Username() + ref.pass, _ = urlobj.User.Password() + urlobj.User = nil + } + urlobj.Path = "/" + ref.urlobj = urlobj + return ref, err +} + +func (ref *Referer) Host() string { + return ref.urlobj.Host +} + func (ref *Referer) Raw() string { return path.Join(ref.urlobj.Host, "/v3/api/", ref.obj, ref.oper) } diff --git a/pkg/accntcli/servhello.go b/pkg/accntcli/servhello.go new file mode 100644 index 0000000..e643b3a --- /dev/null +++ b/pkg/accntcli/servhello.go @@ -0,0 +1,36 @@ +package accntcli + +import ( + "context" + "encoding/json" + "errors" + + "mstore/app/handler" + "mstore/app/imageoper" +) + +func (cli *Client) ServiceHello(ctx context.Context, host string) (bool, error) { + var res bool + var err error + + params := imageoper.SendHelloParams{} + reqdata, err := json.Marshal(params) + if err != nil { + return res, err + } + resdata, err := cli.doHTTPCall(ctx, host, "service", "hello", reqdata) + if err != nil { + return res, err + } + response := handler.Response[imageoper.SendHelloResult]{} + err = json.Unmarshal(resdata, &response) + if err != nil { + return res, err + } + if response.Error { + err = errors.New(response.Message) + return res, err + } + res = response.Result.Alive + return res, err +} diff --git a/pkg/accntcli/updateacc.go b/pkg/accntcli/updateacc.go new file mode 100644 index 0000000..2ca8867 --- /dev/null +++ b/pkg/accntcli/updateacc.go @@ -0,0 +1,64 @@ +package accntcli + +import ( + "context" + "encoding/json" + "errors" + + "mstore/app/accoper" + "mstore/app/handler" +) + +func (cli *Client) UpdateAccountByName(ctx context.Context, host, username, newUsername, newPassword string) error { + var err error + params := accoper.UpdateAccountParams{ + Username: username, + NewUsername: newUsername, + NewPassword: newPassword, + } + reqdata, err := json.Marshal(params) + if err != nil { + return err + } + resdata, err := cli.doHTTPCall(ctx, host, "account", "update", reqdata) + if err != nil { + return err + } + response := handler.NewResponse[accoper.UpdateAccountResult]() + err = json.Unmarshal(resdata, response) + if err != nil { + return err + } + if response.Error { + err = errors.New(response.Message) + return err + } + return err +} + +func (cli *Client) UpdateAccountByID(ctx context.Context, host string, accountID, newUsername, newPassword string) error { + var err error + params := accoper.UpdateAccountParams{ + AccountID: accountID, + NewUsername: newUsername, + NewPassword: newPassword, + } + reqdata, err := json.Marshal(params) + if err != nil { + return err + } + resdata, err := cli.doHTTPCall(ctx, host, "account", "update", reqdata) + if err != nil { + return err + } + response := handler.NewResponse[accoper.UpdateAccountResult]() + err = json.Unmarshal(resdata, response) + if err != nil { + return err + } + if response.Error { + err = errors.New(response.Message) + return err + } + return err +} diff --git a/pkg/accntcli/updgrant.go b/pkg/accntcli/updgrant.go new file mode 100644 index 0000000..0a61b23 --- /dev/null +++ b/pkg/accntcli/updgrant.go @@ -0,0 +1,36 @@ +package accntcli + +import ( + "context" + "encoding/json" + "errors" + + "mstore/app/accoper" + "mstore/app/handler" +) + +func (cli *Client) UpdateGrant(ctx context.Context, host, grantID, newPattern string) error { + var err error + params := accoper.UpdateGrantParams{ + GrantID: grantID, + NewPattern: newPattern, + } + reqdata, err := json.Marshal(params) + if err != nil { + return err + } + respdata, err := cli.doHTTPCall(ctx, host, "grant", "update", reqdata) + if err != nil { + return err + } + response := handler.NewResponse[accoper.UpdateGrantResult]() + err = json.Unmarshal(respdata, response) + if err != nil { + return err + } + if response.Error { + err = errors.New(response.Message) + return err + } + return err +}