Getlicenseinfo (#4655)

Adds a call to get user total count of licenses. Also corrects one test ID which i hope doesn't break E2E tests (although it should if it does, ha)

---

#### Does this PR need a docs update or release note?

- [ ]  Yes, it's included
- [ ] 🕐 Yes, but in a later PR
- [x]  No

#### Type of change

<!--- Please check the type of change your PR introduces: --->
- [x] 🌻 Feature
- [ ] 🐛 Bugfix
- [ ] 🗺️ Documentation
- [ ] 🤖 Supportability/Tests
- [ ] 💻 CI/Deployment
- [ ] 🧹 Tech Debt/Cleanup

#### Issue(s)

<!-- Can reference multiple issues. Use one of the following "magic words" - "closes, fixes" to auto-close the Github issue. -->
* #<issue>

#### Test Plan

<!-- How will this be tested prior to merging.-->
- [x] 💪 Manual
- [x]  Unit test
- [x] 💚 E2E
This commit is contained in:
jules 2023-11-10 15:13:47 -08:00 committed by GitHub
parent d31a91eac5
commit bb86610488
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 109 additions and 17 deletions

View File

@ -186,15 +186,15 @@ func (suite *SharePointIntegrationSuite) SetupSuite() {
si := NewSuiteInfoImpl(suite.T(), ctx, tconfig.M365SiteID(suite.T()), path.SharePointService)
// users needed for permissions
user, err := si.controller.AC.Users().GetByID(ctx, si.user)
user, err := si.controller.AC.Users().GetByID(ctx, si.user, api.CallConfig{})
require.NoError(t, err, "fetching user", si.user, clues.ToCore(err))
si.userID = ptr.Val(user.GetId())
secondaryUser, err := si.controller.AC.Users().GetByID(ctx, si.secondaryUser)
secondaryUser, err := si.controller.AC.Users().GetByID(ctx, si.secondaryUser, api.CallConfig{})
require.NoError(t, err, "fetching user", si.secondaryUser, clues.ToCore(err))
si.secondaryUserID = ptr.Val(secondaryUser.GetId())
tertiaryUser, err := si.controller.AC.Users().GetByID(ctx, si.tertiaryUser)
tertiaryUser, err := si.controller.AC.Users().GetByID(ctx, si.tertiaryUser, api.CallConfig{})
require.NoError(t, err, "fetching user", si.tertiaryUser, clues.ToCore(err))
si.tertiaryUserID = ptr.Val(tertiaryUser.GetId())
@ -255,15 +255,15 @@ func (suite *OneDriveIntegrationSuite) SetupSuite() {
si := NewSuiteInfoImpl(t, ctx, tconfig.M365UserID(t), path.OneDriveService)
user, err := si.controller.AC.Users().GetByID(ctx, si.user)
user, err := si.controller.AC.Users().GetByID(ctx, si.user, api.CallConfig{})
require.NoError(t, err, "fetching user", si.user, clues.ToCore(err))
si.userID = ptr.Val(user.GetId())
secondaryUser, err := si.controller.AC.Users().GetByID(ctx, si.secondaryUser)
secondaryUser, err := si.controller.AC.Users().GetByID(ctx, si.secondaryUser, api.CallConfig{})
require.NoError(t, err, "fetching user", si.secondaryUser, clues.ToCore(err))
si.secondaryUserID = ptr.Val(secondaryUser.GetId())
tertiaryUser, err := si.controller.AC.Users().GetByID(ctx, si.tertiaryUser)
tertiaryUser, err := si.controller.AC.Users().GetByID(ctx, si.tertiaryUser, api.CallConfig{})
require.NoError(t, err, "fetching user", si.tertiaryUser, clues.ToCore(err))
si.tertiaryUserID = ptr.Val(tertiaryUser.GetId())
@ -319,15 +319,15 @@ func (suite *OneDriveNightlySuite) SetupSuite() {
si := NewSuiteInfoImpl(t, ctx, tconfig.M365UserID(t), path.OneDriveService)
user, err := si.controller.AC.Users().GetByID(ctx, si.user)
user, err := si.controller.AC.Users().GetByID(ctx, si.user, api.CallConfig{})
require.NoError(t, err, "fetching user", si.user, clues.ToCore(err))
si.userID = ptr.Val(user.GetId())
secondaryUser, err := si.controller.AC.Users().GetByID(ctx, si.secondaryUser)
secondaryUser, err := si.controller.AC.Users().GetByID(ctx, si.secondaryUser, api.CallConfig{})
require.NoError(t, err, "fetching user", si.secondaryUser, clues.ToCore(err))
si.secondaryUserID = ptr.Val(secondaryUser.GetId())
tertiaryUser, err := si.controller.AC.Users().GetByID(ctx, si.tertiaryUser)
tertiaryUser, err := si.controller.AC.Users().GetByID(ctx, si.tertiaryUser, api.CallConfig{})
require.NoError(t, err, "fetching user", si.tertiaryUser, clues.ToCore(err))
si.tertiaryUserID = ptr.Val(tertiaryUser.GetId())

View File

@ -1139,7 +1139,10 @@ func (suite *OneDriveBackupIntgSuite) TestBackup_Run_oneDriveOwnerMigration() {
counter)
require.NoError(t, err, clues.ToCore(err))
userable, err := ctrl.AC.Users().GetByID(ctx, suite.its.user.ID)
userable, err := ctrl.AC.Users().GetByID(
ctx,
suite.its.user.ID,
api.CallConfig{})
require.NoError(t, err, clues.ToCore(err))
uid := ptr.Val(userable.GetId())

View File

@ -245,7 +245,7 @@ func UnlicensedM365UserID(t *testing.T) string {
cfg, err := ReadTestConfig()
require.NoError(t, err, "retrieving unlicensed m365 user id from test configuration: %+v", clues.ToCore(err))
return strings.ToLower(cfg[TestCfgSecondaryUserID])
return strings.ToLower(cfg[TestCfgUnlicensedUserID])
}
// Teams

View File

@ -86,6 +86,10 @@ func newEventualConsistencyHeaders() *abstractions.RequestHeaders {
return headers
}
func SelectProps(ss ...string) []string {
return idAnd(ss...)
}
// makes a slice with []string{"id", s...}
func idAnd(ss ...string) []string {
id := []string{"id"}

View File

@ -112,15 +112,29 @@ func (c Users) GetAll(
return us, el.Failure()
}
// GetByID looks up the user matching the given identifier. The identifier can be either a
// canonical user id or a princpalName.
func (c Users) GetByID(ctx context.Context, identifier string) (models.Userable, error) {
func (c Users) GetByID(
ctx context.Context,
identifier string,
cc CallConfig,
) (models.Userable, error) {
var (
resp models.Userable
err error
)
resp, err = c.Stable.Client().Users().ByUserId(identifier).Get(ctx, nil)
options := &users.UserItemRequestBuilderGetRequestConfiguration{
QueryParameters: &users.UserItemRequestBuilderGetQueryParameters{},
}
if len(cc.Select) > 0 {
options.QueryParameters.Select = cc.Select
}
resp, err = c.Stable.
Client().
Users().
ByUserId(identifier).
Get(ctx, options)
if err != nil {
if graph.IsErrResourceLocked(err) {
err = clues.Stack(graph.ErrResourceLocked, err)
@ -137,9 +151,9 @@ func (c Users) GetByID(ctx context.Context, identifier string) (models.Userable,
func (c Users) GetIDAndName(
ctx context.Context,
userID string,
_ CallConfig, // not currently supported
cc CallConfig,
) (string, string, error) {
u, err := c.GetByID(ctx, userID)
u, err := c.GetByID(ctx, userID, cc)
if err != nil {
return "", "", err
}

View File

@ -2,6 +2,7 @@ package m365
import (
"context"
"fmt"
"github.com/alcionai/clues"
"github.com/microsoftgraph/msgraph-sdk-go/models"
@ -104,6 +105,31 @@ func usersNoInfo(ctx context.Context, acct account.Account, errs *fault.Bus) ([]
return ret, nil
}
func UserAssignedLicenses(ctx context.Context, acct account.Account, userID string) (int, error) {
ac, err := makeAC(ctx, acct, path.UnknownService)
if err != nil {
return 0, clues.Stack(err).WithClues(ctx)
}
us, err := ac.Users().GetByID(
ctx,
userID,
api.CallConfig{Select: api.SelectProps("assignedLicenses")})
if err != nil {
return 0, err
}
if us.GetAssignedLicenses() != nil {
for _, license := range us.GetAssignedLicenses() {
fmt.Println(license.GetSkuId())
}
return len(us.GetAssignedLicenses()), nil
}
return 0, clues.New("user missing assigned licenses")
}
// parseUser extracts information from `models.Userable` we care about
func parseUser(item models.Userable) (*UserNoInfo, error) {
if item.GetUserPrincipalName() == nil {

View File

@ -239,3 +239,48 @@ func (suite *userIntegrationSuite) TestUsers_InvalidCredentials() {
})
}
}
func (suite *userIntegrationSuite) TestUserAssignedLicenses() {
t := suite.T()
ctx, flush := tester.NewContext(t)
graph.InitializeConcurrencyLimiter(ctx, true, 4)
defer flush()
runs := []struct {
name string
userID string
expect int
expectErr require.ErrorAssertionFunc
}{
{
name: "user with no licenses",
userID: tconfig.UnlicensedM365UserID(t),
expect: 0,
expectErr: require.NoError,
},
{
name: "user with licenses",
userID: tconfig.M365UserID(t),
expect: 2,
expectErr: require.NoError,
},
{
name: "User does not exist",
userID: "fake",
expect: 0,
expectErr: require.Error,
},
}
for _, run := range runs {
t.Run(run.name, func(t *testing.T) {
user, err := UserAssignedLicenses(
ctx,
suite.acct,
run.userID)
run.expectErr(t, err, clues.ToCore(err))
assert.Equal(t, run.expect, user)
})
}
}