use teams API
This commit is contained in:
parent
b2f0870c27
commit
ae0d0f6684
@ -1,165 +0,0 @@
|
|||||||
package api
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/alcionai/clues"
|
|
||||||
msgraphgocore "github.com/microsoftgraph/msgraph-sdk-go-core"
|
|
||||||
"github.com/microsoftgraph/msgraph-sdk-go/models"
|
|
||||||
|
|
||||||
"github.com/alcionai/corso/src/internal/common/str"
|
|
||||||
"github.com/alcionai/corso/src/internal/common/tform"
|
|
||||||
"github.com/alcionai/corso/src/internal/m365/graph"
|
|
||||||
"github.com/alcionai/corso/src/pkg/fault"
|
|
||||||
"github.com/alcionai/corso/src/pkg/logger"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
teamsAdditionalDataLabel = "Team"
|
|
||||||
ResourceProvisioningOptions = "resourceProvisioningOptions"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// controller
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
func (c Client) Teams() Teams {
|
|
||||||
return Teams{c}
|
|
||||||
}
|
|
||||||
|
|
||||||
// On creation of each Teams team a corrsponding group gets created.
|
|
||||||
// The group acts as the protected resource, and all teams data like events,
|
|
||||||
// drive and mail messages are owned by that group.
|
|
||||||
|
|
||||||
// Teams is an interface-compliant provider of the client.
|
|
||||||
type Teams struct {
|
|
||||||
Client
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetAllTeams retrieves all groups.
|
|
||||||
func (c Teams) GetAll(
|
|
||||||
ctx context.Context,
|
|
||||||
errs *fault.Bus,
|
|
||||||
) ([]models.Groupable, error) {
|
|
||||||
service, err := c.Service()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return getGroups(ctx, true, errs, service)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetAll retrieves all groups.
|
|
||||||
func getGroups(
|
|
||||||
ctx context.Context,
|
|
||||||
getOnlyTeams bool,
|
|
||||||
errs *fault.Bus,
|
|
||||||
service graph.Servicer,
|
|
||||||
) ([]models.Groupable, error) {
|
|
||||||
resp, err := service.Client().Groups().Get(ctx, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, graph.Wrap(ctx, err, "getting all groups")
|
|
||||||
}
|
|
||||||
|
|
||||||
iter, err := msgraphgocore.NewPageIterator[models.Groupable](
|
|
||||||
resp,
|
|
||||||
service.Adapter(),
|
|
||||||
models.CreateTeamCollectionResponseFromDiscriminatorValue)
|
|
||||||
if err != nil {
|
|
||||||
return nil, graph.Wrap(ctx, err, "creating groups iterator")
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
groups = make([]models.Groupable, 0)
|
|
||||||
el = errs.Local()
|
|
||||||
)
|
|
||||||
|
|
||||||
iterator := func(item models.Groupable) bool {
|
|
||||||
if el.Failure() != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
err := ValidateGroup(item)
|
|
||||||
if err != nil {
|
|
||||||
el.AddRecoverable(ctx, graph.Wrap(ctx, err, "validating groups"))
|
|
||||||
} else {
|
|
||||||
isTeam := IsTeam(ctx, item)
|
|
||||||
if !getOnlyTeams || isTeam {
|
|
||||||
groups = append(groups, item)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := iter.Iterate(ctx, iterator); err != nil {
|
|
||||||
return nil, graph.Wrap(ctx, err, "iterating all groups")
|
|
||||||
}
|
|
||||||
|
|
||||||
return groups, el.Failure()
|
|
||||||
}
|
|
||||||
|
|
||||||
func IsTeam(ctx context.Context, g models.Groupable) bool {
|
|
||||||
log := logger.Ctx(ctx)
|
|
||||||
|
|
||||||
if g.GetAdditionalData()[ResourceProvisioningOptions] != nil {
|
|
||||||
val, _ := tform.AnyValueToT[[]any](ResourceProvisioningOptions, g.GetAdditionalData())
|
|
||||||
for _, v := range val {
|
|
||||||
s, err := str.AnyToString(v)
|
|
||||||
if err != nil {
|
|
||||||
log.Debug("could not be converted to string value: ", ResourceProvisioningOptions)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if s == teamsAdditionalDataLabel {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetID retrieves team by groupID/teamID.
|
|
||||||
func (c Teams) GetByID(
|
|
||||||
ctx context.Context,
|
|
||||||
identifier string,
|
|
||||||
) (models.Groupable, error) {
|
|
||||||
service, err := c.Service()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := service.Client().Groups().ByGroupId(identifier).Get(ctx, nil)
|
|
||||||
if err != nil {
|
|
||||||
err := graph.Wrap(ctx, err, "getting group by id")
|
|
||||||
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if !IsTeam(ctx, resp) {
|
|
||||||
err := clues.New("given teamID is not related to any team")
|
|
||||||
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return resp, graph.Stack(ctx, err).OrNil()
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// helpers
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// ValidateGroup ensures the item is a Groupable, and contains the necessary
|
|
||||||
// identifiers that we handle with all groups.
|
|
||||||
func ValidateGroup(item models.Groupable) error {
|
|
||||||
if item.GetId() == nil {
|
|
||||||
return clues.New("missing ID")
|
|
||||||
}
|
|
||||||
|
|
||||||
if item.GetDisplayName() == nil {
|
|
||||||
return clues.New("missing display name")
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
113
src/pkg/services/m365/api/teams.go
Normal file
113
src/pkg/services/m365/api/teams.go
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/alcionai/clues"
|
||||||
|
msgraphgocore "github.com/microsoftgraph/msgraph-sdk-go-core"
|
||||||
|
"github.com/microsoftgraph/msgraph-sdk-go/models"
|
||||||
|
|
||||||
|
"github.com/alcionai/corso/src/internal/m365/graph"
|
||||||
|
"github.com/alcionai/corso/src/pkg/fault"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// controller
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
func (c Client) Teams() Teams {
|
||||||
|
return Teams{c}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Teams is an interface-compliant provider of the client.
|
||||||
|
type Teams struct {
|
||||||
|
Client
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAllTeams retrieves all teams.
|
||||||
|
func (c Teams) GetAll(
|
||||||
|
ctx context.Context,
|
||||||
|
errs *fault.Bus,
|
||||||
|
) ([]models.Teamable, error) {
|
||||||
|
service, err := c.Service()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := service.Client().Teams().Get(ctx, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, graph.Wrap(ctx, err, "getting all teams")
|
||||||
|
}
|
||||||
|
|
||||||
|
iter, err := msgraphgocore.NewPageIterator[models.Teamable](
|
||||||
|
resp,
|
||||||
|
service.Adapter(),
|
||||||
|
models.CreateTeamCollectionResponseFromDiscriminatorValue)
|
||||||
|
if err != nil {
|
||||||
|
return nil, graph.Wrap(ctx, err, "creating teams iterator")
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
teams = make([]models.Teamable, 0)
|
||||||
|
el = errs.Local()
|
||||||
|
)
|
||||||
|
|
||||||
|
iterator := func(item models.Teamable) bool {
|
||||||
|
if el.Failure() != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
err := ValidateTeams(item)
|
||||||
|
if err != nil {
|
||||||
|
el.AddRecoverable(ctx, graph.Wrap(ctx, err, "validating teams"))
|
||||||
|
} else {
|
||||||
|
teams = append(teams, item)
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := iter.Iterate(ctx, iterator); err != nil {
|
||||||
|
return nil, graph.Wrap(ctx, err, "iterating all teams")
|
||||||
|
}
|
||||||
|
|
||||||
|
return teams, el.Failure()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetID retrieves team by teamID.
|
||||||
|
func (c Teams) GetByID(
|
||||||
|
ctx context.Context,
|
||||||
|
identifier string,
|
||||||
|
) (models.Teamable, error) {
|
||||||
|
service, err := c.Service()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := service.Client().Teams().ByTeamId(identifier).Get(ctx, nil)
|
||||||
|
if err != nil {
|
||||||
|
err := graph.Wrap(ctx, err, "getting team by id")
|
||||||
|
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp, graph.Stack(ctx, err).OrNil()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// helpers
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// ValidateTeams ensures the item is a Teamable, and contains the necessary
|
||||||
|
// identifiers that we handle with all teams.
|
||||||
|
func ValidateTeams(item models.Teamable) error {
|
||||||
|
if item.GetId() == nil {
|
||||||
|
return clues.New("missing ID")
|
||||||
|
}
|
||||||
|
|
||||||
|
if item.GetDisplayName() == nil {
|
||||||
|
return clues.New("missing display name")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@ -25,21 +25,21 @@ func TestTeamsUnitSuite(t *testing.T) {
|
|||||||
suite.Run(t, &TeamsUnitSuite{Suite: tester.NewUnitSuite(t)})
|
suite.Run(t, &TeamsUnitSuite{Suite: tester.NewUnitSuite(t)})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *TeamsUnitSuite) TestValidateGroup() {
|
func (suite *TeamsUnitSuite) TestValidateTeams() {
|
||||||
team := models.NewTeam()
|
team := models.NewTeam()
|
||||||
team.SetDisplayName(ptr.To("testgroup"))
|
team.SetDisplayName(ptr.To("testteam"))
|
||||||
team.SetId(ptr.To("testID"))
|
team.SetId(ptr.To("testID"))
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
args models.Groupable
|
args models.Teamable
|
||||||
errCheck assert.ErrorAssertionFunc
|
errCheck assert.ErrorAssertionFunc
|
||||||
errIsSkippable bool
|
errIsSkippable bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "Valid group ",
|
name: "Valid Team",
|
||||||
args: func() *models.Group {
|
args: func() *models.Team {
|
||||||
s := models.NewGroup()
|
s := models.NewTeam()
|
||||||
s.SetId(ptr.To("id"))
|
s.SetId(ptr.To("id"))
|
||||||
s.SetDisplayName(ptr.To("testTeam"))
|
s.SetDisplayName(ptr.To("testTeam"))
|
||||||
return s
|
return s
|
||||||
@ -48,8 +48,8 @@ func (suite *TeamsUnitSuite) TestValidateGroup() {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "No name",
|
name: "No name",
|
||||||
args: func() *models.Group {
|
args: func() *models.Team {
|
||||||
s := models.NewGroup()
|
s := models.NewTeam()
|
||||||
s.SetId(ptr.To("id"))
|
s.SetId(ptr.To("id"))
|
||||||
return s
|
return s
|
||||||
}(),
|
}(),
|
||||||
@ -57,8 +57,8 @@ func (suite *TeamsUnitSuite) TestValidateGroup() {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "No ID",
|
name: "No ID",
|
||||||
args: func() *models.Group {
|
args: func() *models.Team {
|
||||||
s := models.NewGroup()
|
s := models.NewTeam()
|
||||||
s.SetDisplayName(ptr.To("testTeam"))
|
s.SetDisplayName(ptr.To("testTeam"))
|
||||||
return s
|
return s
|
||||||
}(),
|
}(),
|
||||||
@ -70,7 +70,7 @@ func (suite *TeamsUnitSuite) TestValidateGroup() {
|
|||||||
suite.Run(test.name, func() {
|
suite.Run(test.name, func() {
|
||||||
t := suite.T()
|
t := suite.T()
|
||||||
|
|
||||||
err := api.ValidateGroup(test.args)
|
err := api.ValidateTeams(test.args)
|
||||||
test.errCheck(t, err, clues.ToCore(err))
|
test.errCheck(t, err, clues.ToCore(err))
|
||||||
|
|
||||||
if test.errIsSkippable {
|
if test.errIsSkippable {
|
||||||
@ -108,10 +108,6 @@ func (suite *TeamsIntgSuite) TestGetAllTeams() {
|
|||||||
GetAll(ctx, fault.New(true))
|
GetAll(ctx, fault.New(true))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotZero(t, len(teams), "must have at least one team")
|
require.NotZero(t, len(teams), "must have at least one team")
|
||||||
|
|
||||||
for _, team := range teams {
|
|
||||||
assert.True(t, api.IsTeam(ctx, team), "must not return non teams groups")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *TeamsIntgSuite) TestTeams_GetByID() {
|
func (suite *TeamsIntgSuite) TestTeams_GetByID() {
|
||||||
Loading…
x
Reference in New Issue
Block a user