From 19ec4152f424246d35597d3c61f1e6fb6bffa4fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dawid=20G=C3=B3rski?= Date: Fri, 27 Aug 2021 14:15:20 +0200 Subject: [PATCH 1/9] added more methods --- GraphClient.go | 29 +++++++++++++++++++++++++++++ Group.go | 19 +++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/GraphClient.go b/GraphClient.go index 69ecb27..410b655 100644 --- a/GraphClient.go +++ b/GraphClient.go @@ -132,6 +132,11 @@ func (g *GraphClient) refreshToken() error { return err } +// returns client Token +func (g *GraphClient) GetToken() Token { + return g.token +} + // makeGETAPICall performs an API-Call to the msgraph API. func (g *GraphClient) makeGETAPICall(apiCall string, reqParams getRequestParams, v interface{}) error { return g.makeAPICall(apiCall, http.MethodGet, reqParams, nil, v) @@ -266,6 +271,30 @@ func (g *GraphClient) ListGroups(opts ...ListQueryOption) (Groups, error) { return marsh.Groups, err } +// ListUserGroups returns a list of all group ids the user is a member of +// You can specify the securityGroupsEnabeled parameter to only return security group ids +// Reference: https://docs.microsoft.com/en-us/graph/api/directoryobject-getmembergroups?view=graph-rest-1.0&tabs=http +func (g *GraphClient) ListUserGroups(identifier string, securityGroupsEnabeled bool) ([]string, error) { + resource := fmt.Sprintf("/users/%v/getMemberGroups", identifier) + var post struct { + SecurityEnabledOnly bool `json:"securityEnabledOnly"` + } + var marsh struct { + Groups []string `json:"value"` + } + post.SecurityEnabledOnly = securityGroupsEnabeled + bodyBytes, err := json.Marshal(post) + if err != nil { + return marsh.Groups, err + } + body := bytes.NewReader(bodyBytes) + //Query Options not supported + reqParams := compileListQueryOptions(nil) + + err = g.makePOSTAPICall(resource, reqParams, body, &marsh) + return marsh.Groups, err +} + // GetUser returns the user object associated to the given user identified by either // the given ID or userPrincipalName // Supports optional OData query parameters https://docs.microsoft.com/en-us/graph/query-parameters diff --git a/Group.go b/Group.go index f6ab86a..5faed6e 100644 --- a/Group.go +++ b/Group.go @@ -57,6 +57,25 @@ func (g Group) ListMembers(opts ...ListQueryOption) (Users, error) { return marsh.Users, g.graphClient.makeGETAPICall(resource, compileListQueryOptions(opts), &marsh) } +// Get a list of the group's members. A group can have users, devices, organizational contacts, and other groups as members. +// This operation is transitive and returns a flat list of all nested members. +// Supports optional OData query parameters https://docs.microsoft.com/en-us/graph/query-parameters +// +// See https://docs.microsoft.com/en-us/graph/api/group-list-transitivemembers?view=graph-rest-1.0&tabs=http +func (g Group) ListTransitiveMembers(opts ...ListQueryOption) (Users, error) { + if g.graphClient == nil { + return nil, ErrNotGraphClientSourced + } + resource := fmt.Sprintf("/groups/%v/transitiveMembers", g.ID) + + var marsh struct { + Users Users `json:"value"` + } + marsh.Users.setGraphClient(g.graphClient) + return marsh.Users, g.graphClient.makeGETAPICall(resource, compileListQueryOptions(opts), &marsh) +} + + // UnmarshalJSON implements the json unmarshal to be used by the json-library func (g *Group) UnmarshalJSON(data []byte) error { tmp := struct { From 0dd649bff8ddfde733e8866556d080755460b509 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dawid=20G=C3=B3rski?= Date: Mon, 6 Sep 2021 09:33:19 +0200 Subject: [PATCH 2/9] made requested changes --- GraphClient.go | 9 ++++++--- Group.go | 2 +- User.go | 9 +++++++++ User_test.go | 42 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 58 insertions(+), 4 deletions(-) diff --git a/GraphClient.go b/GraphClient.go index 410b655..a087f25 100644 --- a/GraphClient.go +++ b/GraphClient.go @@ -5,6 +5,7 @@ package msgraph import ( "bytes" + "context" "encoding/json" "fmt" "io" @@ -271,10 +272,11 @@ func (g *GraphClient) ListGroups(opts ...ListQueryOption) (Groups, error) { return marsh.Groups, err } -// ListUserGroups returns a list of all group ids the user is a member of +// getMemberGroups returns a list of all group ids the user is a member of // You can specify the securityGroupsEnabeled parameter to only return security group ids +// // Reference: https://docs.microsoft.com/en-us/graph/api/directoryobject-getmembergroups?view=graph-rest-1.0&tabs=http -func (g *GraphClient) ListUserGroups(identifier string, securityGroupsEnabeled bool) ([]string, error) { +func (g *GraphClient) getMemberGroups(identifier string, ctx context.Context, securityGroupsEnabeled bool) ([]string, error) { resource := fmt.Sprintf("/users/%v/getMemberGroups", identifier) var post struct { SecurityEnabledOnly bool `json:"securityEnabledOnly"` @@ -290,7 +292,8 @@ func (g *GraphClient) ListUserGroups(identifier string, securityGroupsEnabeled b body := bytes.NewReader(bodyBytes) //Query Options not supported reqParams := compileListQueryOptions(nil) - + reqParams.ctx = ctx + err = g.makePOSTAPICall(resource, reqParams, body, &marsh) return marsh.Groups, err } diff --git a/Group.go b/Group.go index 5faed6e..7c8f102 100644 --- a/Group.go +++ b/Group.go @@ -59,6 +59,7 @@ func (g Group) ListMembers(opts ...ListQueryOption) (Users, error) { // Get a list of the group's members. A group can have users, devices, organizational contacts, and other groups as members. // This operation is transitive and returns a flat list of all nested members. +// This method will currently ONLY return User-instances of members // Supports optional OData query parameters https://docs.microsoft.com/en-us/graph/query-parameters // // See https://docs.microsoft.com/en-us/graph/api/group-list-transitivemembers?view=graph-rest-1.0&tabs=http @@ -75,7 +76,6 @@ func (g Group) ListTransitiveMembers(opts ...ListQueryOption) (Users, error) { return marsh.Users, g.graphClient.makeGETAPICall(resource, compileListQueryOptions(opts), &marsh) } - // UnmarshalJSON implements the json unmarshal to be used by the json-library func (g *Group) UnmarshalJSON(data []byte) error { tmp := struct { diff --git a/User.go b/User.go index e7d3603..354860a 100644 --- a/User.go +++ b/User.go @@ -2,6 +2,7 @@ package msgraph import ( "bytes" + "context" "encoding/json" "fmt" "strings" @@ -145,6 +146,14 @@ func (u User) GetFullName() string { return fmt.Sprintf("%v %v", u.GivenName, u.Surname) } +// GetMemberGroupsAsStrings returns a list of all group ids the user is a member of +// You can specify the securityGroupsEnabeled parameter to only return security group ids +// +// Reference: https://docs.microsoft.com/en-us/graph/api/directoryobject-getmembergroups?view=graph-rest-1.0&tabs=http +func (u User) GetMemberGroupsAsStrings(ctx context.Context, securityGroupsEnabeled bool) ([]string, error) { + return u.graphClient.getMemberGroups(u.ID, ctx, securityGroupsEnabeled) +} + // UpdateUser patches this user object. Note, only set the fields that should be changed. // // IMPORTANT: the user cannot be disabled (field AccountEnabled) this way, because the diff --git a/User_test.go b/User_test.go index 4e719da..743d8f8 100644 --- a/User_test.go +++ b/User_test.go @@ -1,7 +1,9 @@ package msgraph import ( + "context" "fmt" + "reflect" "testing" "time" ) @@ -158,3 +160,43 @@ func TestUser_String(t *testing.T) { } }) } + +func TestUser_GetMemberGroupsAsStrings(t *testing.T) { + u := GetTestUser(t) + type args struct { + ctx context.Context + securityGroupsEnabeled bool + } + tests := []struct { + name string + u User + args args + want []string + wantErr bool + }{ + { + name: "Test user func GetMembershipGroupsAsStrings", + u: u, + args: args{ctx: context.Background(), securityGroupsEnabeled: true}, + wantErr: false, + }, + { + name: "User not initialized by GraphClient", + args: args{ctx: context.Background(), securityGroupsEnabeled: true}, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + + got, err := u.GetMemberGroupsAsStrings(tt.args.ctx, tt.args.securityGroupsEnabeled) + if (err != nil) != tt.wantErr { + t.Errorf("User.GetMemberGroupsAsStrings() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("User.GetMemberGroupsAsStrings() = %v, want %v", got, tt.want) + } + }) + } +} From 5df098fa3926fa88ff4a67b8a676df09aeb4ef22 Mon Sep 17 00:00:00 2001 From: Felix Hartung <7132415+TerraTalpi@users.noreply.github.com> Date: Tue, 14 Dec 2021 12:59:59 +0000 Subject: [PATCH 3/9] GraphClient: update code doc for GetToken and getMemberGroups --- GraphClient.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/GraphClient.go b/GraphClient.go index 4146b7f..25b71d8 100644 --- a/GraphClient.go +++ b/GraphClient.go @@ -133,7 +133,7 @@ func (g *GraphClient) refreshToken() error { return err } -// returns client Token +// GetToken returns a copy the currently token used by this GraphClient instance. func (g *GraphClient) GetToken() Token { return g.token } @@ -362,8 +362,8 @@ func (g *GraphClient) ListGroups(opts ...ListQueryOption) (Groups, error) { return marsh.Groups, err } -// getMemberGroups returns a list of all group ids the user is a member of -// You can specify the securityGroupsEnabeled parameter to only return security group ids +// getMemberGroups returns a list of all group IDs the user is a member of. +// You can specify the securityGroupsEnabled parameter to only return security group IDs. // // Reference: https://docs.microsoft.com/en-us/graph/api/directoryobject-getmembergroups?view=graph-rest-1.0&tabs=http func (g *GraphClient) getMemberGroups(identifier string, ctx context.Context, securityGroupsEnabeled bool) ([]string, error) { From 00630864dcf3a6db028665ac02fbef14644730cc Mon Sep 17 00:00:00 2001 From: Felix Hartung <7132415+TerraTalpi@users.noreply.github.com> Date: Tue, 14 Dec 2021 13:00:32 +0000 Subject: [PATCH 4/9] User: fix GetMemberGroupsAsStrings and corresponding unit test --- User.go | 3 +++ User_test.go | 11 ++++------- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/User.go b/User.go index 80901c0..1967343 100644 --- a/User.go +++ b/User.go @@ -151,6 +151,9 @@ func (u User) GetFullName() string { // // Reference: https://docs.microsoft.com/en-us/graph/api/directoryobject-getmembergroups?view=graph-rest-1.0&tabs=http func (u User) GetMemberGroupsAsStrings(ctx context.Context, securityGroupsEnabeled bool) ([]string, error) { + if u.graphClient == nil { + return nil, ErrNotGraphClientSourced + } return u.graphClient.getMemberGroups(u.ID, ctx, securityGroupsEnabeled) } diff --git a/User_test.go b/User_test.go index b8ab972..b9ad864 100644 --- a/User_test.go +++ b/User_test.go @@ -3,7 +3,6 @@ package msgraph import ( "context" "fmt" - "reflect" "testing" "time" ) @@ -178,7 +177,6 @@ func TestUser_GetMemberGroupsAsStrings(t *testing.T) { name string u User args args - want []string wantErr bool }{ { @@ -195,17 +193,16 @@ func TestUser_GetMemberGroupsAsStrings(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - - got, err := u.GetMemberGroupsAsStrings(tt.args.ctx, tt.args.securityGroupsEnabeled) + got, err := tt.u.GetMemberGroupsAsStrings(tt.args.ctx, tt.args.securityGroupsEnabeled) if (err != nil) != tt.wantErr { t.Errorf("User.GetMemberGroupsAsStrings() error = %v, wantErr %v", err, tt.wantErr) return } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("User.GetMemberGroupsAsStrings() = %v, want %v", got, tt.want) + if !tt.wantErr && len(got) == 0 { + t.Errorf("User.GetMemberGroupsAsStrings() = %v, want at least one value", got) } }) - } + } } func TestUser_UpdateUser(t *testing.T) { From 99072e2832be5e559e15c232d1187379f1abb9e3 Mon Sep 17 00:00:00 2001 From: Felix Hartung <7132415+TerraTalpi@users.noreply.github.com> Date: Tue, 14 Dec 2021 13:14:50 +0000 Subject: [PATCH 5/9] Group: add unit test for ListTransitiveMembers --- Group_test.go | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/Group_test.go b/Group_test.go index dbd6031..196dc83 100644 --- a/Group_test.go +++ b/Group_test.go @@ -82,3 +82,35 @@ func TestGroup_String(t *testing.T) { }) } } + +func TestGroup_ListTransitiveMembers(t *testing.T) { + testGroup := GetTestGroup(t) + + tests := []struct { + name string + g Group + wantErr bool + }{ + { + name: "GraphClient created Group", + g: testGroup, + wantErr: false, + }, { + name: "Not GraphClient created Group", + g: Group{DisplayName: "Test not GraphClient sourced"}, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := tt.g.ListTransitiveMembers() + if (err != nil) != tt.wantErr { + t.Errorf("Group.ListTransitiveMembers() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !tt.wantErr && len(got) == 0 { + t.Errorf("Group.ListTransitiveMembers() = %v, want at least one member of that group", got) + } + }) + } +} From b312cdabefc24dea9f728d0997c798252739f03f Mon Sep 17 00:00:00 2001 From: Felix Hartung <7132415+TerraTalpi@users.noreply.github.com> Date: Tue, 14 Dec 2021 14:24:29 +0000 Subject: [PATCH 6/9] GraphClient: let getMemberGroups use getQueryOptions instead of static context --- GraphClient.go | 8 ++------ User.go | 11 ++++++----- User_test.go | 40 ++++++++++++++++++++++------------------ 3 files changed, 30 insertions(+), 29 deletions(-) diff --git a/GraphClient.go b/GraphClient.go index 25b71d8..355ee8c 100644 --- a/GraphClient.go +++ b/GraphClient.go @@ -5,7 +5,6 @@ package msgraph import ( "bytes" - "context" "encoding/json" "fmt" "io" @@ -366,7 +365,7 @@ func (g *GraphClient) ListGroups(opts ...ListQueryOption) (Groups, error) { // You can specify the securityGroupsEnabled parameter to only return security group IDs. // // Reference: https://docs.microsoft.com/en-us/graph/api/directoryobject-getmembergroups?view=graph-rest-1.0&tabs=http -func (g *GraphClient) getMemberGroups(identifier string, ctx context.Context, securityGroupsEnabeled bool) ([]string, error) { +func (g *GraphClient) getMemberGroups(identifier string, securityGroupsEnabeled bool, opts *getQueryOptions) ([]string, error) { resource := fmt.Sprintf("/users/%v/getMemberGroups", identifier) var post struct { SecurityEnabledOnly bool `json:"securityEnabledOnly"` @@ -380,11 +379,8 @@ func (g *GraphClient) getMemberGroups(identifier string, ctx context.Context, se return marsh.Groups, err } body := bytes.NewReader(bodyBytes) - //Query Options not supported - reqParams := compileListQueryOptions(nil) - reqParams.ctx = ctx - err = g.makePOSTAPICall(resource, reqParams, body, &marsh) + err = g.makePOSTAPICall(resource, opts, body, &marsh) return marsh.Groups, err } diff --git a/User.go b/User.go index 1967343..afe7464 100644 --- a/User.go +++ b/User.go @@ -2,7 +2,6 @@ package msgraph import ( "bytes" - "context" "encoding/json" "fmt" "strings" @@ -146,15 +145,17 @@ func (u User) GetFullName() string { return fmt.Sprintf("%v %v", u.GivenName, u.Surname) } -// GetMemberGroupsAsStrings returns a list of all group ids the user is a member of -// You can specify the securityGroupsEnabeled parameter to only return security group ids +// GetMemberGroupsAsStrings returns a list of all group IDs the user is a member of. +// You can specify the securityGroupsEnabeled parameter to only return security group IDs. +// +// opts ...GetQueryOption - only msgraph.GetWithContext is supported. // // Reference: https://docs.microsoft.com/en-us/graph/api/directoryobject-getmembergroups?view=graph-rest-1.0&tabs=http -func (u User) GetMemberGroupsAsStrings(ctx context.Context, securityGroupsEnabeled bool) ([]string, error) { +func (u User) GetMemberGroupsAsStrings(securityGroupsEnabeled bool, opts ...GetQueryOption) ([]string, error) { if u.graphClient == nil { return nil, ErrNotGraphClientSourced } - return u.graphClient.getMemberGroups(u.ID, ctx, securityGroupsEnabeled) + return u.graphClient.getMemberGroups(u.ID, securityGroupsEnabeled, compileGetQueryOptions(opts)) } // PrettySimpleString returns the User-instance simply formatted for logging purposes: {FullName (email) (activePhone)} diff --git a/User_test.go b/User_test.go index b9ad864..1baf34c 100644 --- a/User_test.go +++ b/User_test.go @@ -1,7 +1,6 @@ package msgraph import ( - "context" "fmt" "testing" "time" @@ -169,37 +168,42 @@ func TestUser_String(t *testing.T) { func TestUser_GetMemberGroupsAsStrings(t *testing.T) { u := GetTestUser(t) - type args struct { - ctx context.Context - securityGroupsEnabeled bool - } tests := []struct { - name string - u User - args args - wantErr bool + name string + u User + securityGroupsEnabeled bool + opt GetQueryOption + wantErr bool }{ { - name: "Test user func GetMembershipGroupsAsStrings", - u: u, - args: args{ctx: context.Background(), securityGroupsEnabeled: true}, - wantErr: false, + name: "Test user func GetMembershipGroupsAsStrings", + u: u, + securityGroupsEnabeled: true, + opt: GetWithContext(nil), + wantErr: false, + }, { + name: "Test user func GetMembershipGroupsAsStrings - no securityGroupsEnabeledF", + u: u, + securityGroupsEnabeled: false, + opt: GetWithContext(nil), + wantErr: false, }, { - name: "User not initialized by GraphClient", - args: args{ctx: context.Background(), securityGroupsEnabeled: true}, - wantErr: true, + name: "User not initialized by GraphClient", + securityGroupsEnabeled: true, + opt: GetWithContext(nil), + wantErr: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := tt.u.GetMemberGroupsAsStrings(tt.args.ctx, tt.args.securityGroupsEnabeled) + got, err := tt.u.GetMemberGroupsAsStrings(tt.securityGroupsEnabeled, tt.opt) if (err != nil) != tt.wantErr { t.Errorf("User.GetMemberGroupsAsStrings() error = %v, wantErr %v", err, tt.wantErr) return } if !tt.wantErr && len(got) == 0 { - t.Errorf("User.GetMemberGroupsAsStrings() = %v, want at least one value", got) + t.Errorf("User.GetMemberGroupsAsStrings() = %v, len(%d), want at least one value", got, len(got)) } }) } From 05fa1b99e138817578afd382eecdc4e44852478a Mon Sep 17 00:00:00 2001 From: Felix Hartung <7132415+TerraTalpi@users.noreply.github.com> Date: Tue, 14 Dec 2021 14:32:38 +0000 Subject: [PATCH 7/9] GraphClient.getMemberGroups: use opts ...GetQueryOption instead of already compiled list --- GraphClient.go | 4 ++-- User.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/GraphClient.go b/GraphClient.go index 355ee8c..c443fbb 100644 --- a/GraphClient.go +++ b/GraphClient.go @@ -365,7 +365,7 @@ func (g *GraphClient) ListGroups(opts ...ListQueryOption) (Groups, error) { // You can specify the securityGroupsEnabled parameter to only return security group IDs. // // Reference: https://docs.microsoft.com/en-us/graph/api/directoryobject-getmembergroups?view=graph-rest-1.0&tabs=http -func (g *GraphClient) getMemberGroups(identifier string, securityGroupsEnabeled bool, opts *getQueryOptions) ([]string, error) { +func (g *GraphClient) getMemberGroups(identifier string, securityGroupsEnabeled bool, opts ...GetQueryOption) ([]string, error) { resource := fmt.Sprintf("/users/%v/getMemberGroups", identifier) var post struct { SecurityEnabledOnly bool `json:"securityEnabledOnly"` @@ -380,7 +380,7 @@ func (g *GraphClient) getMemberGroups(identifier string, securityGroupsEnabeled } body := bytes.NewReader(bodyBytes) - err = g.makePOSTAPICall(resource, opts, body, &marsh) + err = g.makePOSTAPICall(resource, compileGetQueryOptions(opts), body, &marsh) return marsh.Groups, err } diff --git a/User.go b/User.go index afe7464..5e28d7d 100644 --- a/User.go +++ b/User.go @@ -155,7 +155,7 @@ func (u User) GetMemberGroupsAsStrings(securityGroupsEnabeled bool, opts ...GetQ if u.graphClient == nil { return nil, ErrNotGraphClientSourced } - return u.graphClient.getMemberGroups(u.ID, securityGroupsEnabeled, compileGetQueryOptions(opts)) + return u.graphClient.getMemberGroups(u.ID, securityGroupsEnabeled, opts...) } // PrettySimpleString returns the User-instance simply formatted for logging purposes: {FullName (email) (activePhone)} From 6d480b1b49449822bd5d7eed9ed3bd9240591d0d Mon Sep 17 00:00:00 2001 From: Felix Hartung <7132415+TerraTalpi@users.noreply.github.com> Date: Tue, 14 Dec 2021 17:04:27 +0000 Subject: [PATCH 8/9] Group: Add GetMemberGroupAsStrings func --- GraphClient.go | 6 +++--- Group.go | 12 ++++++++++++ Group_test.go | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 3 deletions(-) diff --git a/GraphClient.go b/GraphClient.go index c443fbb..d829bf0 100644 --- a/GraphClient.go +++ b/GraphClient.go @@ -365,15 +365,15 @@ func (g *GraphClient) ListGroups(opts ...ListQueryOption) (Groups, error) { // You can specify the securityGroupsEnabled parameter to only return security group IDs. // // Reference: https://docs.microsoft.com/en-us/graph/api/directoryobject-getmembergroups?view=graph-rest-1.0&tabs=http -func (g *GraphClient) getMemberGroups(identifier string, securityGroupsEnabeled bool, opts ...GetQueryOption) ([]string, error) { - resource := fmt.Sprintf("/users/%v/getMemberGroups", identifier) +func (g *GraphClient) getMemberGroups(identifier string, securityEnabledOnly bool, opts ...GetQueryOption) ([]string, error) { + resource := fmt.Sprintf("/directoryObjects/%v/getMemberGroups", identifier) var post struct { SecurityEnabledOnly bool `json:"securityEnabledOnly"` } var marsh struct { Groups []string `json:"value"` } - post.SecurityEnabledOnly = securityGroupsEnabeled + post.SecurityEnabledOnly = securityEnabledOnly bodyBytes, err := json.Marshal(post) if err != nil { return marsh.Groups, err diff --git a/Group.go b/Group.go index 7c8f102..96df753 100644 --- a/Group.go +++ b/Group.go @@ -76,6 +76,18 @@ func (g Group) ListTransitiveMembers(opts ...ListQueryOption) (Users, error) { return marsh.Users, g.graphClient.makeGETAPICall(resource, compileListQueryOptions(opts), &marsh) } +// GetMemberGroupsAsStrings returns a list of all group IDs the user is a member of. +// +// opts ...GetQueryOption - only msgraph.GetWithContext is supported. +// +// Reference: https://docs.microsoft.com/en-us/graph/api/directoryobject-getmembergroups?view=graph-rest-1.0&tabs=http +func (g Group) GetMemberGroupsAsStrings(opts ...GetQueryOption) ([]string, error) { + if g.graphClient == nil { + return nil, ErrNotGraphClientSourced + } + return g.graphClient.getMemberGroups(g.ID, false, opts...) // securityEnabledOnly is not supported for Groups, see documentation / API-reference +} + // UnmarshalJSON implements the json unmarshal to be used by the json-library func (g *Group) UnmarshalJSON(data []byte) error { tmp := struct { diff --git a/Group_test.go b/Group_test.go index 196dc83..fefa8f7 100644 --- a/Group_test.go +++ b/Group_test.go @@ -114,3 +114,40 @@ func TestGroup_ListTransitiveMembers(t *testing.T) { }) } } + +func TestGroup_GetMemberGroupsAsStrings(t *testing.T) { + testGroup := GetTestGroup(t) + + tests := []struct { + name string + g Group + opts []GetQueryOption + wantErr bool + }{ + { + name: "Test group func GetMembershipGroupsAsStrings", + g: testGroup, + wantErr: false, + }, { + name: "Test group func GetMembershipGroupsAsStrings - no securityGroupsEnabeledF", + g: testGroup, + wantErr: false, + }, + { + name: "Group not initialized by GraphClient", + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := tt.g.GetMemberGroupsAsStrings(tt.opts...) + if (err != nil) != tt.wantErr { + t.Errorf("Group.GetMemberGroupsAsStrings() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !tt.wantErr && len(got) == 0 { + t.Errorf("Group.GetMemberGroupsAsStrings() = %v, len(%d), want at least one value", got, len(got)) + } + }) + } +} From 8f88e00c145b5ed47e6273033b7f46e6cca430a3 Mon Sep 17 00:00:00 2001 From: Felix Hartung <7132415+TerraTalpi@users.noreply.github.com> Date: Tue, 14 Dec 2021 17:05:03 +0000 Subject: [PATCH 9/9] Group_test: enhance unit test ListTransitiveMembers error message --- Group_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Group_test.go b/Group_test.go index fefa8f7..14276f0 100644 --- a/Group_test.go +++ b/Group_test.go @@ -109,7 +109,7 @@ func TestGroup_ListTransitiveMembers(t *testing.T) { return } if !tt.wantErr && len(got) == 0 { - t.Errorf("Group.ListTransitiveMembers() = %v, want at least one member of that group", got) + t.Errorf("Group.ListTransitiveMembers() = %v, len(%d), want at least one member of that group", got, len(got)) } }) }