diff --git a/src/pkg/services/m365/api/groups.go b/src/pkg/services/m365/api/groups.go index cfccfed47..3419ad63f 100644 --- a/src/pkg/services/m365/api/groups.go +++ b/src/pkg/services/m365/api/groups.go @@ -101,6 +101,27 @@ const ( filterGroupByMailQueryTmpl = "proxyAddresses/any(a:a eq 'smtp:%s')" ) +// GetTeamByID can lookup a team by its group id. It will fail if the group +// is not a Team. +func (c Groups) GetTeamByID( + ctx context.Context, + identifier string, + _ CallConfig, // matching standards +) (models.Teamable, error) { + ctx = clues.Add(ctx, "resource_identifier", identifier) + + t, err := c.Stable.Client().Teams().ByTeamId(identifier).Get(ctx, nil) + if err != nil { + if graph.IsErrResourceLocked(err) { + return nil, graph.Stack(ctx, clues.Stack(graph.ErrResourceLocked, err)) + } + + return nil, graph.Wrap(ctx, err, "finding team by ID") + } + + return t, err +} + // GetID can look up a group by either its canonical id (a uuid) // or by the group's display name. If looking up the display name // an error will be returned if more than one group gets returned diff --git a/src/pkg/services/m365/api/groups_test.go b/src/pkg/services/m365/api/groups_test.go index f0ebc51e1..5cd2bb299 100644 --- a/src/pkg/services/m365/api/groups_test.go +++ b/src/pkg/services/m365/api/groups_test.go @@ -107,6 +107,17 @@ func (suite *GroupsIntgSuite) TestGetAll() { require.NotZero(t, len(groups), "must have at least one group") } +func (suite *GroupsIntgSuite) TestGetTeamByID() { + t := suite.T() + + ctx, flush := tester.NewContext(t) + defer flush() + + team, err := suite.its.ac.Groups().GetTeamByID(ctx, suite.its.group.id, CallConfig{}) + require.NoError(t, err, "getting team by ID") + require.NotNil(t, team, "must have valid team") +} + func (suite *GroupsIntgSuite) TestGetAllSites() { t := suite.T() @@ -238,6 +249,9 @@ func (suite *GroupsIntgSuite) TestGroups_GetByID_mockResourceLockedErrs() { interceptV1Path("groups"). Reply(403). JSON(graphTD.ParseableToMap(t, err)) + interceptV1Path("teams"). + Reply(403). + JSON(graphTD.ParseableToMap(t, err)) }, }, { @@ -249,6 +263,9 @@ func (suite *GroupsIntgSuite) TestGroups_GetByID_mockResourceLockedErrs() { interceptV1Path("groups", gID). Reply(403). JSON(graphTD.ParseableToMap(t, err)) + interceptV1Path("teams", gID). + Reply(403). + JSON(graphTD.ParseableToMap(t, err)) }, }, { @@ -266,6 +283,9 @@ func (suite *GroupsIntgSuite) TestGroups_GetByID_mockResourceLockedErrs() { interceptV1Path("groups", gID). Reply(403). JSON(graphTD.ParseableToMap(t, err)) + interceptV1Path("teams", gID). + Reply(403). + JSON(graphTD.ParseableToMap(t, err)) }, }, } @@ -280,10 +300,16 @@ func (suite *GroupsIntgSuite) TestGroups_GetByID_mockResourceLockedErrs() { test.setup(t) + // Verify both GetByID and GetTeamByID APIs handle this error _, err := suite.its.gockAC. Groups(). GetByID(ctx, test.id, CallConfig{}) require.ErrorIs(t, err, graph.ErrResourceLocked, clues.ToCore(err)) + + _, err = suite.its.gockAC. + Groups(). + GetTeamByID(ctx, test.id, CallConfig{}) + require.ErrorIs(t, err, graph.ErrResourceLocked, clues.ToCore(err)) }) } }