From 8f4aae93dbd477079441a2171f6ee253bfbf734b Mon Sep 17 00:00:00 2001 From: Angel Borroy Date: Fri, 12 May 2023 12:22:08 +0200 Subject: [PATCH] Support for GROUP command --- Makefile | 2 +- README.md | 38 ++------- alfresco.go | 1 + cmd/group/add.go | 55 ++++++++++++ cmd/group/create.go | 60 +++++++++++++ cmd/group/delete.go | 39 +++++++++ cmd/group/get.go | 40 +++++++++ cmd/group/group-type.go | 122 +++++++++++++++++++++++++++ cmd/group/group.go | 24 ++++++ cmd/group/list.go | 62 ++++++++++++++ cmd/group/sub.go | 45 ++++++++++ cmd/group/update.go | 51 +++++++++++ cmd/people/groups.go | 58 +++++++++++++ cmd/people/update.go | 2 +- cmd/root.go | 2 +- docs/alfresco.md | 1 + docs/generate/generate.go | 1 + docs/group/alfresco_group.md | 37 ++++++++ docs/group/alfresco_group_add.md | 37 ++++++++ docs/group/alfresco_group_create.md | 39 +++++++++ docs/group/alfresco_group_delete.md | 35 ++++++++ docs/group/alfresco_group_get.md | 36 ++++++++ docs/group/alfresco_group_list.md | 39 +++++++++ docs/group/alfresco_group_sub.md | 36 ++++++++ docs/group/alfresco_group_update.md | 37 ++++++++ docs/people/alfresco_people.md | 1 + docs/people/alfresco_people_group.md | 39 +++++++++ test/test_group.sh | 73 ++++++++++++++++ test/test_people.sh | 8 ++ 29 files changed, 986 insertions(+), 34 deletions(-) create mode 100644 cmd/group/add.go create mode 100644 cmd/group/create.go create mode 100644 cmd/group/delete.go create mode 100644 cmd/group/get.go create mode 100644 cmd/group/group-type.go create mode 100644 cmd/group/group.go create mode 100644 cmd/group/list.go create mode 100644 cmd/group/sub.go create mode 100644 cmd/group/update.go create mode 100644 cmd/people/groups.go create mode 100644 docs/group/alfresco_group.md create mode 100644 docs/group/alfresco_group_add.md create mode 100644 docs/group/alfresco_group_create.md create mode 100644 docs/group/alfresco_group_delete.md create mode 100644 docs/group/alfresco_group_get.md create mode 100644 docs/group/alfresco_group_list.md create mode 100644 docs/group/alfresco_group_sub.md create mode 100644 docs/group/alfresco_group_update.md create mode 100644 docs/people/alfresco_people_group.md create mode 100755 test/test_group.sh diff --git a/Makefile b/Makefile index 805cca9..5df99c2 100644 --- a/Makefile +++ b/Makefile @@ -27,7 +27,7 @@ $(DARWIN): env GOOS=darwin GOARCH=arm64 go build -v -o $(DARWIN) -ldflags="-s -w -X main.version=$(VERSION)" ./alfresco.go test: - cd test && ./test_node.sh && ./test_people.sh + cd test && ./test_node.sh && ./test_people.sh && ./test_group.sh docs: cd docs/generate && go build generate.go && ./generate diff --git a/README.md b/README.md index 6914cbf..57926c6 100644 --- a/README.md +++ b/README.md @@ -11,16 +11,19 @@ Using `-h` flag provides detail on the use of the different commands available: ``` $ ./alfresco -h -A Command Line Interface for Alfresco Content Services. +Alfresco CLI provides access to Alfresco REST API services via command line. +A running ACS server is required to use this program (commonly available in http://localhost:8080/alfresco). Usage: alfresco [command] Available Commands: completion Generate the autocompletion script for the specified shell - config Connection details + config Manage ACS connection details + group Manage groups in ACS Repository help Help about any command - node Manage nodes + node Manage nodes in ACS Repository + people Manage people in ACS Repository Flags: -h, --help help for alfresco @@ -79,32 +82,6 @@ $ tail -f alfresco.log 2023/04/28 10:12:56 ERROR [NODE CREATE] Post "http://localhost:8080/alfresco/api/-default-/public/alfresco/versions/1/nodes/4960a8a5-a258-4fed-84b4-73ae8cf9b2de/children": EOF ``` -## Commands - -**Node** - -The `node` command provides access to Node handling in Alfresco Repository. - -``` -./alfresco node -h -Manage nodes - -Usage: - alfresco node [command] - -Available Commands: - create Create new Node - delete Delete Node - download-folder Download Alfresco Repository folder to local folder - get Get Node information (properties and content) - list Get children nodes - update Update Node information - upload-folder Upload local folder to Alfresco Repository - -Flags: - -i, --nodeId string Node Id in Alfresco Repository -``` - ## Generic flags ``` @@ -173,12 +150,11 @@ Sample bash scripts for testing purposes are provided in [test](test) folder. ## Documentation -Detailed documentation is available in [docs/alfresco.md](docs/alfresco.md) +Detailed documentation for available commands in [docs/alfresco.md](docs/alfresco.md) ## TODO * Site commands -* Group commands * Search commands * Provide pre-built programs for Windows, Linux, Mac AMD64 & Mac ARM64 * Control concurrency rate \ No newline at end of file diff --git a/alfresco.go b/alfresco.go index cd13866..6f70e30 100644 --- a/alfresco.go +++ b/alfresco.go @@ -6,6 +6,7 @@ import ( "github.com/aborroy/alfresco-cli/cmd" _ "github.com/aborroy/alfresco-cli/cmd/config" + _ "github.com/aborroy/alfresco-cli/cmd/group" _ "github.com/aborroy/alfresco-cli/cmd/node" _ "github.com/aborroy/alfresco-cli/cmd/people" ) diff --git a/cmd/group/add.go b/cmd/group/add.go new file mode 100644 index 0000000..6178775 --- /dev/null +++ b/cmd/group/add.go @@ -0,0 +1,55 @@ +package group + +import ( + "encoding/json" + "log" + "net/http" + + "github.com/aborroy/alfresco-cli/cmd" + "github.com/aborroy/alfresco-cli/httpclient" + "github.com/spf13/cobra" +) + +const AddGroupCmdId string = "[GROUP ADD]" + +var authorityId string +var authorityType string +var groupAddCmd = &cobra.Command{ + Use: "add", + Short: "Add an authority (person or group) to a Group in repository", + Long: `The authority is added as children of the Group.`, + Run: func(command *cobra.Command, args []string) { + + var groupAdd GroupAdd + groupAdd.ID = authorityId + groupAdd.MemberType = authorityType + jsonGroupAdd, _ := json.Marshal(groupAdd) + + execution := &httpclient.HttpExecution{ + Method: http.MethodPost, + Data: string(jsonGroupAdd), + Format: httpclient.Json, + Url: groupsUrlPath + groupId + "/members", + ResponseBodyOutput: &responseBody, + } + + _error := httpclient.Execute(execution) + if _error != nil { + cmd.ExitWithError(AddGroupCmdId, _error) + } + }, + PostRun: func(command *cobra.Command, args []string) { + log.Println(AddGroupCmdId, "Authority "+authorityId+" ("+authorityType+") has been added to group "+groupId) + }, +} + +func init() { + groupCmd.AddCommand(groupAddCmd) + groupAddCmd.Flags().StringVarP(&groupId, "groupId", "i", "", "ID of the group in Alfresco Repository.") + groupAddCmd.Flags().StringVarP(&authorityId, "authorityId", "a", "", "ID of the authority (group or person) in Alfresco Repository to be added.") + groupAddCmd.Flags().StringVarP(&authorityType, "authorityType", "t", "", "Type of the authority: GROUP or PERSON.") + groupAddCmd.Flags().SortFlags = false + groupAddCmd.MarkFlagRequired("groupId") + groupAddCmd.MarkFlagRequired("authorityId") + groupAddCmd.MarkFlagRequired("authorityType") +} diff --git a/cmd/group/create.go b/cmd/group/create.go new file mode 100644 index 0000000..b185dd0 --- /dev/null +++ b/cmd/group/create.go @@ -0,0 +1,60 @@ +package group + +import ( + "encoding/json" + "log" + "net/http" + "strings" + + "github.com/aborroy/alfresco-cli/cmd" + "github.com/aborroy/alfresco-cli/httpclient" + "github.com/spf13/cobra" +) + +const CreateGroupCmdId string = "[GROUP CREATE]" + +var displayName string +var parentIds []string +var groupCreateCmd = &cobra.Command{ + Use: "create", + Short: "Create new Group in ACS Repository", + Long: `Creates a new group in the repository. +The group can be created setting only required properties. +When specifying parentIds, the group is created associated to those parentIds, not as a children of them.`, + Run: func(command *cobra.Command, args []string) { + + var groupCreate GroupUpdate + groupCreate.ID = groupId + groupCreate.DisplayName = displayName + if parentIds != nil { + groupCreate.ParentIds = parentIds + } + jsonGroupCreate, _ := json.Marshal(groupCreate) + + execution := &httpclient.HttpExecution{ + Method: http.MethodPost, + Data: string(jsonGroupCreate), + Format: httpclient.Json, + Url: strings.TrimSuffix(groupsUrlPath, "/"), + ResponseBodyOutput: &responseBody, + } + + _error := httpclient.Execute(execution) + if _error != nil { + cmd.ExitWithError(CreateGroupCmdId, _error) + } + }, + PostRun: func(command *cobra.Command, args []string) { + log.Println(CreateGroupCmdId, "Group "+groupId+" has been created") + }, +} + +func init() { + groupCmd.AddCommand(groupCreateCmd) + groupCreateCmd.Flags().StringVarP(&groupId, "groupId", "i", "", "ID of the group in Alfresco Repository.") + groupCreateCmd.Flags().StringVarP(&displayName, "displayName", "d", "", "Display name of the group in Alfresco Repository.") + groupCreateCmd.Flags().StringArrayVarP(&parentIds, "parentIds", "p", nil, "List containing the IDs of parent groups.") + groupCreateCmd.Flags().SortFlags = false + groupCreateCmd.MarkFlagRequired("groupId") + +} diff --git a/cmd/group/delete.go b/cmd/group/delete.go new file mode 100644 index 0000000..d20cbc1 --- /dev/null +++ b/cmd/group/delete.go @@ -0,0 +1,39 @@ +package group + +import ( + "log" + "net/http" + + "github.com/aborroy/alfresco-cli/cmd" + "github.com/aborroy/alfresco-cli/httpclient" + "github.com/spf13/cobra" +) + +const DeleteGroupCmdId string = "[GROUP DELETE]" + +var groupDeleteCmd = &cobra.Command{ + Use: "delete", + Short: "Delete a Group existing in the repository", + Long: `Removes an existing group from the repository.`, + Run: func(command *cobra.Command, args []string) { + execution := &httpclient.HttpExecution{ + Method: http.MethodDelete, + Format: httpclient.None, + Url: groupsUrlPath + groupId, + ResponseBodyOutput: &responseBody, + } + _error := httpclient.Execute(execution) + if _error != nil { + cmd.ExitWithError(DeleteGroupCmdId, _error) + } + }, + PostRun: func(command *cobra.Command, args []string) { + log.Println(DeleteGroupCmdId, "Group "+groupId+" has been deleted") + }, +} + +func init() { + groupCmd.AddCommand(groupDeleteCmd) + groupDeleteCmd.Flags().StringVarP(&groupId, "groupId", "i", "", "ID of the group in Alfresco Repository.") + groupDeleteCmd.MarkFlagRequired("groupId") +} diff --git a/cmd/group/get.go b/cmd/group/get.go new file mode 100644 index 0000000..502fc04 --- /dev/null +++ b/cmd/group/get.go @@ -0,0 +1,40 @@ +package group + +import ( + "log" + "net/http" + + "github.com/aborroy/alfresco-cli/cmd" + "github.com/aborroy/alfresco-cli/httpclient" + "github.com/spf13/cobra" +) + +const GetGroupCmdId string = "[GROUP GET]" + +var groupGetCmd = &cobra.Command{ + Use: "get", + Short: "Get Group information from repository", + Long: `Properties of the Group are retrieved. +Properties are provided as output of the command.`, + Run: func(command *cobra.Command, args []string) { + execution := &httpclient.HttpExecution{ + Method: http.MethodGet, + Format: httpclient.None, + Url: groupsUrlPath + groupId, + ResponseBodyOutput: &responseBody, + } + _error := httpclient.Execute(execution) + if _error != nil { + cmd.ExitWithError(GetGroupCmdId, _error) + } + }, + PostRun: func(command *cobra.Command, args []string) { + log.Println(GetGroupCmdId, "Details for group "+groupId+" have been retrieved") + }, +} + +func init() { + groupCmd.AddCommand(groupGetCmd) + groupGetCmd.Flags().StringVarP(&groupId, "groupId", "i", "", "ID of the group in Alfresco Repository.") + groupGetCmd.MarkFlagRequired("groupId") +} diff --git a/cmd/group/group-type.go b/cmd/group/group-type.go new file mode 100644 index 0000000..aca516c --- /dev/null +++ b/cmd/group/group-type.go @@ -0,0 +1,122 @@ +package group + +import ( + "encoding/json" + "fmt" + "os" + "reflect" + "strconv" + "text/tabwriter" + + "github.com/aborroy/alfresco-cli/cmd" +) + +const groupsUrlPath string = "/api/-default-/public/alfresco/versions/1/groups/" + +type GroupUpdate struct { + ID string `json:"id,omitempty"` + DisplayName string `json:"displayName,omitempty"` + ParentIds []string `json:"parentIds,omitempty"` +} + +type GroupAdd struct { + ID string `json:"id"` + MemberType string `json:"memberType,omitempty"` +} + +type Group struct { + Entry struct { + IsRoot bool `json:"isRoot"` + DisplayName string `json:"displayName"` + ID string `json:"id"` + MemberType string `json:"memberType,omitempty"` + } `json:"entry"` +} + +type GroupList struct { + List struct { + Pagination struct { + Count int `json:"count"` + HasMoreItems bool `json:"hasMoreItems"` + TotalItems int `json:"totalItems"` + SkipCount int `json:"skipCount"` + MaxItems int `json:"maxItems"` + } `json:"pagination"` + Entries []struct { + Group + } `json:"entries"` + } `json:"list"` +} + +func output(data []byte, format string) { + if format == string(cmd.Json) { + fmt.Println(string(data[:])) + } else { + var groupList GroupList + err := json.Unmarshal(data, &groupList) + if err != nil || reflect.DeepEqual(groupList, GroupList{}) { + outputGroup(data, format) + } else { + outputGroupList(data, format, groupList) + } + } +} + +func outputGroup(data []byte, format string) { + switch format { + case string(cmd.Id): + var group Group + json.Unmarshal(data, &group) + fmt.Println(group.Entry.ID) + case string(cmd.Default): + var group Group + json.Unmarshal(data, &group) + if !reflect.DeepEqual(group, Group{}) { + w := tabwriter.NewWriter(os.Stdout, 1, 1, 1, ' ', 0) + if group.Entry.MemberType == "" { + group.Entry.MemberType = "GROUP" + } + fmt.Fprintln(w, "ID\tNAME\tIS ROOT\tTYPE\t") + fmt.Fprintln(w, + group.Entry.ID+"\t"+ + group.Entry.DisplayName+"\t"+ + strconv.FormatBool(group.Entry.IsRoot)+"\t"+ + group.Entry.MemberType+"\t") + w.Flush() + } + default: + fmt.Println("Format '" + format + "' is not an option, allowed values are 'id', 'json' or 'default'") + } +} + +func outputGroupList(data []byte, format string, groupList GroupList) { + switch format { + case string(cmd.Id): + for _, group := range groupList.List.Entries { + fmt.Println(group.Entry.ID) + } + case string(cmd.Default): + w := tabwriter.NewWriter(os.Stdout, 1, 4, 1, ' ', 0) + fmt.Fprintln(w, "ID\tNAME\tIS ADMIN\tTYPE\t") + for _, group := range groupList.List.Entries { + if group.Entry.MemberType == "" { + group.Entry.MemberType = "GROUP" + } + fmt.Fprintln(w, + group.Entry.ID+"\t"+ + group.Entry.DisplayName+"\t"+ + strconv.FormatBool(group.Entry.IsRoot)+"\t"+ + group.Entry.MemberType+"\t") + } + w.Flush() + fmt.Printf("# Count=%d, HasMoreItems=%t, TotalItems=%d, SkipCount=%d, MaxItems=%d", + groupList.List.Pagination.Count, + groupList.List.Pagination.HasMoreItems, + groupList.List.Pagination.TotalItems, + groupList.List.Pagination.SkipCount, + groupList.List.Pagination.MaxItems) + default: + fmt.Println("Format '" + format + "' is not an option, allowed values are 'id', 'json' or 'default'") + } + +} diff --git a/cmd/group/group.go b/cmd/group/group.go new file mode 100644 index 0000000..1a45cba --- /dev/null +++ b/cmd/group/group.go @@ -0,0 +1,24 @@ +package group + +import ( + "bytes" + + "github.com/aborroy/alfresco-cli/cmd" + "github.com/spf13/cobra" +) + +var responseBody bytes.Buffer +var groupId string +var groupCmd = &cobra.Command{ + Use: "group", + Short: "Manage groups in ACS Repository", + Long: `ACS Repository handles a set of Groups that main contain another groups or persons.`, + PersistentPostRun: func(command *cobra.Command, args []string) { + var format, _ = command.Flags().GetString("output") + output(responseBody.Bytes(), format) + }, +} + +func init() { + cmd.RootCmd.AddCommand(groupCmd) +} diff --git a/cmd/group/list.go b/cmd/group/list.go new file mode 100644 index 0000000..d34f6cc --- /dev/null +++ b/cmd/group/list.go @@ -0,0 +1,62 @@ +package group + +import ( + "log" + "net/http" + "strconv" + + "github.com/aborroy/alfresco-cli/cmd" + "github.com/aborroy/alfresco-cli/httpclient" + "github.com/aborroy/alfresco-cli/nativestore" + "github.com/spf13/cobra" + "github.com/spf13/viper" +) + +const ListGroupCmdId string = "[GROUP LIST]" + +var skipCount int +var maxItems int +var groupListCmd = &cobra.Command{ + Use: "list", + Short: "Get Group list from repository", + Long: `Properties List is provided as output of the command. +If list elements count is greater than "maxItems" flag, output includes "HasMoreItems" field set to true. +Incrementing the "skipCount" flag on a loop will allow to retrieve all the children nodes.`, + Run: func(command *cobra.Command, args []string) { + if maxItems == -1 { + maxItems = viper.GetInt(nativestore.MaxItemsLabel) + } + var params = make(map[string]string) + params["skipCount"] = strconv.Itoa(skipCount) + params["maxItems"] = strconv.Itoa(maxItems) + + var url = groupsUrlPath + groupId + "/members" + if groupId == "" { + url = groupsUrlPath + } + + execution := &httpclient.HttpExecution{ + Method: http.MethodGet, + Format: httpclient.None, + Url: url, + Parameters: httpclient.GetUrlParams(params), + ResponseBodyOutput: &responseBody, + } + + _error := httpclient.Execute(execution) + if _error != nil { + cmd.ExitWithError(ListGroupCmdId, _error) + } + }, + PostRun: func(command *cobra.Command, args []string) { + log.Println(ListGroupCmdId, "Group list has been retrieved") + }, +} + +func init() { + groupCmd.AddCommand(groupListCmd) + groupListCmd.Flags().StringVarP(&groupId, "groupId", "i", "", "ID of the group in Alfresco Repository. When this parameter is omitted, group list is recovered from root node.") + groupListCmd.Flags().IntVar(&skipCount, "skipCount", 0, "Skip a number of initial nodes from the list") + groupListCmd.Flags().IntVar(&maxItems, "maxItems", -1, "Maximum number of nodes in the response list (max. 1000)") + groupListCmd.Flags().SortFlags = false +} diff --git a/cmd/group/sub.go b/cmd/group/sub.go new file mode 100644 index 0000000..70788aa --- /dev/null +++ b/cmd/group/sub.go @@ -0,0 +1,45 @@ +package group + +import ( + "log" + "net/http" + + "github.com/aborroy/alfresco-cli/cmd" + "github.com/aborroy/alfresco-cli/httpclient" + "github.com/spf13/cobra" +) + +const SubGroupCmdId string = "[GROUP SUB]" + +var memberId string +var groupSubCmd = &cobra.Command{ + Use: "sub", + Short: "Removes an authority (person or group) from a Group in repository", + Long: `The authority is removed as children of the Group.`, + Run: func(command *cobra.Command, args []string) { + + execution := &httpclient.HttpExecution{ + Method: http.MethodDelete, + Format: httpclient.Json, + Url: groupsUrlPath + groupId + "/members/" + memberId, + ResponseBodyOutput: &responseBody, + } + + _error := httpclient.Execute(execution) + if _error != nil { + cmd.ExitWithError(SubGroupCmdId, _error) + } + }, + PostRun: func(command *cobra.Command, args []string) { + log.Println(SubGroupCmdId, "Auhtority "+authorityId+" ("+authorityType+") has been removed from group "+groupId) + }, +} + +func init() { + groupCmd.AddCommand(groupSubCmd) + groupSubCmd.Flags().StringVarP(&groupId, "groupId", "i", "", "ID of the group in Alfresco Repository.") + groupSubCmd.Flags().StringVarP(&memberId, "memberId", "m", "", "ID of the authority (group or person) in Alfresco Repository to be added.") + groupSubCmd.Flags().SortFlags = false + groupSubCmd.MarkFlagRequired("groupId") + groupSubCmd.MarkFlagRequired("memberId") +} diff --git a/cmd/group/update.go b/cmd/group/update.go new file mode 100644 index 0000000..ed1f0ae --- /dev/null +++ b/cmd/group/update.go @@ -0,0 +1,51 @@ +package group + +import ( + "encoding/json" + "log" + "net/http" + + "github.com/aborroy/alfresco-cli/cmd" + "github.com/aborroy/alfresco-cli/httpclient" + "github.com/spf13/cobra" +) + +const UpdateGroupCmdId string = "[GROUP UPDATE]" + +var groupUpdateCmd = &cobra.Command{ + Use: "update", + Short: "Update Group properties in ACS Repository", + Long: `Updates an existing group in the repository. +Add only properties that require modification.`, + Run: func(command *cobra.Command, args []string) { + + var groupUpdate GroupUpdate + groupUpdate.DisplayName = displayName + jsonGroupUpdate, _ := json.Marshal(groupUpdate) + + execution := &httpclient.HttpExecution{ + Method: http.MethodPut, + Data: string(jsonGroupUpdate), + Format: httpclient.Json, + Url: groupsUrlPath + groupId, + ResponseBodyOutput: &responseBody, + } + + _error := httpclient.Execute(execution) + if _error != nil { + cmd.ExitWithError(CreateGroupCmdId, _error) + } + }, + PostRun: func(command *cobra.Command, args []string) { + log.Println(CreateGroupCmdId, "Group "+groupId+" has been updated") + }, +} + +func init() { + groupCmd.AddCommand(groupUpdateCmd) + groupUpdateCmd.Flags().StringVarP(&groupId, "groupId", "i", "", "ID of the group in Alfresco Repository.") + groupUpdateCmd.Flags().StringVarP(&displayName, "displayName", "d", "", "Display name of the group in Alfresco Repository.") + groupUpdateCmd.Flags().SortFlags = false + groupUpdateCmd.MarkFlagRequired("groupId") + groupUpdateCmd.MarkFlagRequired("displayName") +} diff --git a/cmd/people/groups.go b/cmd/people/groups.go new file mode 100644 index 0000000..a135b2b --- /dev/null +++ b/cmd/people/groups.go @@ -0,0 +1,58 @@ +package people + +import ( + "log" + "net/http" + "strconv" + + "github.com/aborroy/alfresco-cli/cmd" + "github.com/aborroy/alfresco-cli/httpclient" + "github.com/aborroy/alfresco-cli/nativestore" + "github.com/spf13/cobra" + "github.com/spf13/viper" +) + +const GroupPeopleCmdId string = "[PEOPLE GROUP]" + +var skipCountGroup int +var maxItemsGroup int +var peopleGroupCmd = &cobra.Command{ + Use: "group", + Short: "Get Group list for a person in repository", + Long: `Properties List is provided as output of the command. +If list elements count is greater than "maxItems" flag, output includes "HasMoreItems" field set to true. +Incrementing the "skipCount" flag on a loop will allow to retrieve all the children nodes.`, + Run: func(command *cobra.Command, args []string) { + if maxItems == -1 { + maxItemsGroup = viper.GetInt(nativestore.MaxItemsLabel) + } + var params = make(map[string]string) + params["skipCount"] = strconv.Itoa(skipCountGroup) + params["maxItems"] = strconv.Itoa(maxItemsGroup) + + execution := &httpclient.HttpExecution{ + Method: http.MethodGet, + Format: httpclient.None, + Url: peopleUrlPath + personId + "/groups", + Parameters: httpclient.GetUrlParams(params), + ResponseBodyOutput: &responseBody, + } + + _error := httpclient.Execute(execution) + if _error != nil { + cmd.ExitWithError(GroupPeopleCmdId, _error) + } + }, + PostRun: func(command *cobra.Command, args []string) { + log.Println(GroupPeopleCmdId, "Group list for person "+personId+"has been retrieved") + }, +} + +func init() { + peopleCmd.AddCommand(peopleGroupCmd) + peopleGroupCmd.Flags().StringVarP(&personId, "personId", "i", "", "Username of the user in Alfresco Repository. You can use the -me- string in place of to specify the currently authenticated user.") + peopleGroupCmd.Flags().IntVar(&skipCountGroup, "skipCount", 0, "Skip a number of initial nodes from the list") + peopleGroupCmd.Flags().IntVar(&maxItemsGroup, "maxItems", -1, "Maximum number of nodes in the response list (max. 1000)") + peopleGroupCmd.Flags().SortFlags = false + peopleGroupCmd.MarkFlagRequired("personId") +} diff --git a/cmd/people/update.go b/cmd/people/update.go index e95dcf4..a6eec09 100644 --- a/cmd/people/update.go +++ b/cmd/people/update.go @@ -41,7 +41,7 @@ Add only properties that require modification.`, } }, PostRun: func(command *cobra.Command, args []string) { - log.Println(CreatePeopleCmdId, "Person "+personId+" has been created") + log.Println(CreatePeopleCmdId, "Person "+personId+" has been updated") }, } diff --git a/cmd/root.go b/cmd/root.go index f889a6c..5d14374 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -23,7 +23,7 @@ var RootCmd = &cobra.Command{ Short: "A Command Line Interface for Alfresco Content Services", Long: `Alfresco CLI provides access to Alfresco REST API services via command line. A running ACS server is required to use this program (commonly available in http://localhost:8080/alfresco).`, - Version: "0.0.3", + Version: "0.0.4", } var UsernameParam string diff --git a/docs/alfresco.md b/docs/alfresco.md index 8151285..d697eea 100644 --- a/docs/alfresco.md +++ b/docs/alfresco.md @@ -23,6 +23,7 @@ A running ACS server is required to use this program (commonly available in http ### SEE ALSO * [alfresco config](config/alfresco_config.md) - Manage ACS connection details +* [alfresco group](group/alfresco_group.md) - Manage groups in ACS Repository * [alfresco node](node/alfresco_node.md) - Manage nodes in ACS Repository * [alfresco people](people/alfresco_people.md) - Manage people in ACS Repository diff --git a/docs/generate/generate.go b/docs/generate/generate.go index e89f8b6..f7d24cd 100644 --- a/docs/generate/generate.go +++ b/docs/generate/generate.go @@ -13,6 +13,7 @@ import ( "github.com/aborroy/alfresco-cli/cmd" _ "github.com/aborroy/alfresco-cli/cmd/config" + _ "github.com/aborroy/alfresco-cli/cmd/group" _ "github.com/aborroy/alfresco-cli/cmd/node" _ "github.com/aborroy/alfresco-cli/cmd/people" "github.com/spf13/cobra/doc" diff --git a/docs/group/alfresco_group.md b/docs/group/alfresco_group.md new file mode 100644 index 0000000..56f8977 --- /dev/null +++ b/docs/group/alfresco_group.md @@ -0,0 +1,37 @@ +--- +title: "alfresco group" +slug: alfresco_group +--- +## alfresco group + +Manage groups in ACS Repository + +### Synopsis + +ACS Repository handles a set of Groups that main contain another groups or persons. + +### Options + +``` + -h, --help help for group +``` + +### Options inherited from parent commands + +``` + -o, --output string Output format. E.g.: 'default', 'json' or 'id'. (default "default") + --password string Alfresco Password for the Username (overrides default stored config value) + --username string Alfresco Username (overrides default stored config value) +``` + +### SEE ALSO + +* [alfresco](../alfresco.md) - A Command Line Interface for Alfresco Content Services +* [alfresco group add](alfresco_group_add.md) - Add an authority (person or group) to a Group in repository +* [alfresco group create](alfresco_group_create.md) - Create new Group in ACS Repository +* [alfresco group delete](alfresco_group_delete.md) - Delete a Group existing in the repository +* [alfresco group get](alfresco_group_get.md) - Get Group information from repository +* [alfresco group list](alfresco_group_list.md) - Get Group list from repository +* [alfresco group sub](alfresco_group_sub.md) - Removes an authority (person or group) from a Group in repository +* [alfresco group update](alfresco_group_update.md) - Update Group properties in ACS Repository + diff --git a/docs/group/alfresco_group_add.md b/docs/group/alfresco_group_add.md new file mode 100644 index 0000000..344e8c4 --- /dev/null +++ b/docs/group/alfresco_group_add.md @@ -0,0 +1,37 @@ +--- +title: "alfresco group add" +slug: alfresco_group_add +--- +## alfresco group add + +Add an authority (person or group) to a Group in repository + +### Synopsis + +The authority is added as children of the Group. + +``` +alfresco group add [flags] +``` + +### Options + +``` + -i, --groupId string ID of the group in Alfresco Repository. + -a, --authorityId string ID of the authority (group or person) in Alfresco Repository to be added. + -t, --authorityType string Type of the authority: GROUP or PERSON. + -h, --help help for add +``` + +### Options inherited from parent commands + +``` + -o, --output string Output format. E.g.: 'default', 'json' or 'id'. (default "default") + --password string Alfresco Password for the Username (overrides default stored config value) + --username string Alfresco Username (overrides default stored config value) +``` + +### SEE ALSO + +* [alfresco group](alfresco_group.md) - Manage groups in ACS Repository + diff --git a/docs/group/alfresco_group_create.md b/docs/group/alfresco_group_create.md new file mode 100644 index 0000000..8b71e6c --- /dev/null +++ b/docs/group/alfresco_group_create.md @@ -0,0 +1,39 @@ +--- +title: "alfresco group create" +slug: alfresco_group_create +--- +## alfresco group create + +Create new Group in ACS Repository + +### Synopsis + +Creates a new group in the repository. +The group can be created setting only required properties. +When specifying parentIds, the group is created associated to those parentIds, not as a children of them. + +``` +alfresco group create [flags] +``` + +### Options + +``` + -i, --groupId string ID of the group in Alfresco Repository. + -d, --displayName string Display name of the group in Alfresco Repository. + -p, --parentIds stringArray List containing the IDs of parent groups. + -h, --help help for create +``` + +### Options inherited from parent commands + +``` + -o, --output string Output format. E.g.: 'default', 'json' or 'id'. (default "default") + --password string Alfresco Password for the Username (overrides default stored config value) + --username string Alfresco Username (overrides default stored config value) +``` + +### SEE ALSO + +* [alfresco group](alfresco_group.md) - Manage groups in ACS Repository + diff --git a/docs/group/alfresco_group_delete.md b/docs/group/alfresco_group_delete.md new file mode 100644 index 0000000..2ee00a8 --- /dev/null +++ b/docs/group/alfresco_group_delete.md @@ -0,0 +1,35 @@ +--- +title: "alfresco group delete" +slug: alfresco_group_delete +--- +## alfresco group delete + +Delete a Group existing in the repository + +### Synopsis + +Removes an existing group from the repository. + +``` +alfresco group delete [flags] +``` + +### Options + +``` + -i, --groupId string ID of the group in Alfresco Repository. + -h, --help help for delete +``` + +### Options inherited from parent commands + +``` + -o, --output string Output format. E.g.: 'default', 'json' or 'id'. (default "default") + --password string Alfresco Password for the Username (overrides default stored config value) + --username string Alfresco Username (overrides default stored config value) +``` + +### SEE ALSO + +* [alfresco group](alfresco_group.md) - Manage groups in ACS Repository + diff --git a/docs/group/alfresco_group_get.md b/docs/group/alfresco_group_get.md new file mode 100644 index 0000000..4f62433 --- /dev/null +++ b/docs/group/alfresco_group_get.md @@ -0,0 +1,36 @@ +--- +title: "alfresco group get" +slug: alfresco_group_get +--- +## alfresco group get + +Get Group information from repository + +### Synopsis + +Properties of the Group are retrieved. +Properties are provided as output of the command. + +``` +alfresco group get [flags] +``` + +### Options + +``` + -i, --groupId string ID of the group in Alfresco Repository. + -h, --help help for get +``` + +### Options inherited from parent commands + +``` + -o, --output string Output format. E.g.: 'default', 'json' or 'id'. (default "default") + --password string Alfresco Password for the Username (overrides default stored config value) + --username string Alfresco Username (overrides default stored config value) +``` + +### SEE ALSO + +* [alfresco group](alfresco_group.md) - Manage groups in ACS Repository + diff --git a/docs/group/alfresco_group_list.md b/docs/group/alfresco_group_list.md new file mode 100644 index 0000000..2a86426 --- /dev/null +++ b/docs/group/alfresco_group_list.md @@ -0,0 +1,39 @@ +--- +title: "alfresco group list" +slug: alfresco_group_list +--- +## alfresco group list + +Get Group list from repository + +### Synopsis + +Properties List is provided as output of the command. +If list elements count is greater than "maxItems" flag, output includes "HasMoreItems" field set to true. +Incrementing the "skipCount" flag on a loop will allow to retrieve all the children nodes. + +``` +alfresco group list [flags] +``` + +### Options + +``` + -i, --groupId string ID of the group in Alfresco Repository. When this parameter is omitted, group list is recovered from root node. + --skipCount int Skip a number of initial nodes from the list + --maxItems int Maximum number of nodes in the response list (max. 1000) (default -1) + -h, --help help for list +``` + +### Options inherited from parent commands + +``` + -o, --output string Output format. E.g.: 'default', 'json' or 'id'. (default "default") + --password string Alfresco Password for the Username (overrides default stored config value) + --username string Alfresco Username (overrides default stored config value) +``` + +### SEE ALSO + +* [alfresco group](alfresco_group.md) - Manage groups in ACS Repository + diff --git a/docs/group/alfresco_group_sub.md b/docs/group/alfresco_group_sub.md new file mode 100644 index 0000000..285da0f --- /dev/null +++ b/docs/group/alfresco_group_sub.md @@ -0,0 +1,36 @@ +--- +title: "alfresco group sub" +slug: alfresco_group_sub +--- +## alfresco group sub + +Removes an authority (person or group) from a Group in repository + +### Synopsis + +The authority is removed as children of the Group. + +``` +alfresco group sub [flags] +``` + +### Options + +``` + -i, --groupId string ID of the group in Alfresco Repository. + -m, --memberId string ID of the authority (group or person) in Alfresco Repository to be added. + -h, --help help for sub +``` + +### Options inherited from parent commands + +``` + -o, --output string Output format. E.g.: 'default', 'json' or 'id'. (default "default") + --password string Alfresco Password for the Username (overrides default stored config value) + --username string Alfresco Username (overrides default stored config value) +``` + +### SEE ALSO + +* [alfresco group](alfresco_group.md) - Manage groups in ACS Repository + diff --git a/docs/group/alfresco_group_update.md b/docs/group/alfresco_group_update.md new file mode 100644 index 0000000..0ea7543 --- /dev/null +++ b/docs/group/alfresco_group_update.md @@ -0,0 +1,37 @@ +--- +title: "alfresco group update" +slug: alfresco_group_update +--- +## alfresco group update + +Update Group properties in ACS Repository + +### Synopsis + +Updates an existing group in the repository. +Add only properties that require modification. + +``` +alfresco group update [flags] +``` + +### Options + +``` + -i, --groupId string ID of the group in Alfresco Repository. + -d, --displayName string Display name of the group in Alfresco Repository. + -h, --help help for update +``` + +### Options inherited from parent commands + +``` + -o, --output string Output format. E.g.: 'default', 'json' or 'id'. (default "default") + --password string Alfresco Password for the Username (overrides default stored config value) + --username string Alfresco Username (overrides default stored config value) +``` + +### SEE ALSO + +* [alfresco group](alfresco_group.md) - Manage groups in ACS Repository + diff --git a/docs/people/alfresco_people.md b/docs/people/alfresco_people.md index 314a3ae..4b9ff26 100644 --- a/docs/people/alfresco_people.md +++ b/docs/people/alfresco_people.md @@ -30,6 +30,7 @@ ACS Repository handles a set of Persons that may be associated to groups, permis * [alfresco people create](alfresco_people_create.md) - Create new Person in ACS Repository * [alfresco people delete](alfresco_people_delete.md) - Delete a Person existing in the repository * [alfresco people get](alfresco_people_get.md) - Get Person information from repository +* [alfresco people group](alfresco_people_group.md) - Get Group list for a person in repository * [alfresco people list](alfresco_people_list.md) - Get Person list from repository * [alfresco people update](alfresco_people_update.md) - Update Person properties in ACS Repository diff --git a/docs/people/alfresco_people_group.md b/docs/people/alfresco_people_group.md new file mode 100644 index 0000000..2d7e6e2 --- /dev/null +++ b/docs/people/alfresco_people_group.md @@ -0,0 +1,39 @@ +--- +title: "alfresco people group" +slug: alfresco_people_group +--- +## alfresco people group + +Get Group list for a person in repository + +### Synopsis + +Properties List is provided as output of the command. +If list elements count is greater than "maxItems" flag, output includes "HasMoreItems" field set to true. +Incrementing the "skipCount" flag on a loop will allow to retrieve all the children nodes. + +``` +alfresco people group [flags] +``` + +### Options + +``` + -i, --personId string Username of the user in Alfresco Repository. You can use the -me- string in place of to specify the currently authenticated user. + --skipCount int Skip a number of initial nodes from the list + --maxItems int Maximum number of nodes in the response list (max. 1000) (default -1) + -h, --help help for group +``` + +### Options inherited from parent commands + +``` + -o, --output string Output format. E.g.: 'default', 'json' or 'id'. (default "default") + --password string Alfresco Password for the Username (overrides default stored config value) + --username string Alfresco Username (overrides default stored config value) +``` + +### SEE ALSO + +* [alfresco people](alfresco_people.md) - Manage people in ACS Repository + diff --git a/test/test_group.sh b/test/test_group.sh new file mode 100755 index 0000000..5dc0e0f --- /dev/null +++ b/test/test_group.sh @@ -0,0 +1,73 @@ +#!/bin/bash + +set -o errexit +set -o pipefail +set -o nounset + +# Cleanup resources +function cleanup { + EXIT_CODE=$? + set +e + docker compose down + exit $EXIT_CODE +} +trap cleanup EXIT + +echo "[INTEGRATION TESTS for GROUP commands]" + +# Start Alfresco +docker compose up -d +echo "Starting Alfresco ..." +bash -c 'while [[ "$(curl -s -o /dev/null -w ''%{http_code}'' http://localhost:8080/alfresco/s/api/server)" != "200" ]]; do sleep 5; done' + +# Alfresco CLI program location +ALF="../alfresco" + +# Configure Alfresco CLI for a local ACS in port 8080 with default credentials (admin/admin) +# ACS must be up & ready before running this script +$ALF config set -s http://localhost:8080/alfresco -u admin -p admin +echo "Credentials stored" + +# Get Name for group "GROUP_ALFRESCO_ADMINISTRATORS" +ADMIN_NAME=$($ALF group list | grep GROUP_ALFRESCO_ADMINISTRATORS | awk -F ' ' '{print $2}') +echo "Retrieved admin group using "list": $ADMIN_NAME" + +if [[ "$ADMIN_NAME" != "ALFRESCO_ADMINISTRATORS" ]]; then + echo "Got $ADMIN_NAME but expecting ALFRESCO_ADMINISTRATORS" + exit -1 +fi + +# Create group "alfresco" +ALFRESCO_GROUP_ID=$($ALF group create -i GROUP_ALFRESCO -d Alfresco -o id) +echo "Created new group alfresco using "get": $ALFRESCO_GROUP_ID" + +if [[ "$ALFRESCO_GROUP_ID" != "GROUP_ALFRESCO" ]]; then + echo "Got $ALFRESCO_GROUP_ID but expecting GROUP_ALFRESCO" + exit -1 +fi + +# Modify group "alfresco" +ALFRESCO_GROUP_NAME=$($ALF group update -i GROUP_ALFRESCO -d Hyland | grep GROUP_ALFRESCO | awk -F ' ' '{print $2}') +echo "Modified group alfresco name using "update": $ALFRESCO_GROUP_NAME" +ALFRESCO_GROUP_NAME=$($ALF group get -i GROUP_ALFRESCO | grep GROUP_ALFRESCO | awk -F ' ' '{print $2}') + +if [[ "$ALFRESCO_GROUP_NAME" != "Hyland" ]]; then + echo "Got $ALFRESCO_GROUP_NAME but expecting Hyland" + exit -1 +fi + +# Add user "admin" to group "alfresco" as member +ALFRESCO_USER_NAME=$($ALF group add -i GROUP_ALFRESCO -a admin -t PERSON | grep admin | awk -F ' ' '{print $2}') +echo "Added user admin to group alfresco" + +if [[ "$ALFRESCO_USER_NAME" != "admin" ]]; then + echo "Got $ALFRESCO_USER_NAME but expecting admin" + exit -1 +fi + +# Remove group "alfresco" +$ALF group delete -i $ALFRESCO_GROUP_ID +echo "Group $ALFRESCO_GROUP_ID has been deleted" + +# Stop Alfresco +docker compose down \ No newline at end of file diff --git a/test/test_people.sh b/test/test_people.sh index 333f7a9..78c0043 100755 --- a/test/test_people.sh +++ b/test/test_people.sh @@ -56,6 +56,14 @@ if [[ "$ALFRESCO_USER_NAME" != "Hyland" ]]; then exit -1 fi +# Get groups from user "alfresco" +ALFRESCO_USER_GROUPS_COUNT=$($ALF people group -i alfresco -o id | wc -l | xargs) + +if [[ "$ALFRESCO_USER_GROUPS_COUNT" != "1" ]]; then + echo "Got $ALFRESCO_USER_GROUPS_COUNT but expecting 1" + exit -1 +fi + # Remove user "alfresco" $ALF people delete -i $ALFRESCO_USER_ID echo "Person $ALFRESCO_USER_ID has been deleted"