From 6e32cd4985c79eb1553ff90311cbc79876877ef3 Mon Sep 17 00:00:00 2001 From: Philipp Meier Date: Mon, 16 Oct 2023 11:36:04 +0200 Subject: [PATCH 1/5] Implement support for CAP guestsOrExternalUsers Fixes #261 --- msgraph/models.go | 80 ++++++++++++++++++++++++++++++++++++------- msgraph/valuetypes.go | 21 ++++++++++++ 2 files changed, 88 insertions(+), 13 deletions(-) diff --git a/msgraph/models.go b/msgraph/models.go index 8bffe987..11f282ff 100644 --- a/msgraph/models.go +++ b/msgraph/models.go @@ -88,7 +88,7 @@ type AccessPackageCatalog struct { DisplayName *string `json:"displayName,omitempty"` IsExternallyVisible *bool `json:"isExternallyVisible,omitempty"` ModifiedDateTime *time.Time `json:"modifiedDateTime,omitempty"` - //Beta + // Beta CatalogStatus AccessPackageCatalogStatus `json:"catalogStatus,omitempty"` CreatedBy *string `json:"createdBy,omitempty"` ModifiedBy *string `json:"modifiedBy,omitempty"` @@ -547,10 +547,10 @@ type AppRoleAssignment struct { type ApprovalSettings struct { IsApprovalRequiredForAdd *bool `json:"isApprovalRequiredForAdd,omitempty"` IsApprovalRequiredForUpdate *bool `json:"isApprovalRequiredForUpdate,omitempty"` - IsApprovalRequired *bool `json:"isApprovalRequired,omitempty"` //beta property - IsApprovalRequiredForExtension *bool `json:"isApprovalRequiredForExtension,omitempty"` //beta property - IsRequestorJustificationRequired *bool `json:"isRequestorJustificationRequired,omitempty"` //beta property - ApprovalMode ApprovalMode `json:"approvalMode,omitempty"` //beta property + IsApprovalRequired *bool `json:"isApprovalRequired,omitempty"` // beta property + IsApprovalRequiredForExtension *bool `json:"isApprovalRequiredForExtension,omitempty"` // beta property + IsRequestorJustificationRequired *bool `json:"isRequestorJustificationRequired,omitempty"` // beta property + ApprovalMode ApprovalMode `json:"approvalMode,omitempty"` // beta property ApprovalStages *[]ApprovalStage `json:"approvalStages,omitempty"` } @@ -693,12 +693,66 @@ type ConditionalAccessSessionControls struct { } type ConditionalAccessUsers struct { - IncludeUsers *[]string `json:"includeUsers,omitempty"` - ExcludeUsers *[]string `json:"excludeUsers,omitempty"` - IncludeGroups *[]string `json:"includeGroups,omitempty"` - ExcludeGroups *[]string `json:"excludeGroups,omitempty"` - IncludeRoles *[]string `json:"includeRoles,omitempty"` - ExcludeRoles *[]string `json:"excludeRoles,omitempty"` + IncludeUsers *[]string `json:"includeUsers,omitempty"` + ExcludeUsers *[]string `json:"excludeUsers,omitempty"` + IncludeGroups *[]string `json:"includeGroups,omitempty"` + ExcludeGroups *[]string `json:"excludeGroups,omitempty"` + IncludeRoles *[]string `json:"includeRoles,omitempty"` + ExcludeRoles *[]string `json:"excludeRoles,omitempty"` + IncludeGuestsOrExternalUsers *ConditionalAccessGuestsOrExternalUsers `json:"includeGuestsOrExternalUsers,omitempty"` + ExcludeGuestsOrExternalUsers *ConditionalAccessGuestsOrExternalUsers `json:"excludeGuestsOrExternalUsers,omitempty"` +} + +type ConditionalAccessGuestsOrExternalUsers struct { + GuestOrExternalUserTypes *[]ConditionalAccessGuestOrExternalUserType `json:"guestOrExternalUserTypes,omitempty"` + ExternalTenants *ConditionalAccessExternalTenants `json:"externalTenants,omitempty"` +} + +type ConditionalAccessExternalTenants struct { + MembershipKind *string `json:"membershipKind,omitempty"` + Members *[]string `json:"members,omitempty"` +} + +func (c ConditionalAccessGuestsOrExternalUsers) MarshalJSON() ([]byte, error) { + var val *StringNullWhenEmpty + if c.GuestOrExternalUserTypes != nil { + theTypes := StringNullWhenEmpty(strings.Join(*c.GuestOrExternalUserTypes, ",")) + val = &theTypes + } + + // Local type needed to avoid recursive MarshalJSON calls + type conditionalAccessGuestsOrExternalUsers ConditionalAccessGuestsOrExternalUsers + guestOrExternalUsers := struct { + GuestOrExternalUserTypes *StringNullWhenEmpty `json:"guestOrExternalUserTypes,omitempty"` + *conditionalAccessGuestsOrExternalUsers + }{ + GuestOrExternalUserTypes: val, + conditionalAccessGuestsOrExternalUsers: (*conditionalAccessGuestsOrExternalUsers)(&c), + } + buf, err := json.Marshal(&guestOrExternalUsers) + return buf, err +} + +func (c *ConditionalAccessGuestsOrExternalUsers) UnmarshalJSON(data []byte) error { + // Local type needed to avoid recursive UnmarshalJSON calls + type conditionalAccessGuestsOrExternalUsers ConditionalAccessGuestsOrExternalUsers + guestOrExternalUsers := struct { + GuestOrExternalUserTypes *string `json:"guestOrExternalUserTypes"` + *conditionalAccessGuestsOrExternalUsers + }{ + conditionalAccessGuestsOrExternalUsers: (*conditionalAccessGuestsOrExternalUsers)(c), + } + if err := json.Unmarshal(data, &guestOrExternalUsers); err != nil { + return err + } + if guestOrExternalUsers.GuestOrExternalUserTypes != nil { + var types []string + for _, s := range strings.Split(*guestOrExternalUsers.GuestOrExternalUserTypes, ",") { + types = append(types, strings.TrimSpace(s)) + } + c.GuestOrExternalUserTypes = &types + } + return nil } type ConnectionInfo struct { @@ -1645,7 +1699,7 @@ type TermsOfUseAgreement struct { UserReacceptRequiredFrequency *string `json:"userReacceptRequiredFrequency,omitempty"` IsViewingBeforeAcceptanceRequired *bool `json:"isViewingBeforeAcceptanceRequired,omitempty"` IsPerDeviceAcceptanceRequired *bool `json:"isPerDeviceAcceptanceRequired,omitempty"` - TermsExpiration *TermsOfUseAgreementExpiration `json:"termsExpiration,omitempty"` //For some reason this exports the Frequency both here and above AcceptanceExpirationFrequency Request separates them but response groups them. Anticipate this in Tests + TermsExpiration *TermsOfUseAgreementExpiration `json:"termsExpiration,omitempty"` // For some reason this exports the Frequency both here and above AcceptanceExpirationFrequency Request separates them but response groups them. Anticipate this in Tests Files *[]TermsOfUseAgreementFile `json:"files,omitempty"` File *TermsOfUseAgreementFile `json:"file,omitempty"` } @@ -1656,7 +1710,7 @@ type TermsOfUseAgreementExpiration struct { } type TermsOfUseAgreementFileData struct { - //Data is within its own object for some reason + // Data is within its own object for some reason Data *[]byte `json:"data,omitempty"` } diff --git a/msgraph/valuetypes.go b/msgraph/valuetypes.go index eca99667..5e37c5a8 100644 --- a/msgraph/valuetypes.go +++ b/msgraph/valuetypes.go @@ -404,6 +404,27 @@ const ( ConditionalAccessRiskLevelUnknownFutureValue ConditionalAccessRiskLevel = "unknownFutureValue" ) +type ConditionalAccessGuestOrExternalUserType = string + +const ( + ConditionalAccessGuestOrExternalUserTypeNone ConditionalAccessGuestOrExternalUserType = "none" + ConditionalAccessGuestOrExternalUserTypeInternalGuest ConditionalAccessGuestOrExternalUserType = "internalGuest" + ConditionalAccessGuestOrExternalUserTypeB2bCollaborationGuest ConditionalAccessGuestOrExternalUserType = "b2bCollaborationGuest" + ConditionalAccessGuestOrExternalUserTypeB2bCollaborationMember ConditionalAccessGuestOrExternalUserType = "b2bCollaborationMember" + ConditionalAccessGuestOrExternalUserTypeB2bDirectConnectUser ConditionalAccessGuestOrExternalUserType = "b2bDirectConnectUser" + ConditionalAccessGuestOrExternalUserTypeOtherExternalUser ConditionalAccessGuestOrExternalUserType = "otherExternalUser" + ConditionalAccessGuestOrExternalUserTypeServiceProvider ConditionalAccessGuestOrExternalUserType = "serviceProvider" + ConditionalAccessGuestOrExternalUserTypeUnknownFutureValue ConditionalAccessGuestOrExternalUserType = "unknownFutureValue" +) + +type ConditionalAccessExternalTenantsMembershipKind = string + +const ( + ConditionalAccessExternalTenantsMembershipKindAll ConditionalAccessExternalTenantsMembershipKind = "all" + ConditionalAccessExternalTenantsMembershipKindEnumerated ConditionalAccessExternalTenantsMembershipKind = "enumerated" + ConditionalAccessExternalTenantsMembershipKindUnknownFutureValue ConditionalAccessExternalTenantsMembershipKind = "unknownFutureValue" +) + type ConnectedOrganizationState = string const ( From df881e2f51d9cb60480672f7350d3202952441f7 Mon Sep 17 00:00:00 2001 From: Philipp Meier Date: Mon, 23 Oct 2023 11:12:28 +0200 Subject: [PATCH 2/5] Revert unrelatd whitespace changes Changes came from gofumpt. --- msgraph/models.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/msgraph/models.go b/msgraph/models.go index 11f282ff..3a186fde 100644 --- a/msgraph/models.go +++ b/msgraph/models.go @@ -88,7 +88,7 @@ type AccessPackageCatalog struct { DisplayName *string `json:"displayName,omitempty"` IsExternallyVisible *bool `json:"isExternallyVisible,omitempty"` ModifiedDateTime *time.Time `json:"modifiedDateTime,omitempty"` - // Beta + //Beta CatalogStatus AccessPackageCatalogStatus `json:"catalogStatus,omitempty"` CreatedBy *string `json:"createdBy,omitempty"` ModifiedBy *string `json:"modifiedBy,omitempty"` @@ -547,10 +547,10 @@ type AppRoleAssignment struct { type ApprovalSettings struct { IsApprovalRequiredForAdd *bool `json:"isApprovalRequiredForAdd,omitempty"` IsApprovalRequiredForUpdate *bool `json:"isApprovalRequiredForUpdate,omitempty"` - IsApprovalRequired *bool `json:"isApprovalRequired,omitempty"` // beta property - IsApprovalRequiredForExtension *bool `json:"isApprovalRequiredForExtension,omitempty"` // beta property - IsRequestorJustificationRequired *bool `json:"isRequestorJustificationRequired,omitempty"` // beta property - ApprovalMode ApprovalMode `json:"approvalMode,omitempty"` // beta property + IsApprovalRequired *bool `json:"isApprovalRequired,omitempty"` //beta property + IsApprovalRequiredForExtension *bool `json:"isApprovalRequiredForExtension,omitempty"` //beta property + IsRequestorJustificationRequired *bool `json:"isRequestorJustificationRequired,omitempty"` //beta property + ApprovalMode ApprovalMode `json:"approvalMode,omitempty"` //beta property ApprovalStages *[]ApprovalStage `json:"approvalStages,omitempty"` } @@ -1699,7 +1699,7 @@ type TermsOfUseAgreement struct { UserReacceptRequiredFrequency *string `json:"userReacceptRequiredFrequency,omitempty"` IsViewingBeforeAcceptanceRequired *bool `json:"isViewingBeforeAcceptanceRequired,omitempty"` IsPerDeviceAcceptanceRequired *bool `json:"isPerDeviceAcceptanceRequired,omitempty"` - TermsExpiration *TermsOfUseAgreementExpiration `json:"termsExpiration,omitempty"` // For some reason this exports the Frequency both here and above AcceptanceExpirationFrequency Request separates them but response groups them. Anticipate this in Tests + TermsExpiration *TermsOfUseAgreementExpiration `json:"termsExpiration,omitempty"` //For some reason this exports the Frequency both here and above AcceptanceExpirationFrequency Request separates them but response groups them. Anticipate this in Tests Files *[]TermsOfUseAgreementFile `json:"files,omitempty"` File *TermsOfUseAgreementFile `json:"file,omitempty"` } @@ -1710,7 +1710,7 @@ type TermsOfUseAgreementExpiration struct { } type TermsOfUseAgreementFileData struct { - // Data is within its own object for some reason + //Data is within its own object for some reason Data *[]byte `json:"data,omitempty"` } From b204d91a39e0cfa272d0199369ec2216b67dbb4a Mon Sep 17 00:00:00 2001 From: Philipp Meier Date: Tue, 24 Oct 2023 11:16:53 +0200 Subject: [PATCH 3/5] Fix patch not removing guestsOrExternalUsers block Need to explicitly send field with null value for the patch operation to affect it. --- msgraph/models.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/msgraph/models.go b/msgraph/models.go index 3a186fde..29203a92 100644 --- a/msgraph/models.go +++ b/msgraph/models.go @@ -699,8 +699,8 @@ type ConditionalAccessUsers struct { ExcludeGroups *[]string `json:"excludeGroups,omitempty"` IncludeRoles *[]string `json:"includeRoles,omitempty"` ExcludeRoles *[]string `json:"excludeRoles,omitempty"` - IncludeGuestsOrExternalUsers *ConditionalAccessGuestsOrExternalUsers `json:"includeGuestsOrExternalUsers,omitempty"` - ExcludeGuestsOrExternalUsers *ConditionalAccessGuestsOrExternalUsers `json:"excludeGuestsOrExternalUsers,omitempty"` + IncludeGuestsOrExternalUsers *ConditionalAccessGuestsOrExternalUsers `json:"includeGuestsOrExternalUsers"` + ExcludeGuestsOrExternalUsers *ConditionalAccessGuestsOrExternalUsers `json:"excludeGuestsOrExternalUsers"` } type ConditionalAccessGuestsOrExternalUsers struct { From 10040aadd3d6e5c53ec527fd25eca789beed1ec9 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Wed, 25 Oct 2023 16:06:57 +0100 Subject: [PATCH 4/5] ConditionalAccessGuestsOrExternalUsers: ignore GuestOrExternalUserTypes when marshaling --- msgraph/models.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msgraph/models.go b/msgraph/models.go index 29203a92..db13f66c 100644 --- a/msgraph/models.go +++ b/msgraph/models.go @@ -704,7 +704,7 @@ type ConditionalAccessUsers struct { } type ConditionalAccessGuestsOrExternalUsers struct { - GuestOrExternalUserTypes *[]ConditionalAccessGuestOrExternalUserType `json:"guestOrExternalUserTypes,omitempty"` + GuestOrExternalUserTypes *[]ConditionalAccessGuestOrExternalUserType `json:"-"` // see ConditionalAccessGuestsOrExternalUsers.MarshalJSON / ConditionalAccessGuestsOrExternalUsers.UnmarshalJSON ExternalTenants *ConditionalAccessExternalTenants `json:"externalTenants,omitempty"` } From 0bfce0327ca1eebd53efbb31a98adebc6c89d061 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Wed, 25 Oct 2023 16:07:27 +0100 Subject: [PATCH 5/5] ConditionalAccessExternalTenants: type alias for MembershipKind --- msgraph/models.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/msgraph/models.go b/msgraph/models.go index db13f66c..11c16520 100644 --- a/msgraph/models.go +++ b/msgraph/models.go @@ -709,8 +709,9 @@ type ConditionalAccessGuestsOrExternalUsers struct { } type ConditionalAccessExternalTenants struct { - MembershipKind *string `json:"membershipKind,omitempty"` - Members *[]string `json:"members,omitempty"` + MembershipKind *ConditionalAccessExternalTenantsMembershipKind `json:"membershipKind,omitempty"` + Members *[]string `json:"members,omitempty"` + } func (c ConditionalAccessGuestsOrExternalUsers) MarshalJSON() ([]byte, error) {