From 70da5c3086fdfe88d7436ba486a31441f46985bf Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Tue, 15 Jun 2021 10:53:59 +0100 Subject: [PATCH 1/2] Add new type alias StringNullWhenEmpty for nullable string values, tidy up models and split value types into another file --- msgraph/models.go | 290 +++++++++++++++--------------------------- msgraph/valuetypes.go | 79 ++++++++++++ 2 files changed, 182 insertions(+), 187 deletions(-) create mode 100644 msgraph/valuetypes.go diff --git a/msgraph/models.go b/msgraph/models.go index e0bd050f..ce20ef1d 100644 --- a/msgraph/models.go +++ b/msgraph/models.go @@ -66,21 +66,21 @@ type Application struct { } func (a Application) MarshalJSON() ([]byte, error) { - var groupMembershipClaims *string + var val *StringNullWhenEmpty if a.GroupMembershipClaims != nil { claims := make([]string, 0) for _, c := range *a.GroupMembershipClaims { claims = append(claims, string(c)) } - theClaims := strings.Join(claims, ",") - groupMembershipClaims = &theClaims + theClaims := StringNullWhenEmpty(strings.Join(claims, ",")) + val = &theClaims } type application Application return json.Marshal(&struct { - GroupMembershipClaims *string `json:"groupMembershipClaims,omitempty"` + GroupMembershipClaims *StringNullWhenEmpty `json:"groupMembershipClaims,omitempty"` *application }{ - GroupMembershipClaims: groupMembershipClaims, + GroupMembershipClaims: val, application: (*application)(&a), }) } @@ -106,30 +106,6 @@ func (a *Application) UnmarshalJSON(data []byte) error { return nil } -func (a *Application) UnmarshalJSON2(data []byte) error { - type application Application - var app application - if err := json.Unmarshal(data, &app); err != nil { - return err - } - *a = Application(app) - var app2 struct { - GroupMembershipClaims *string `json:"groupMembershipClaims"` - } - if err := json.Unmarshal(data, &app2); err != nil { - return err - } - if app2.GroupMembershipClaims != nil { - var groupMembershipClaims []GroupMembershipClaim - claims := strings.Split(*app2.GroupMembershipClaims, ",") - for _, c := range claims { - groupMembershipClaims = append(groupMembershipClaims, GroupMembershipClaim(strings.TrimSpace(c))) - } - a.GroupMembershipClaims = &groupMembershipClaims - } - return nil -} - // AppendOwner appends a new owner object URI to the Owners slice. func (a *Application) AppendOwner(endpoint environments.ApiEndpoint, apiVersion ApiVersion, id string) { val := fmt.Sprintf("%s/%s/directoryObjects/%s", endpoint, apiVersion, id) @@ -298,9 +274,9 @@ type ApplicationEnforcedRestrictionsSessionControl struct { } type ApplicationWeb struct { - HomePageUrl *string `json:"homePageUrl"` + HomePageUrl *StringNullWhenEmpty `json:"homePageUrl,omitempty"` ImplicitGrantSettings *ImplicitGrantSettings `json:"implicitGrantSettings,omitempty"` - LogoutUrl *string `json:"logoutUrl"` + LogoutUrl *StringNullWhenEmpty `json:"logoutUrl,omitempty"` RedirectUris *[]string `json:"redirectUris,omitempty"` } @@ -314,12 +290,17 @@ type AppRole struct { Value *string `json:"value,omitempty"` } -type AppRoleAllowedMemberType string - -const ( - AppRoleAllowedMemberTypeApplication AppRoleAllowedMemberType = "Application" - AppRoleAllowedMemberTypeUser AppRoleAllowedMemberType = "User" -) +type AppRoleAssignment struct { + Id *string `json:"id,omitempty"` + DeletedDateTime *time.Time `json:"deletedDateTime,omitempty"` + AppRoleId *string `json:"appRoleId,omitempty"` + CreatedDateTime *time.Time `json:"createdDateTime,omitempty"` + PrincipalDisplayName *string `json:"principalDisplayName,omitempty"` + PrincipalId *string `json:"principalId,omitempty"` + PrincipalType *string `json:"principalType,omitempty"` + ResourceDisplayName *string `json:"resourceDisplayName,omitempty"` + ResourceId *string `json:"resourceId,omitempty"` +} type BaseNamedLocation struct { ODataType *string `json:"@odata.type,omitempty"` @@ -467,10 +448,10 @@ type Group struct { Classification *string `json:"classification,omitempty"` CreatedDateTime *time.Time `json:"createdDateTime,omitempty"` DeletedDateTime *time.Time `json:"deletedDateTime,omitempty"` - Description *string `json:"description,omitempty"` + Description *StringNullWhenEmpty `json:"description,omitempty"` DisplayName *string `json:"displayName,omitempty"` ExpirationDateTime *time.Time `json:"expirationDateTime,omitempty"` - GroupTypes *[]string `json:"groupTypes,omitempty"` + GroupTypes []GroupType `json:"groupTypes,omitempty"` HasMembersWithLicenseErrors *bool `json:"hasMembersWithLicenseErrors,omitempty"` HideFromAddressLists *bool `json:"hideFromAddressLists,omitempty"` HideFromOutlookClients *bool `json:"hideFromOutlookClients,omitempty"` @@ -535,16 +516,6 @@ type GroupAssignedLicense struct { SkuId *string `json:"skuId,omitempty"` } -type GroupMembershipClaim string - -const ( - GroupMembershipClaimAll GroupMembershipClaim = "All" - GroupMembershipClaimNone GroupMembershipClaim = "None" - GroupMembershipClaimApplicationGroup GroupMembershipClaim = "ApplicationGroup" - GroupMembershipClaimDirectoryRole GroupMembershipClaim = "DirectoryRole" - GroupMembershipClaimSecurityGroup GroupMembershipClaim = "SecurityGroup" -) - type GroupOnPremisesProvisioningError struct { Category *string `json:"category,omitempty"` OccurredDateTime time.Time `json:"occurredDateTime,omitempty"` @@ -552,6 +523,15 @@ type GroupOnPremisesProvisioningError struct { Value *string `json:"value,omitempty"` } +type IdentityProvider struct { + ODataType *string `json:"@odata.type,omitempty"` + ID *string `json:"id,omitempty"` + ClientId *string `json:"clientId,omitempty"` + ClientSecret *string `json:"clientSecret,omitempty"` + Type *string `json:"identityProviderType,omitempty"` + Name *string `json:"displayName,omitempty"` +} + type ImplicitGrantSettings struct { EnableAccessTokenIssuance *bool `json:"enableAccessTokenIssuance,omitempty"` EnableIdTokenIssuance *bool `json:"enableIdTokenIssuance,omitempty"` @@ -597,6 +577,11 @@ type IPNamedLocationIPRange struct { CIDRAddress *string `json:"cidrAddress,omitempty"` } +type ItemBody struct { + Content *string `json:"content,omitempty"` + ContentType *BodyType `json:"contentType,omitempty"` +} + type KerberosSignOnSettings struct { ServicePrincipalName *string `json:"kerberosServicePrincipalName,omitempty"` SignOnMappingAttributeType *string `jsonL:"kerberosSignOnMappingAttributeType,omitempty"` @@ -614,19 +599,9 @@ type KeyCredential struct { Key *string `json:"key,omitempty"` } -type KeyCredentialType string - -const ( - KeyCredentialTypeAsymmetricX509Cert KeyCredentialType = "AsymmetricX509Cert" - KeyCredentialTypeX509CertAndPassword KeyCredentialType = "X509CertAndPassword" -) - -type KeyCredentialUsage string - -const ( - KeyCredentialUsageSign KeyCredentialUsage = "Sign" - KeyCredentialUsageVerify KeyCredentialUsage = "Verify" -) +type MailMessage struct { + Message *Message `json:"message,omitempty"` +} // Me describes the authenticated user. type Me struct { @@ -635,6 +610,16 @@ type Me struct { UserPrincipalName *string `json:"userPrincipalName"` } +type Message struct { + ID *string `json:"id,omitempty"` + Subject *string `json:"subject,omitempty"` + Body *ItemBody `json:"body,omitempty"` + From *Recipient `json:"from,omitempty"` + ToRecipients *[]Recipient `json:"toRecipients,omitempty"` + CcRecipients *[]Recipient `json:"ccRecipients,omitempty"` + BccRecipients *[]Recipient `json:"bccRecipients,omitempty"` +} + type NamedLocation interface{} type OnPremisesPublishing struct { @@ -714,13 +699,6 @@ type PermissionScope struct { Value *string `json:"value,omitempty"` } -type PermissionScopeType string - -const ( - PermissionScopeTypeAdmin PermissionScopeType = "Admin" - PermissionScopeTypeUser PermissionScopeType = "User" -) - type PersistentBrowserSessionControl struct { IsEnabled *bool `json:"isEnabled,omitempty"` Mode *string `json:"mode,omitempty"` @@ -744,13 +722,6 @@ type ResourceAccess struct { Type ResourceAccessType `json:"type,omitempty"` } -type ResourceAccessType string - -const ( - ResourceAccessTypeRole ResourceAccessType = "Role" - ResourceAccessTypeScope ResourceAccessType = "Scope" -) - type SamlSingleSignOnSettings struct { RelayState *string `json:"relayState,omitempty"` } @@ -803,14 +774,6 @@ func (a *ServicePrincipal) AppendOwner(endpoint string, apiVersion string, id st a.Owners = &owners } -type SignInAudience string - -const ( - SignInAudienceAzureADMyOrg SignInAudience = "AzureADMyOrg" - SignInAudienceAzureADMultipleOrgs SignInAudience = "AzureADMultipleOrgs" - SignInAudienceAzureADandPersonalMicrosoftAccount SignInAudience = "AzureADandPersonalMicrosoftAccount" -) - type SignInFrequencySessionControl struct { IsEnabled *bool `json:"isEnabled,omitempty"` Type *string `json:"type,omitempty"` @@ -826,62 +789,62 @@ type SingleSignOnField struct { // User describes a User object. type User struct { - ID *string `json:"id,omitempty"` - AboutMe *string `json:"aboutMe,omitempty"` - AccountEnabled *bool `json:"accountEnabled,omitempty"` - BusinessPhones *[]string `json:"businessPhones,omitempty"` - City *string `json:"city,omitempty"` - CompanyName *string `json:"companyName,omitempty"` - Country *string `json:"country,omitempty"` - CreatedDateTime *time.Time `json:"createdDateTime,omitempty"` - CreationType *string `json:"creationType,omitempty"` - DeletedDateTime *time.Time `json:"deletedDateTime,omitempty"` - Department *string `json:"department,omitempty"` - DisplayName *string `json:"displayName,omitempty"` - EmployeeHireDate *time.Time `json:"employeeHireDate,omitempty"` - EmployeeId *string `json:"employeeId,omitempty"` - EmployeeType *string `json:"employeeType,omitempty"` - ExternalUserState *string `json:"externalUserState,omitempty"` - FaxNumber *string `json:"faxNumber,omitempty"` - GivenName *string `json:"givenName,omitempty"` - ImAddresses *[]string `json:"imAddresses,omitempty"` - Interests *[]string `json:"interests,omitempty"` - IsManagementRestricted *bool `json:"isManagementRestricted,omitempty"` - IsResourceAccount *bool `json:"isResourceAccount,omitempty"` - JobTitle *string `json:"jobTitle,omitempty"` - Mail *string `json:"mail,omitempty"` - MailNickname *string `json:"mailNickname,omitempty"` - MobilePhone *string `json:"mobilePhone,omitempty"` - MySite *string `json:"mySite,omitempty"` - OfficeLocation *string `json:"officeLocation,omitempty"` - OnPremisesDistinguishedName *string `json:"onPremisesDistinguishedName,omitempty"` - OnPremisesDomainName *string `json:"onPremisesDomainName,omitempty"` - OnPremisesImmutableId *string `json:"onPremisesImmutableId,omitempty"` - OnPremisesLastSyncDateTime *string `json:"onPremisesLastSyncDateTime,omitempty"` - OnPremisesSamAccountName *string `json:"onPremisesSamAccountName,omitempty"` - OnPremisesSecurityIdentifier *string `json:"onPremisesSecurityIdentifier,omitempty"` - OnPremisesSyncEnabled *bool `json:"onPremisesSyncEnabled,omitempty"` - OnPremisesUserPrincipalName *string `json:"onPremisesUserPrincipalName,omitempty"` - OtherMails *[]string `json:"otherMails,omitempty"` - PasswordPolicies *string `json:"passwordPolicies,omitempty"` - PastProjects *[]string `json:"pastProjects,omitempty"` - PostalCode *string `json:"postalCode,omitempty"` - PreferredDataLocation *string `json:"preferredDataLocation,omitempty"` - PreferredLanguage *string `json:"preferredLanguage,omitempty"` - PreferredName *string `json:"preferredName,omitempty"` - ProxyAddresses *[]string `json:"proxyAddresses,omitempty"` - RefreshTokensValidFromDateTime *time.Time `json:"refreshTokensValidFromDateTime,omitempty"` - Responsibilities *[]string `json:"responsibilities,omitempty"` - Schools *[]string `json:"schools,omitempty"` - ShowInAddressList *bool `json:"showInAddressList,omitempty"` - SignInSessionsValidFromDateTime *time.Time `json:"signInSessionsValidFromDateTime,omitempty"` - Skills *[]string `json:"skills,omitempty"` - State *string `json:"state,omitempty"` - StreetAddress *string `json:"streetAddress,omitempty"` - Surname *string `json:"surname,omitempty"` - UsageLocation *string `json:"usageLocation,omitempty"` - UserPrincipalName *string `json:"userPrincipalName,omitempty"` - UserType *string `json:"userType,omitempty"` + ID *string `json:"id,omitempty"` + AboutMe *string `json:"aboutMe,omitempty"` + AccountEnabled *bool `json:"accountEnabled,omitempty"` + BusinessPhones *[]string `json:"businessPhones,omitempty"` + City *StringNullWhenEmpty `json:"city,omitempty"` + CompanyName *StringNullWhenEmpty `json:"companyName,omitempty"` + Country *StringNullWhenEmpty `json:"country,omitempty"` + CreatedDateTime *time.Time `json:"createdDateTime,omitempty"` + CreationType *string `json:"creationType,omitempty"` + DeletedDateTime *time.Time `json:"deletedDateTime,omitempty"` + Department *StringNullWhenEmpty `json:"department,omitempty"` + DisplayName *string `json:"displayName,omitempty"` + EmployeeHireDate *time.Time `json:"employeeHireDate,omitempty"` + EmployeeId *string `json:"employeeId,omitempty"` + EmployeeType *string `json:"employeeType,omitempty"` + ExternalUserState *string `json:"externalUserState,omitempty"` + FaxNumber *string `json:"faxNumber,omitempty"` + GivenName *StringNullWhenEmpty `json:"givenName,omitempty"` + ImAddresses *[]string `json:"imAddresses,omitempty"` + Interests *[]string `json:"interests,omitempty"` + IsManagementRestricted *bool `json:"isManagementRestricted,omitempty"` + IsResourceAccount *bool `json:"isResourceAccount,omitempty"` + JobTitle *StringNullWhenEmpty `json:"jobTitle,omitempty"` + Mail *string `json:"mail,omitempty"` + MailNickname *string `json:"mailNickname,omitempty"` + MobilePhone *StringNullWhenEmpty `json:"mobilePhone,omitempty"` + MySite *string `json:"mySite,omitempty"` + OfficeLocation *StringNullWhenEmpty `json:"officeLocation,omitempty"` + OnPremisesDistinguishedName *string `json:"onPremisesDistinguishedName,omitempty"` + OnPremisesDomainName *string `json:"onPremisesDomainName,omitempty"` + OnPremisesImmutableId *string `json:"onPremisesImmutableId,omitempty"` + OnPremisesLastSyncDateTime *string `json:"onPremisesLastSyncDateTime,omitempty"` + OnPremisesSamAccountName *string `json:"onPremisesSamAccountName,omitempty"` + OnPremisesSecurityIdentifier *string `json:"onPremisesSecurityIdentifier,omitempty"` + OnPremisesSyncEnabled *bool `json:"onPremisesSyncEnabled,omitempty"` + OnPremisesUserPrincipalName *string `json:"onPremisesUserPrincipalName,omitempty"` + OtherMails *[]string `json:"otherMails,omitempty"` + PasswordPolicies *string `json:"passwordPolicies,omitempty"` + PastProjects *[]string `json:"pastProjects,omitempty"` + PostalCode *StringNullWhenEmpty `json:"postalCode,omitempty"` + PreferredDataLocation *string `json:"preferredDataLocation,omitempty"` + PreferredLanguage *string `json:"preferredLanguage,omitempty"` + PreferredName *string `json:"preferredName,omitempty"` + ProxyAddresses *[]string `json:"proxyAddresses,omitempty"` + RefreshTokensValidFromDateTime *time.Time `json:"refreshTokensValidFromDateTime,omitempty"` + Responsibilities *[]string `json:"responsibilities,omitempty"` + Schools *[]string `json:"schools,omitempty"` + ShowInAddressList *bool `json:"showInAddressList,omitempty"` + SignInSessionsValidFromDateTime *time.Time `json:"signInSessionsValidFromDateTime,omitempty"` + Skills *[]string `json:"skills,omitempty"` + State *StringNullWhenEmpty `json:"state,omitempty"` + StreetAddress *StringNullWhenEmpty `json:"streetAddress,omitempty"` + Surname *StringNullWhenEmpty `json:"surname,omitempty"` + UsageLocation *StringNullWhenEmpty `json:"usageLocation,omitempty"` + UserPrincipalName *string `json:"userPrincipalName,omitempty"` + UserType *string `json:"userType,omitempty"` PasswordProfile *UserPasswordProfile `json:"passwordProfile,omitempty"` } @@ -897,50 +860,3 @@ type VerifiedPublisher struct { DisplayName *string `json:"displayName,omitempty"` VerifiedPublisherId *string `json:"verifiedPublisherId,omitempty"` } - -type AppRoleAssignment struct { - Id *string `json:"id,omitempty"` - DeletedDateTime *time.Time `json:"deletedDateTime,omitempty"` - AppRoleId *string `json:"appRoleId,omitempty"` - CreatedDateTime *time.Time `json:"createdDateTime,omitempty"` - PrincipalDisplayName *string `json:"principalDisplayName,omitempty"` - PrincipalId *string `json:"principalId,omitempty"` - PrincipalType *string `json:"principalType,omitempty"` - ResourceDisplayName *string `json:"resourceDisplayName,omitempty"` - ResourceId *string `json:"resourceId,omitempty"` -} - -type MailMessage struct { - Message *Message `json:"message,omitempty"` -} - -type Message struct { - ID *string `json:"id,omitempty"` - Subject *string `json:"subject,omitempty"` - Body *ItemBody `json:"body,omitempty"` - From *Recipient `json:"from,omitempty"` - ToRecipients *[]Recipient `json:"toRecipients,omitempty"` - CcRecipients *[]Recipient `json:"ccRecipients,omitempty"` - BccRecipients *[]Recipient `json:"bccRecipients,omitempty"` -} - -type ItemBody struct { - Content *string `json:"content,omitempty"` - ContentType *BodyType `json:"contentType,omitempty"` -} - -type BodyType string - -const ( - BodyTypeText BodyType = "text" - BodyTypeHtml BodyType = "html" -) - -type IdentityProvider struct { - ODataType *string `json:"@odata.type,omitempty"` - ID *string `json:"id,omitempty"` - ClientId *string `json:"clientId,omitempty"` - ClientSecret *string `json:"clientSecret,omitempty"` - Type *string `json:"identityProviderType,omitempty"` - Name *string `json:"displayName,omitempty"` -} diff --git a/msgraph/valuetypes.go b/msgraph/valuetypes.go new file mode 100644 index 00000000..8d5b7573 --- /dev/null +++ b/msgraph/valuetypes.go @@ -0,0 +1,79 @@ +package msgraph + +import "encoding/json" + +type StringNullWhenEmpty string + +func (s StringNullWhenEmpty) MarshalJSON() ([]byte, error) { + if s == "" { + return []byte("null"), nil + } + return json.Marshal(string(s)) +} + +type AppRoleAllowedMemberType string + +const ( + AppRoleAllowedMemberTypeApplication AppRoleAllowedMemberType = "Application" + AppRoleAllowedMemberTypeUser AppRoleAllowedMemberType = "User" +) + +type BodyType string + +const ( + BodyTypeText BodyType = "text" + BodyTypeHtml BodyType = "html" +) + +type GroupType string + +const ( + GroupTypeUnified GroupType = "Unified" +) + +type GroupMembershipClaim string + +const ( + GroupMembershipClaimAll GroupMembershipClaim = "All" + GroupMembershipClaimNone GroupMembershipClaim = "None" + GroupMembershipClaimApplicationGroup GroupMembershipClaim = "ApplicationGroup" + GroupMembershipClaimDirectoryRole GroupMembershipClaim = "DirectoryRole" + GroupMembershipClaimSecurityGroup GroupMembershipClaim = "SecurityGroup" +) + +type KeyCredentialType string + +const ( + KeyCredentialTypeAsymmetricX509Cert KeyCredentialType = "AsymmetricX509Cert" + KeyCredentialTypeX509CertAndPassword KeyCredentialType = "X509CertAndPassword" +) + +type KeyCredentialUsage string + +const ( + KeyCredentialUsageSign KeyCredentialUsage = "Sign" + KeyCredentialUsageVerify KeyCredentialUsage = "Verify" +) + +type PermissionScopeType string + +const ( + PermissionScopeTypeAdmin PermissionScopeType = "Admin" + PermissionScopeTypeUser PermissionScopeType = "User" +) + +type ResourceAccessType string + +const ( + ResourceAccessTypeRole ResourceAccessType = "Role" + ResourceAccessTypeScope ResourceAccessType = "Scope" +) + +type SignInAudience string + +const ( + SignInAudienceAzureADMyOrg SignInAudience = "AzureADMyOrg" + SignInAudienceAzureADMultipleOrgs SignInAudience = "AzureADMultipleOrgs" + SignInAudienceAzureADandPersonalMicrosoftAccount SignInAudience = "AzureADandPersonalMicrosoftAccount" + SignInAudiencePersonalMicrosoftAccount SignInAudience = "PersonalMicrosoftAccount" +) From 8e1714208aa49c1a2f0c753de6f59344efe00c49 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Tue, 15 Jun 2021 11:08:52 +0100 Subject: [PATCH 2/2] Document the StringNullWhenEmpty type --- msgraph/valuetypes.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/msgraph/valuetypes.go b/msgraph/valuetypes.go index 8d5b7573..41d40787 100644 --- a/msgraph/valuetypes.go +++ b/msgraph/valuetypes.go @@ -2,6 +2,9 @@ package msgraph import "encoding/json" +// StringNullWhenEmpty is a string type that marshals its JSON representation as null when set to its zero value. +// Can be used with a pointer reference with the `omitempty` tag to omit a field when the pointer is nil, but send a +// JSON null value when the string is empty. type StringNullWhenEmpty string func (s StringNullWhenEmpty) MarshalJSON() ([]byte, error) {