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:
parent
d31a91eac5
commit
bb86610488
@ -186,15 +186,15 @@ func (suite *SharePointIntegrationSuite) SetupSuite() {
|
|||||||
si := NewSuiteInfoImpl(suite.T(), ctx, tconfig.M365SiteID(suite.T()), path.SharePointService)
|
si := NewSuiteInfoImpl(suite.T(), ctx, tconfig.M365SiteID(suite.T()), path.SharePointService)
|
||||||
|
|
||||||
// users needed for permissions
|
// 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))
|
require.NoError(t, err, "fetching user", si.user, clues.ToCore(err))
|
||||||
si.userID = ptr.Val(user.GetId())
|
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))
|
require.NoError(t, err, "fetching user", si.secondaryUser, clues.ToCore(err))
|
||||||
si.secondaryUserID = ptr.Val(secondaryUser.GetId())
|
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))
|
require.NoError(t, err, "fetching user", si.tertiaryUser, clues.ToCore(err))
|
||||||
si.tertiaryUserID = ptr.Val(tertiaryUser.GetId())
|
si.tertiaryUserID = ptr.Val(tertiaryUser.GetId())
|
||||||
|
|
||||||
@ -255,15 +255,15 @@ func (suite *OneDriveIntegrationSuite) SetupSuite() {
|
|||||||
|
|
||||||
si := NewSuiteInfoImpl(t, ctx, tconfig.M365UserID(t), path.OneDriveService)
|
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))
|
require.NoError(t, err, "fetching user", si.user, clues.ToCore(err))
|
||||||
si.userID = ptr.Val(user.GetId())
|
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))
|
require.NoError(t, err, "fetching user", si.secondaryUser, clues.ToCore(err))
|
||||||
si.secondaryUserID = ptr.Val(secondaryUser.GetId())
|
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))
|
require.NoError(t, err, "fetching user", si.tertiaryUser, clues.ToCore(err))
|
||||||
si.tertiaryUserID = ptr.Val(tertiaryUser.GetId())
|
si.tertiaryUserID = ptr.Val(tertiaryUser.GetId())
|
||||||
|
|
||||||
@ -319,15 +319,15 @@ func (suite *OneDriveNightlySuite) SetupSuite() {
|
|||||||
|
|
||||||
si := NewSuiteInfoImpl(t, ctx, tconfig.M365UserID(t), path.OneDriveService)
|
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))
|
require.NoError(t, err, "fetching user", si.user, clues.ToCore(err))
|
||||||
si.userID = ptr.Val(user.GetId())
|
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))
|
require.NoError(t, err, "fetching user", si.secondaryUser, clues.ToCore(err))
|
||||||
si.secondaryUserID = ptr.Val(secondaryUser.GetId())
|
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))
|
require.NoError(t, err, "fetching user", si.tertiaryUser, clues.ToCore(err))
|
||||||
si.tertiaryUserID = ptr.Val(tertiaryUser.GetId())
|
si.tertiaryUserID = ptr.Val(tertiaryUser.GetId())
|
||||||
|
|
||||||
|
|||||||
@ -1139,7 +1139,10 @@ func (suite *OneDriveBackupIntgSuite) TestBackup_Run_oneDriveOwnerMigration() {
|
|||||||
counter)
|
counter)
|
||||||
require.NoError(t, err, clues.ToCore(err))
|
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))
|
require.NoError(t, err, clues.ToCore(err))
|
||||||
|
|
||||||
uid := ptr.Val(userable.GetId())
|
uid := ptr.Val(userable.GetId())
|
||||||
|
|||||||
@ -245,7 +245,7 @@ func UnlicensedM365UserID(t *testing.T) string {
|
|||||||
cfg, err := ReadTestConfig()
|
cfg, err := ReadTestConfig()
|
||||||
require.NoError(t, err, "retrieving unlicensed m365 user id from test configuration: %+v", clues.ToCore(err))
|
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
|
// Teams
|
||||||
|
|||||||
@ -86,6 +86,10 @@ func newEventualConsistencyHeaders() *abstractions.RequestHeaders {
|
|||||||
return headers
|
return headers
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func SelectProps(ss ...string) []string {
|
||||||
|
return idAnd(ss...)
|
||||||
|
}
|
||||||
|
|
||||||
// makes a slice with []string{"id", s...}
|
// makes a slice with []string{"id", s...}
|
||||||
func idAnd(ss ...string) []string {
|
func idAnd(ss ...string) []string {
|
||||||
id := []string{"id"}
|
id := []string{"id"}
|
||||||
|
|||||||
@ -112,15 +112,29 @@ func (c Users) GetAll(
|
|||||||
return us, el.Failure()
|
return us, el.Failure()
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetByID looks up the user matching the given identifier. The identifier can be either a
|
func (c Users) GetByID(
|
||||||
// canonical user id or a princpalName.
|
ctx context.Context,
|
||||||
func (c Users) GetByID(ctx context.Context, identifier string) (models.Userable, error) {
|
identifier string,
|
||||||
|
cc CallConfig,
|
||||||
|
) (models.Userable, error) {
|
||||||
var (
|
var (
|
||||||
resp models.Userable
|
resp models.Userable
|
||||||
err error
|
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 err != nil {
|
||||||
if graph.IsErrResourceLocked(err) {
|
if graph.IsErrResourceLocked(err) {
|
||||||
err = clues.Stack(graph.ErrResourceLocked, 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(
|
func (c Users) GetIDAndName(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
userID string,
|
userID string,
|
||||||
_ CallConfig, // not currently supported
|
cc CallConfig,
|
||||||
) (string, string, error) {
|
) (string, string, error) {
|
||||||
u, err := c.GetByID(ctx, userID)
|
u, err := c.GetByID(ctx, userID, cc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", err
|
return "", "", err
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package m365
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/alcionai/clues"
|
"github.com/alcionai/clues"
|
||||||
"github.com/microsoftgraph/msgraph-sdk-go/models"
|
"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
|
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
|
// parseUser extracts information from `models.Userable` we care about
|
||||||
func parseUser(item models.Userable) (*UserNoInfo, error) {
|
func parseUser(item models.Userable) (*UserNoInfo, error) {
|
||||||
if item.GetUserPrincipalName() == nil {
|
if item.GetUserPrincipalName() == nil {
|
||||||
|
|||||||
@ -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)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user