From 0213dce67c89dbd792b1b3b32c4012b97c2d2cd2 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Tue, 10 Aug 2021 14:17:47 +0100 Subject: [PATCH 01/10] Use `io` package in favor of `ioutil` for Go 1.16 --- msgraph/app_role_assignments.go | 10 +++---- msgraph/applications.go | 44 ++++++++++++++--------------- msgraph/conditionalaccesspolicy.go | 14 ++++----- msgraph/directory_audit_reports.go | 10 +++---- msgraph/directory_role_templates.go | 10 +++---- msgraph/directory_roles.go | 22 +++++++-------- msgraph/domains.go | 10 +++---- msgraph/groups.go | 44 ++++++++++++++--------------- msgraph/identity_providers.go | 18 ++++++------ msgraph/invitations.go | 6 ++-- msgraph/me.go | 10 +++---- msgraph/namedlocations.go | 26 ++++++++--------- msgraph/reports.go | 26 ++++++++--------- msgraph/schema_extensions.go | 14 ++++----- msgraph/serviceprincipals.go | 40 +++++++++++++------------- msgraph/sign_in_reports.go | 10 +++---- msgraph/users.go | 32 ++++++++++----------- 17 files changed, 173 insertions(+), 173 deletions(-) diff --git a/msgraph/app_role_assignments.go b/msgraph/app_role_assignments.go index f6491f46..b32172b6 100644 --- a/msgraph/app_role_assignments.go +++ b/msgraph/app_role_assignments.go @@ -4,7 +4,7 @@ import ( "context" "encoding/json" "fmt" - "io/ioutil" + "io" "net/http" ) @@ -59,9 +59,9 @@ func (c *AppRoleAssignmentsClient) List(ctx context.Context, id string) (*[]AppR return nil, status, fmt.Errorf("AppRoleAssignmentsClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var data struct { AppRoleAssignments []AppRoleAssignment `json:"value"` @@ -118,9 +118,9 @@ func (c *AppRoleAssignmentsClient) Assign(ctx context.Context, clientServicePrin return nil, status, fmt.Errorf("AppRoleAssignmentsClient.BaseClient.Post(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var appRoleAssignment AppRoleAssignment if err := json.Unmarshal(respBody, &appRoleAssignment); err != nil { diff --git a/msgraph/applications.go b/msgraph/applications.go index 0c0a9cb9..fd3b04a1 100644 --- a/msgraph/applications.go +++ b/msgraph/applications.go @@ -5,7 +5,7 @@ import ( "encoding/json" "errors" "fmt" - "io/ioutil" + "io" "net/http" "github.com/manicminer/hamilton/odata" @@ -38,9 +38,9 @@ func (c *ApplicationsClient) List(ctx context.Context, query odata.Query) (*[]Ap return nil, status, fmt.Errorf("ApplicationsClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var data struct { Applications []Application `json:"value"` @@ -70,9 +70,9 @@ func (c *ApplicationsClient) Create(ctx context.Context, application Application return nil, status, fmt.Errorf("ApplicationsClient.BaseClient.Post(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var newApplication Application if err := json.Unmarshal(respBody, &newApplication); err != nil { @@ -96,9 +96,9 @@ func (c *ApplicationsClient) Get(ctx context.Context, id string, query odata.Que return nil, status, fmt.Errorf("ApplicationsClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var application Application if err := json.Unmarshal(respBody, &application); err != nil { @@ -123,9 +123,9 @@ func (c *ApplicationsClient) GetDeleted(ctx context.Context, id string, query od return nil, status, fmt.Errorf("ApplicationsClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var application Application if err := json.Unmarshal(respBody, &application); err != nil { @@ -207,7 +207,7 @@ func (c *ApplicationsClient) ListDeleted(ctx context.Context, query odata.Query) return nil, status, err } defer resp.Body.Close() - respBody, _ := ioutil.ReadAll(resp.Body) + respBody, _ := io.ReadAll(resp.Body) var data struct { DeletedApps []Application `json:"value"` } @@ -232,9 +232,9 @@ func (c *ApplicationsClient) RestoreDeleted(ctx context.Context, id string) (*Ap return nil, status, fmt.Errorf("ApplicationsClient.BaseClient.Post(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var restoredApplication Application if err = json.Unmarshal(respBody, &restoredApplication); err != nil { @@ -267,9 +267,9 @@ func (c *ApplicationsClient) AddPassword(ctx context.Context, applicationId stri return nil, status, fmt.Errorf("ApplicationsClient.BaseClient.Post(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var newPasswordCredential PasswordCredential if err := json.Unmarshal(respBody, &newPasswordCredential); err != nil { @@ -320,9 +320,9 @@ func (c *ApplicationsClient) ListOwners(ctx context.Context, id string) (*[]stri return nil, status, fmt.Errorf("ApplicationsClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var data struct { Owners []struct { @@ -357,9 +357,9 @@ func (c *ApplicationsClient) GetOwner(ctx context.Context, applicationId, ownerI return nil, status, fmt.Errorf("ApplicationsClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var data struct { Context string `json:"@odata.context"` @@ -474,9 +474,9 @@ func (c *ApplicationsClient) ListExtensions(ctx context.Context, id string, quer return nil, status, fmt.Errorf("ApplicationsClient.BaseClient.List(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var data struct { @@ -507,9 +507,9 @@ func (c *ApplicationsClient) CreateExtension(ctx context.Context, applicationExt return nil, status, fmt.Errorf("ApplicationsClient.BaseClient.Post(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var newApplicationExtension ApplicationExtension diff --git a/msgraph/conditionalaccesspolicy.go b/msgraph/conditionalaccesspolicy.go index 99f95d0c..db9d98ae 100644 --- a/msgraph/conditionalaccesspolicy.go +++ b/msgraph/conditionalaccesspolicy.go @@ -5,7 +5,7 @@ import ( "encoding/json" "errors" "fmt" - "io/ioutil" + "io" "net/http" "github.com/manicminer/hamilton/odata" @@ -38,9 +38,9 @@ func (c *ConditionalAccessPolicyClient) List(ctx context.Context, query odata.Qu return nil, status, fmt.Errorf("ConditionalAccessPolicyClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var data struct { ConditionalAccessPolicys []ConditionalAccessPolicy `json:"value"` @@ -70,9 +70,9 @@ func (c *ConditionalAccessPolicyClient) Create(ctx context.Context, conditionalA return nil, status, fmt.Errorf("ConditionalAccessPolicyClient.BaseClient.Post(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var newConditionalAccessPolicy ConditionalAccessPolicy if err := json.Unmarshal(respBody, &newConditionalAccessPolicy); err != nil { @@ -96,9 +96,9 @@ func (c *ConditionalAccessPolicyClient) Get(ctx context.Context, id string, quer return nil, status, fmt.Errorf("ConditionalAccessPolicyClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var conditionalAccessPolicy ConditionalAccessPolicy if err := json.Unmarshal(respBody, &conditionalAccessPolicy); err != nil { diff --git a/msgraph/directory_audit_reports.go b/msgraph/directory_audit_reports.go index 203b9a2f..1c6a69ff 100644 --- a/msgraph/directory_audit_reports.go +++ b/msgraph/directory_audit_reports.go @@ -4,7 +4,7 @@ import ( "context" "encoding/json" "fmt" - "io/ioutil" + "io" "net/http" "github.com/manicminer/hamilton/odata" @@ -37,9 +37,9 @@ func (c *DirectoryAuditReportsClient) List(ctx context.Context, query odata.Quer return nil, status, fmt.Errorf("DirectoryAuditReportsClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var data struct { DirectoryAuditReports []DirectoryAudit `json:"value"` @@ -65,9 +65,9 @@ func (c *DirectoryAuditReportsClient) Get(ctx context.Context, id string, query return nil, status, fmt.Errorf("DirectoryAuditReportsClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var directoryAuditReport DirectoryAudit if err := json.Unmarshal(respBody, &directoryAuditReport); err != nil { diff --git a/msgraph/directory_role_templates.go b/msgraph/directory_role_templates.go index cf9c7464..f719f6bc 100644 --- a/msgraph/directory_role_templates.go +++ b/msgraph/directory_role_templates.go @@ -4,7 +4,7 @@ import ( "context" "encoding/json" "fmt" - "io/ioutil" + "io" "net/http" ) @@ -33,9 +33,9 @@ func (c *DirectoryRoleTemplatesClient) List(ctx context.Context) (*[]DirectoryRo return nil, status, fmt.Errorf("DirectoryRoleTemplatesClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var data struct { DirectoryRoleTemplates []DirectoryRoleTemplate `json:"value"` @@ -60,9 +60,9 @@ func (c *DirectoryRoleTemplatesClient) Get(ctx context.Context, id string) (*Dir return nil, status, fmt.Errorf("DirectoryRoleTemplatesClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var dirRoleTemplate DirectoryRoleTemplate if err := json.Unmarshal(respBody, &dirRoleTemplate); err != nil { diff --git a/msgraph/directory_roles.go b/msgraph/directory_roles.go index 1a9c9c9d..94bb0500 100644 --- a/msgraph/directory_roles.go +++ b/msgraph/directory_roles.go @@ -5,7 +5,7 @@ import ( "encoding/json" "errors" "fmt" - "io/ioutil" + "io" "net/http" "github.com/manicminer/hamilton/odata" @@ -36,9 +36,9 @@ func (c *DirectoryRolesClient) List(ctx context.Context) (*[]DirectoryRole, int, return nil, status, fmt.Errorf("DirectoryRolesClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var data struct { DirectoryRoles []DirectoryRole `json:"value"` @@ -62,9 +62,9 @@ func (c *DirectoryRolesClient) Get(ctx context.Context, id string) (*DirectoryRo return nil, status, fmt.Errorf("DirectoryRolesClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var dirRole DirectoryRole if err := json.Unmarshal(respBody, &dirRole); err != nil { @@ -88,9 +88,9 @@ func (c *DirectoryRolesClient) ListMembers(ctx context.Context, id string) (*[]s return nil, status, fmt.Errorf("DirectoryRolesClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var data struct { Members []struct { @@ -201,9 +201,9 @@ func (c *DirectoryRolesClient) GetMember(ctx context.Context, directoryRoleId, m return nil, status, fmt.Errorf("DirectoryRolesClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var data struct { Context string `json:"@odata.context"` @@ -255,9 +255,9 @@ func (c *DirectoryRolesClient) Activate(ctx context.Context, roleTemplateID stri return nil, status, fmt.Errorf("DirectoryRolesClient.BaseClient.Post(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var newDirRole DirectoryRole if err := json.Unmarshal(respBody, &newDirRole); err != nil { diff --git a/msgraph/domains.go b/msgraph/domains.go index 35caff51..e10762d9 100644 --- a/msgraph/domains.go +++ b/msgraph/domains.go @@ -4,7 +4,7 @@ import ( "context" "encoding/json" "fmt" - "io/ioutil" + "io" "net/http" "github.com/manicminer/hamilton/odata" @@ -39,9 +39,9 @@ func (c *DomainsClient) List(ctx context.Context, query odata.Query) (*[]Domain, } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var data struct { @@ -71,9 +71,9 @@ func (c *DomainsClient) Get(ctx context.Context, id string, query odata.Query) ( return nil, status, fmt.Errorf("DomainsClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var domain Domain if err := json.Unmarshal(respBody, &domain); err != nil { diff --git a/msgraph/groups.go b/msgraph/groups.go index a2d1f6eb..fcde6be7 100644 --- a/msgraph/groups.go +++ b/msgraph/groups.go @@ -4,7 +4,7 @@ import ( "context" "encoding/json" "fmt" - "io/ioutil" + "io" "net/http" "github.com/manicminer/hamilton/odata" @@ -37,9 +37,9 @@ func (c *GroupsClient) List(ctx context.Context, query odata.Query) (*[]Group, i return nil, status, fmt.Errorf("GroupsClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var data struct { Groups []Group `json:"value"` @@ -69,9 +69,9 @@ func (c *GroupsClient) Create(ctx context.Context, group Group) (*Group, int, er return nil, status, fmt.Errorf("GroupsClient.BaseClient.Post(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var newGroup Group if err := json.Unmarshal(respBody, &newGroup); err != nil { @@ -95,9 +95,9 @@ func (c *GroupsClient) Get(ctx context.Context, id string, query odata.Query) (* return nil, status, fmt.Errorf("GroupsClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var group Group if err := json.Unmarshal(respBody, &group); err != nil { @@ -137,9 +137,9 @@ func (c *GroupsClient) GetWithSchemaExtensions(ctx context.Context, id string, q return nil, status, fmt.Errorf("GroupsClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } group.SchemaExtensions = schemaExtensions @@ -164,9 +164,9 @@ func (c *GroupsClient) GetDeleted(ctx context.Context, id string, query odata.Qu return nil, status, fmt.Errorf("GroupsClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var group Group if err := json.Unmarshal(respBody, &group); err != nil { @@ -244,7 +244,7 @@ func (c *GroupsClient) ListDeleted(ctx context.Context, query odata.Query) (*[]G return nil, status, err } defer resp.Body.Close() - respBody, _ := ioutil.ReadAll(resp.Body) + respBody, _ := io.ReadAll(resp.Body) var data struct { DeletedGroups []Group `json:"value"` } @@ -268,9 +268,9 @@ func (c *GroupsClient) RestoreDeleted(ctx context.Context, id string) (*Group, i return nil, status, fmt.Errorf("GroupsClient.BaseClient.Post(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var restoredGroup Group if err = json.Unmarshal(respBody, &restoredGroup); err != nil { @@ -295,9 +295,9 @@ func (c *GroupsClient) ListMembers(ctx context.Context, id string) (*[]string, i return nil, status, fmt.Errorf("GroupsClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var data struct { Members []struct { @@ -332,9 +332,9 @@ func (c *GroupsClient) GetMember(ctx context.Context, groupId, memberId string) return nil, status, fmt.Errorf("GroupsClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var data struct { Context string `json:"@odata.context"` @@ -458,9 +458,9 @@ func (c *GroupsClient) ListOwners(ctx context.Context, id string) (*[]string, in return nil, status, fmt.Errorf("GroupsClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var data struct { Owners []struct { @@ -495,9 +495,9 @@ func (c *GroupsClient) GetOwner(ctx context.Context, groupId, ownerId string) (* return nil, status, fmt.Errorf("GroupsClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var data struct { Context string `json:"@odata.context"` diff --git a/msgraph/identity_providers.go b/msgraph/identity_providers.go index 79652e91..12978031 100644 --- a/msgraph/identity_providers.go +++ b/msgraph/identity_providers.go @@ -5,7 +5,7 @@ import ( "encoding/json" "errors" "fmt" - "io/ioutil" + "io" "net/http" ) @@ -34,9 +34,9 @@ func (c *IdentityProvidersClient) List(ctx context.Context) (*[]IdentityProvider return nil, status, fmt.Errorf("IdentityProvidersClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var data struct { IdentityProviders []IdentityProvider `json:"value"` @@ -66,9 +66,9 @@ func (c *IdentityProvidersClient) Create(ctx context.Context, provider IdentityP return nil, status, fmt.Errorf("IdentityProvidersClient.BaseClient.Post(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var newProvider IdentityProvider if err := json.Unmarshal(respBody, &newProvider); err != nil { @@ -91,9 +91,9 @@ func (c *IdentityProvidersClient) Get(ctx context.Context, id string) (*Identity return nil, status, fmt.Errorf("IdentityProvidersClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var provider IdentityProvider if err := json.Unmarshal(respBody, &provider); err != nil { @@ -156,9 +156,9 @@ func (c *IdentityProvidersClient) ListAvailableProviderTypes(ctx context.Context return nil, status, fmt.Errorf("IdentityProvidersClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var data struct { IdentityProviderTypes []string `json:"value"` diff --git a/msgraph/invitations.go b/msgraph/invitations.go index 26b2ddd4..f986fd7f 100644 --- a/msgraph/invitations.go +++ b/msgraph/invitations.go @@ -4,7 +4,7 @@ import ( "context" "encoding/json" "fmt" - "io/ioutil" + "io" "net/http" ) @@ -39,9 +39,9 @@ func (c *InvitationsClient) Create(ctx context.Context, invitation Invitation) ( return nil, status, fmt.Errorf("InvitationsClient.BaseClient.Post(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var newInvitation Invitation if err := json.Unmarshal(respBody, &newInvitation); err != nil { diff --git a/msgraph/me.go b/msgraph/me.go index 7e390323..6abac353 100644 --- a/msgraph/me.go +++ b/msgraph/me.go @@ -4,7 +4,7 @@ import ( "context" "encoding/json" "fmt" - "io/ioutil" + "io" "net/http" "github.com/manicminer/hamilton/odata" @@ -37,9 +37,9 @@ func (c *MeClient) Get(ctx context.Context, query odata.Query) (*Me, int, error) return nil, status, fmt.Errorf("MeClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var me Me if err := json.Unmarshal(respBody, &me); err != nil { @@ -63,9 +63,9 @@ func (c *MeClient) GetProfile(ctx context.Context, query odata.Query) (*Me, int, return nil, status, fmt.Errorf("MeClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var me Me if err := json.Unmarshal(respBody, &me); err != nil { diff --git a/msgraph/namedlocations.go b/msgraph/namedlocations.go index 96bfcf55..b2acf753 100644 --- a/msgraph/namedlocations.go +++ b/msgraph/namedlocations.go @@ -4,7 +4,7 @@ import ( "context" "encoding/json" "fmt" - "io/ioutil" + "io" "net/http" "github.com/manicminer/hamilton/internal/utils" @@ -40,9 +40,9 @@ func (c *NamedLocationsClient) List(ctx context.Context, query odata.Query) (*[] } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var data struct { @@ -127,9 +127,9 @@ func (c *NamedLocationsClient) CreateIP(ctx context.Context, ipNamedLocation IPN return nil, status, fmt.Errorf("NamedLocationsClient.BaseClient.Post(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var newIPNamedLocation IPNamedLocation if err := json.Unmarshal(respBody, &newIPNamedLocation); err != nil { @@ -160,9 +160,9 @@ func (c *NamedLocationsClient) CreateCountry(ctx context.Context, countryNamedLo return nil, status, fmt.Errorf("NamedLocationsClient.BaseClient.Post(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var newCountryNamedLocation CountryNamedLocation if err := json.Unmarshal(respBody, &newCountryNamedLocation); err != nil { @@ -186,9 +186,9 @@ func (c *NamedLocationsClient) GetIP(ctx context.Context, id string, query odata return nil, status, fmt.Errorf("NamedLocationsClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var ipNamedLocation IPNamedLocation if err := json.Unmarshal(respBody, &ipNamedLocation); err != nil { @@ -212,9 +212,9 @@ func (c *NamedLocationsClient) Get(ctx context.Context, id string, query odata.Q return nil, status, fmt.Errorf("NamedLocationsClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var o odata.OData @@ -264,9 +264,9 @@ func (c *NamedLocationsClient) GetCountry(ctx context.Context, id string, query return nil, status, fmt.Errorf("NamedLocationsClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var countryNamedLocation CountryNamedLocation if err := json.Unmarshal(respBody, &countryNamedLocation); err != nil { diff --git a/msgraph/reports.go b/msgraph/reports.go index 62d3a799..fba44ad1 100644 --- a/msgraph/reports.go +++ b/msgraph/reports.go @@ -4,7 +4,7 @@ import ( "context" "encoding/json" "fmt" - "io/ioutil" + "io" "net/http" "github.com/manicminer/hamilton/odata" @@ -36,9 +36,9 @@ func (c *ReportsClient) GetCredentialUserRegistrationCount(ctx context.Context, return nil, status, fmt.Errorf("ReportsClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var data struct { CredentialUserRegistrationCount []CredentialUserRegistrationCount `json:"value"` @@ -63,9 +63,9 @@ func (c *ReportsClient) GetCredentialUserRegistrationDetails(ctx context.Context return nil, status, fmt.Errorf("ReportsClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var data struct { CredentialUserRegistrationDetails []CredentialUserRegistrationDetails `json:"value"` @@ -90,9 +90,9 @@ func (c *ReportsClient) GetUserCredentialUsageDetails(ctx context.Context, query return nil, status, fmt.Errorf("ReportsClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var data struct { UserCredentialUsageDetails []UserCredentialUsageDetails `json:"value"` @@ -117,9 +117,9 @@ func (c *ReportsClient) GetCredentialUsageSummary(ctx context.Context, period Cr return nil, status, fmt.Errorf("ReportsClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var data struct { CredentialUsageSummary []CredentialUsageSummary `json:"value"` @@ -144,9 +144,9 @@ func (c *ReportsClient) GetAuthenticationMethodsUsersRegisteredByFeature(ctx con return nil, status, fmt.Errorf("ReportsClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var userRegistrationFeatureSummary UserRegistrationFeatureSummary @@ -171,9 +171,9 @@ func (c *ReportsClient) GetAuthenticationMethodsUsersRegisteredByMethod(ctx cont return nil, status, fmt.Errorf("ReportsClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var userRegistrationMethodSummary UserRegistrationMethodSummary diff --git a/msgraph/schema_extensions.go b/msgraph/schema_extensions.go index 4a1ea75d..b5764941 100644 --- a/msgraph/schema_extensions.go +++ b/msgraph/schema_extensions.go @@ -4,7 +4,7 @@ import ( "context" "encoding/json" "fmt" - "io/ioutil" + "io" "net/http" "github.com/manicminer/hamilton/odata" @@ -37,9 +37,9 @@ func (c *SchemaExtensionsClient) List(ctx context.Context, query odata.Query) (* return nil, status, fmt.Errorf("SchemaExtensionsClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var data struct { SchemaExtensions []SchemaExtension `json:"value"` @@ -65,9 +65,9 @@ func (c *SchemaExtensionsClient) Get(ctx context.Context, id string, query odata return nil, status, fmt.Errorf("SchemaExtensionsClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var schemaExtension SchemaExtension if err := json.Unmarshal(respBody, &schemaExtension); err != nil { @@ -117,9 +117,9 @@ func (c *SchemaExtensionsClient) Create(ctx context.Context, schemaExtension Sch return nil, status, fmt.Errorf("SchemaExtensionsClient.BaseClient.Post(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var newSchemaExtension SchemaExtension if err := json.Unmarshal(respBody, &newSchemaExtension); err != nil { diff --git a/msgraph/serviceprincipals.go b/msgraph/serviceprincipals.go index 85efe6bf..0b0aa9f2 100644 --- a/msgraph/serviceprincipals.go +++ b/msgraph/serviceprincipals.go @@ -5,7 +5,7 @@ import ( "encoding/json" "errors" "fmt" - "io/ioutil" + "io" "net/http" "github.com/manicminer/hamilton/odata" @@ -38,9 +38,9 @@ func (c *ServicePrincipalsClient) List(ctx context.Context, query odata.Query) ( return nil, status, fmt.Errorf("ServicePrincipalsClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var data struct { ServicePrincipals []ServicePrincipal `json:"value"` @@ -74,9 +74,9 @@ func (c *ServicePrincipalsClient) Create(ctx context.Context, servicePrincipal S return nil, status, fmt.Errorf("ServicePrincipalsClient.BaseClient.Post(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var newServicePrincipal ServicePrincipal if err := json.Unmarshal(respBody, &newServicePrincipal); err != nil { @@ -100,9 +100,9 @@ func (c *ServicePrincipalsClient) Get(ctx context.Context, id string, query odat return nil, status, fmt.Errorf("ServicePrincipalsClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var servicePrincipal ServicePrincipal if err := json.Unmarshal(respBody, &servicePrincipal); err != nil { @@ -168,9 +168,9 @@ func (c *ServicePrincipalsClient) ListOwners(ctx context.Context, id string) (*[ return nil, status, fmt.Errorf("ServicePrincipalsClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var data struct { Owners []struct { @@ -205,9 +205,9 @@ func (c *ServicePrincipalsClient) GetOwner(ctx context.Context, servicePrincipal return nil, status, fmt.Errorf("ServicePrincipalsClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var data struct { Context string `json:"@odata.context"` @@ -323,9 +323,9 @@ func (c *ServicePrincipalsClient) ListGroupMemberships(ctx context.Context, id s return nil, status, fmt.Errorf("ServicePrincipalsClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var data struct { Groups []Group `json:"value"` @@ -360,9 +360,9 @@ func (c *ServicePrincipalsClient) AddPassword(ctx context.Context, servicePrinci return nil, status, fmt.Errorf("ServicePrincipalsClient.BaseClient.Post(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var newPasswordCredential PasswordCredential if err := json.Unmarshal(respBody, &newPasswordCredential); err != nil { @@ -413,7 +413,7 @@ func (c *ServicePrincipalsClient) ListOwnedObjects(ctx context.Context, id strin return nil, status, err } defer resp.Body.Close() - respBody, _ := ioutil.ReadAll(resp.Body) + respBody, _ := io.ReadAll(resp.Body) var data struct { OwnedObjects []struct { Type string `json:"@odata.type"` @@ -445,9 +445,9 @@ func (c *ServicePrincipalsClient) ListAppRoleAssignments(ctx context.Context, re return nil, status, fmt.Errorf("ServicePrincipalsClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var data struct { AppRoleAssignments []AppRoleAssignment `json:"value"` @@ -509,9 +509,9 @@ func (c *ServicePrincipalsClient) AssignAppRoleForResource(ctx context.Context, return nil, status, fmt.Errorf("ServicePrincipalsClient.BaseClient.Post(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var appRoleAssignment AppRoleAssignment if err := json.Unmarshal(respBody, &appRoleAssignment); err != nil { diff --git a/msgraph/sign_in_reports.go b/msgraph/sign_in_reports.go index bd4f9060..dd47698a 100644 --- a/msgraph/sign_in_reports.go +++ b/msgraph/sign_in_reports.go @@ -4,7 +4,7 @@ import ( "context" "encoding/json" "fmt" - "io/ioutil" + "io" "net/http" "github.com/manicminer/hamilton/odata" @@ -37,9 +37,9 @@ func (c *SignInReportsClient) List(ctx context.Context, query odata.Query) (*[]S return nil, status, fmt.Errorf("SignInLogsClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var data struct { SignInLogs []SignInReport `json:"value"` @@ -65,9 +65,9 @@ func (c *SignInReportsClient) Get(ctx context.Context, id string, query odata.Qu return nil, status, fmt.Errorf("SignInLogsClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var signInReport SignInReport if err := json.Unmarshal(respBody, &signInReport); err != nil { diff --git a/msgraph/users.go b/msgraph/users.go index 39680f61..52e742fc 100644 --- a/msgraph/users.go +++ b/msgraph/users.go @@ -4,7 +4,7 @@ import ( "context" "encoding/json" "fmt" - "io/ioutil" + "io" "net/http" "github.com/manicminer/hamilton/odata" @@ -37,9 +37,9 @@ func (c *UsersClient) List(ctx context.Context, query odata.Query) (*[]User, int return nil, status, fmt.Errorf("UsersClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var data struct { Users []User `json:"value"` @@ -69,9 +69,9 @@ func (c *UsersClient) Create(ctx context.Context, user User) (*User, int, error) return nil, status, fmt.Errorf("UsersClient.BaseClient.Post(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var newUser User if err := json.Unmarshal(respBody, &newUser); err != nil { @@ -95,9 +95,9 @@ func (c *UsersClient) Get(ctx context.Context, id string, query odata.Query) (*U return nil, status, fmt.Errorf("UsersClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var user User if err := json.Unmarshal(respBody, &user); err != nil { @@ -137,9 +137,9 @@ func (c *UsersClient) GetWithSchemaExtensions(ctx context.Context, id string, qu return nil, status, fmt.Errorf("UsersClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } user.SchemaExtensions = schemaExtensions @@ -164,9 +164,9 @@ func (c *UsersClient) GetDeleted(ctx context.Context, id string, query odata.Que return nil, status, fmt.Errorf("UsersClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var user User if err := json.Unmarshal(respBody, &user); err != nil { @@ -244,7 +244,7 @@ func (c *UsersClient) ListDeleted(ctx context.Context, query odata.Query) (*[]Us return nil, status, err } defer resp.Body.Close() - respBody, _ := ioutil.ReadAll(resp.Body) + respBody, _ := io.ReadAll(resp.Body) var data struct { DeletedUsers []User `json:"value"` } @@ -268,9 +268,9 @@ func (c *UsersClient) RestoreDeleted(ctx context.Context, id string) (*User, int return nil, status, fmt.Errorf("UsersClient.BaseClient.Post(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var restoredUser User if err = json.Unmarshal(respBody, &restoredUser); err != nil { @@ -295,9 +295,9 @@ func (c *UsersClient) ListGroupMemberships(ctx context.Context, id string, query return nil, status, fmt.Errorf("UsersClient.BaseClient.Get(): %v", err) } defer resp.Body.Close() - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, status, fmt.Errorf("ioutil.ReadAll(): %v", err) + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } var data struct { Groups []Group `json:"value"` From 31798fa5749f3d9a5188ca7b8d49d22cafb35a0f Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Thu, 12 Aug 2021 11:53:26 +0100 Subject: [PATCH 02/10] Support for Directory Objects - Adds a top level model struct for the directoryObject API base class - Embed this struct into other models to inherit the ID and odata fields - Support operations via the /directoryObjects endpoint - Improved handling of @odata.bind fields so that the tenant ID isn't needed to build odata URIs for objects --- msgraph/applications.go | 11 +- msgraph/applications_test.go | 41 ++++++- msgraph/directory_objects.go | 152 +++++++++++++++++++++++++ msgraph/directory_objects_test.go | 172 +++++++++++++++++++++++++++++ msgraph/directory_roles.go | 13 +-- msgraph/directory_roles_test.go | 2 +- msgraph/groups.go | 48 +++----- msgraph/groups_test.go | 17 ++- msgraph/identity_providers_test.go | 4 +- msgraph/models.go | 159 +++++++++++++------------- msgraph/namedlocations.go | 16 +-- msgraph/serviceprincipals.go | 13 +-- msgraph/serviceprincipals_test.go | 10 +- msgraph/users_test.go | 4 +- msgraph/valuetypes.go | 55 ++++++++- odata/odata.go | 35 +++++- 16 files changed, 592 insertions(+), 160 deletions(-) create mode 100644 msgraph/directory_objects.go create mode 100644 msgraph/directory_objects_test.go diff --git a/msgraph/applications.go b/msgraph/applications.go index fd3b04a1..9e0dd76f 100644 --- a/msgraph/applications.go +++ b/msgraph/applications.go @@ -373,8 +373,8 @@ func (c *ApplicationsClient) GetOwner(ctx context.Context, applicationId, ownerI return &data.Id, status, nil } -// AddOwners adds a new owner to an Application. -// First populate the Owners field of the Application using the AppendOwner method of the model, then call this method. +// AddOwners adds new owners to an Application. +// First populate the `owners` field, then call this method func (c *ApplicationsClient) AddOwners(ctx context.Context, application *Application) (int, error) { var status int if application.ID == nil { @@ -392,12 +392,7 @@ func (c *ApplicationsClient) AddOwners(ctx context.Context, application *Applica return false } - data := struct { - Owner string `json:"@odata.id"` - }{ - Owner: owner, - } - body, err := json.Marshal(data) + body, err := json.Marshal(DirectoryObject{ODataId: owner.ODataId}) if err != nil { return status, fmt.Errorf("json.Marshal(): %v", err) } diff --git a/msgraph/applications_test.go b/msgraph/applications_test.go index 0928524b..fafc8b51 100644 --- a/msgraph/applications_test.go +++ b/msgraph/applications_test.go @@ -18,15 +18,52 @@ type ApplicationsClientTest struct { } func TestApplicationsClient(t *testing.T) { + rs := test.RandomString() c := ApplicationsClientTest{ connection: test.NewConnection(auth.MsGraph, auth.TokenVersion2), - randomString: test.RandomString(), + randomString: rs, } c.client = msgraph.NewApplicationsClient(c.connection.AuthConfig.TenantID) c.client.BaseClient.Authorizer = c.connection.Authorizer + token, err := c.connection.Authorizer.Token() + if err != nil { + t.Fatalf("could not acquire access token: %v", err) + } + claims, err := auth.ParseClaims(token) + if err != nil { + t.Fatalf("could not parse claims: %v", err) + } + + u := UsersClientTest{ + connection: test.NewConnection(auth.MsGraph, auth.TokenVersion2), + randomString: rs, + } + u.client = msgraph.NewUsersClient(u.connection.AuthConfig.TenantID) + u.client.BaseClient.Authorizer = u.connection.Authorizer + + user := testUsersClient_Create(t, u, msgraph.User{ + AccountEnabled: utils.BoolPtr(true), + DisplayName: utils.StringPtr("test-user-applicationowner"), + MailNickname: utils.StringPtr(fmt.Sprintf("test-user-applicationowner-%s", c.randomString)), + UserPrincipalName: utils.StringPtr(fmt.Sprintf("test-user-applicationowner-%s@%s", c.randomString, c.connection.DomainName)), + PasswordProfile: &msgraph.UserPasswordProfile{ + Password: utils.StringPtr(fmt.Sprintf("IrPa55w0rd%s", c.randomString)), + }, + }) + + o := DirectoryObjectsClientTest{ + connection: test.NewConnection(auth.MsGraph, auth.TokenVersion2), + randomString: rs, + } + o.client = msgraph.NewDirectoryObjectsClient(c.connection.AuthConfig.TenantID) + o.client.BaseClient.Authorizer = o.connection.Authorizer + + self := testDirectoryObjectsClient_Get(t, o, claims.ObjectId) + app := testApplicationsClient_Create(t, c, msgraph.Application{ DisplayName: utils.StringPtr(fmt.Sprintf("test-application-%s", c.randomString)), + Owners: &msgraph.Owners{*self}, }) testApplicationsClient_Get(t, c, *app.ID) app.DisplayName = utils.StringPtr(fmt.Sprintf("test-app-updated-%s", c.randomString)) @@ -45,7 +82,7 @@ func TestApplicationsClient(t *testing.T) { owners := testApplicationsClient_ListOwners(t, c, *app.ID) testApplicationsClient_GetOwner(t, c, *app.ID, (*owners)[0]) testApplicationsClient_RemoveOwners(t, c, *app.ID, owners) - app.AppendOwner(c.client.BaseClient.Endpoint, c.client.BaseClient.ApiVersion, (*owners)[0]) + app.Owners = &msgraph.Owners{*user.DirectoryObject} testApplicationsClient_AddOwners(t, c, app) pwd := testApplicationsClient_AddPassword(t, c, app) testApplicationsClient_RemovePassword(t, c, app, pwd) diff --git a/msgraph/directory_objects.go b/msgraph/directory_objects.go new file mode 100644 index 00000000..9487cc9a --- /dev/null +++ b/msgraph/directory_objects.go @@ -0,0 +1,152 @@ +package msgraph + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + + "github.com/manicminer/hamilton/internal/utils" + "github.com/manicminer/hamilton/odata" +) + +// DirectoryObjectsClient performs operations on Directory Objects (the base type for other objects such as users and groups) +type DirectoryObjectsClient struct { + BaseClient Client +} + +// NewDirectoryObjectsClient returns a new DirectoryObjectsClient. +func NewDirectoryObjectsClient(tenantId string) *DirectoryObjectsClient { + return &DirectoryObjectsClient{ + BaseClient: NewClient(Version10, tenantId), + } +} + +// Get retrieves a DirectoryObject. +func (c *DirectoryObjectsClient) Get(ctx context.Context, id string, query odata.Query) (*DirectoryObject, int, error) { + resp, status, _, err := c.BaseClient.Get(ctx, GetHttpRequestInput{ + ConsistencyFailureFunc: RetryOn404ConsistencyFailureFunc, + ValidStatusCodes: []int{http.StatusOK}, + Uri: Uri{ + Entity: fmt.Sprintf("/directoryObjects/%s", id), + Params: query.Values(), + HasTenantId: true, + }, + }) + if err != nil { + return nil, status, fmt.Errorf("DirectoryObjects.BaseClient.Get(): %v", err) + } + defer resp.Body.Close() + respBody, err := io.ReadAll(resp.Body) + if err != nil { + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) + } + var directoryObject DirectoryObject + if err := json.Unmarshal(respBody, &directoryObject); err != nil { + return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) + } + return &directoryObject, status, nil +} + +// Delete removes a DirectoryObject. +func (c *DirectoryObjectsClient) Delete(ctx context.Context, id string) (int, error) { + _, status, _, err := c.BaseClient.Delete(ctx, DeleteHttpRequestInput{ + ConsistencyFailureFunc: RetryOn404ConsistencyFailureFunc, + ValidStatusCodes: []int{http.StatusNoContent}, + Uri: Uri{ + Entity: fmt.Sprintf("/directoryObjects/%s", id), + HasTenantId: true, + }, + }) + if err != nil { + return status, fmt.Errorf("DirectoryObjects.BaseClient.Get(): %v", err) + } + return status, nil +} + +// GetMemberGroups retrieves IDs of the groups and directory roles that a directory object is a member of. +// id is the object ID of the directory object. +func (c *DirectoryObjectsClient) GetMemberGroups(ctx context.Context, id string, securityEnabledOnly bool) (*[]DirectoryObject, int, error) { + var status int + body, err := json.Marshal(struct { + SecurityEnabledOnly bool `json:"securityEnabledOnly"` + }{ + SecurityEnabledOnly: securityEnabledOnly, + }) + if err != nil { + return nil, status, fmt.Errorf("json.Marshal(): %v", err) + } + resp, status, _, err := c.BaseClient.Post(ctx, PostHttpRequestInput{ + Body: body, + ConsistencyFailureFunc: RetryOn404ConsistencyFailureFunc, + ValidStatusCodes: []int{http.StatusOK}, + Uri: Uri{ + Entity: fmt.Sprintf("/directoryObjects/%s/getMemberGroups", id), + HasTenantId: false, + }, + }) + if err != nil { + return nil, status, fmt.Errorf("DirectoryObjectsClient.BaseClient.Post(): %v", err) + } + defer resp.Body.Close() + respBody, err := io.ReadAll(resp.Body) + if err != nil { + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) + } + var data struct { + IDs []string `json:"value"` + } + if err := json.Unmarshal(respBody, &data); err != nil { + return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) + } + + result := make([]DirectoryObject, len(data.IDs)) + for i, id := range data.IDs { + result[i].ID = utils.StringPtr(id) + } + return &result, status, nil +} + +// GetMemberObjects retrieves IDs of the groups and directory roles that a directory object is a member of. +// id is the object ID of the directory object. +func (c *DirectoryObjectsClient) GetMemberObjects(ctx context.Context, id string, securityEnabledOnly bool) (*[]DirectoryObject, int, error) { + var status int + body, err := json.Marshal(struct { + SecurityEnabledOnly bool `json:"securityEnabledOnly"` + }{ + SecurityEnabledOnly: securityEnabledOnly, + }) + if err != nil { + return nil, status, fmt.Errorf("json.Marshal(): %v", err) + } + resp, status, _, err := c.BaseClient.Post(ctx, PostHttpRequestInput{ + Body: body, + ConsistencyFailureFunc: RetryOn404ConsistencyFailureFunc, + ValidStatusCodes: []int{http.StatusOK}, + Uri: Uri{ + Entity: fmt.Sprintf("/directoryObjects/%s/getMemberObjects", id), + HasTenantId: false, + }, + }) + if err != nil { + return nil, status, fmt.Errorf("DirectoryObjectsClient.BaseClient.Post(): %v", err) + } + defer resp.Body.Close() + respBody, err := io.ReadAll(resp.Body) + if err != nil { + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) + } + var data struct { + IDs []string `json:"value"` + } + if err := json.Unmarshal(respBody, &data); err != nil { + return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) + } + + result := make([]DirectoryObject, len(data.IDs)) + for i, id := range data.IDs { + result[i].ID = utils.StringPtr(id) + } + return &result, status, nil +} diff --git a/msgraph/directory_objects_test.go b/msgraph/directory_objects_test.go new file mode 100644 index 00000000..7445d8e5 --- /dev/null +++ b/msgraph/directory_objects_test.go @@ -0,0 +1,172 @@ +package msgraph_test + +import ( + "fmt" + "testing" + + "github.com/manicminer/hamilton/auth" + "github.com/manicminer/hamilton/internal/test" + "github.com/manicminer/hamilton/internal/utils" + "github.com/manicminer/hamilton/msgraph" + "github.com/manicminer/hamilton/odata" +) + +type DirectoryObjectsClientTest struct { + connection *test.Connection + client *msgraph.DirectoryObjectsClient + randomString string +} + +func TestDirectoryObjectsClient(t *testing.T) { + rs := test.RandomString() + c := DirectoryObjectsClientTest{ + connection: test.NewConnection(auth.MsGraph, auth.TokenVersion2), + randomString: rs, + } + c.client = msgraph.NewDirectoryObjectsClient(c.connection.AuthConfig.TenantID) + c.client.BaseClient.Authorizer = c.connection.Authorizer + + g := GroupsClientTest{ + connection: test.NewConnection(auth.MsGraph, auth.TokenVersion2), + randomString: rs, + } + g.client = msgraph.NewGroupsClient(c.connection.AuthConfig.TenantID) + g.client.BaseClient.Authorizer = c.connection.Authorizer + + u := UsersClientTest{ + connection: test.NewConnection(auth.MsGraph, auth.TokenVersion2), + randomString: rs, + } + u.client = msgraph.NewUsersClient(c.connection.AuthConfig.TenantID) + u.client.BaseClient.Authorizer = c.connection.Authorizer + + user := testUsersClient_Create(t, u, msgraph.User{ + AccountEnabled: utils.BoolPtr(true), + DisplayName: utils.StringPtr("test-user"), + MailNickname: utils.StringPtr(fmt.Sprintf("test-user-directoryobject-%s", c.randomString)), + UserPrincipalName: utils.StringPtr(fmt.Sprintf("test-user-directoryobject-%s@%s", c.randomString, c.connection.DomainName)), + PasswordProfile: &msgraph.UserPasswordProfile{ + Password: utils.StringPtr(fmt.Sprintf("IrPa55w0rd%s", c.randomString)), + }, + }) + + newGroup1 := msgraph.Group{ + DisplayName: utils.StringPtr("test-group-directoryobject-member"), + MailEnabled: utils.BoolPtr(false), + MailNickname: utils.StringPtr(fmt.Sprintf("test-group-directoryobject-member-%s", c.randomString)), + SecurityEnabled: utils.BoolPtr(true), + } + newGroup1.Members = &msgraph.Members{*user.DirectoryObject} + group1 := testGroupsClient_Create(t, g, newGroup1) + + newGroup2 := msgraph.Group{ + DisplayName: utils.StringPtr("test-group-directoryobject"), + MailEnabled: utils.BoolPtr(false), + MailNickname: utils.StringPtr(fmt.Sprintf("test-group-directoryobject-%s", c.randomString)), + SecurityEnabled: utils.BoolPtr(true), + Members: &msgraph.Members{ + *group1.DirectoryObject, + *user.DirectoryObject, + }, + } + group2 := testGroupsClient_Create(t, g, newGroup2) + + testDirectoryObjectsClient_Get(t, c, *user.ID) + testDirectoryObjectsClient_Get(t, c, *group1.ID) + testDirectoryObjectsClient_GetMemberGroups(t, c, *user.ID, true, []string{*group1.ID, *group2.ID}) + testDirectoryObjectsClient_GetMemberObjects(t, c, *group1.ID, true, []string{*group2.ID}) + testDirectoryObjectsClient_Delete(t, c, *group1.ID) +} + +func testDirectoryObjectsClient_Get(t *testing.T, c DirectoryObjectsClientTest, id string) (directoryObject *msgraph.DirectoryObject) { + directoryObject, status, err := c.client.Get(c.connection.Context, id, odata.Query{}) + if err != nil { + t.Fatalf("DirectoryObjectsClient.Get(): %v", err) + } + if status < 200 || status >= 300 { + t.Fatalf("DirectoryObjectsClient.Get(): invalid status: %d", status) + } + if directoryObject == nil { + t.Fatal("DirectoryObjectsClient.Get(): directoryObject was nil") + } + if directoryObject.ID == nil { + t.Fatal("DirectoryObjectsClient.Get(): directoryObject ID was nil") + } + return +} + +func testDirectoryObjectsClient_GetMemberGroups(t *testing.T, c DirectoryObjectsClientTest, id string, securityEnabledOnly bool, expected []string) (directoryObjects *[]msgraph.DirectoryObject) { + directoryObjects, status, err := c.client.GetMemberGroups(c.connection.Context, id, securityEnabledOnly) + if err != nil { + t.Fatalf("DirectoryObjectsClient.GetMemberGroups(): %v", err) + } + if status < 200 || status >= 300 { + t.Fatalf("DirectoryObjectsClient.GetMemberGroups(): invalid status: %d", status) + } + if directoryObjects == nil { + t.Fatal("DirectoryObjectsClient.GetMemberGroups(): directoryObjects was nil") + } + if len(*directoryObjects) == 0 { + t.Fatal("DirectoryObjectsClient.GetMemberGroups(): directoryObjects was empty") + } + + expectedCount := len(expected) + if len(*directoryObjects) < expectedCount { + t.Fatalf("DirectoryObjectsClient.GetMemberGroups(): expected at least %d result. has: %d", expectedCount, len(*directoryObjects)) + } + var expectedFound int + for _, e := range expected { + for _, o := range *directoryObjects { + if o.ID != nil && e == *o.ID { + expectedFound++ + } + } + } + if expectedFound < expectedCount { + t.Fatalf("DirectoryObjectsClient.GetMemberGroups(): expected %d matching objects. found: %d", expectedCount, expectedFound) + } + return +} + +func testDirectoryObjectsClient_GetMemberObjects(t *testing.T, c DirectoryObjectsClientTest, id string, securityEnabledOnly bool, expected []string) (directoryObjects *[]msgraph.DirectoryObject) { + directoryObjects, status, err := c.client.GetMemberObjects(c.connection.Context, id, securityEnabledOnly) + if err != nil { + t.Fatalf("DirectoryObjectsClient.GetMemberObjects(): %v", err) + } + if status < 200 || status >= 300 { + t.Fatalf("DirectoryObjectsClient.GetMemberObjects(): invalid status: %d", status) + } + if directoryObjects == nil { + t.Fatal("DirectoryObjectsClient.GetMemberObjects(): directoryObjects was nil") + } + if len(*directoryObjects) == 0 { + t.Fatal("DirectoryObjectsClient.GetMemberObjects(): directoryObjects was empty") + } + + expectedCount := len(expected) + if len(*directoryObjects) < expectedCount { + t.Fatalf("DirectoryObjectsClient.GetMemberObjects(): expected at least %d result. has: %d", expectedCount, len(*directoryObjects)) + } + var expectedFound int + for _, e := range expected { + for _, o := range *directoryObjects { + if o.ID != nil && e == *o.ID { + expectedFound++ + } + } + } + if expectedFound < expectedCount { + t.Fatalf("DirectoryObjectsClient.GetMemberObjects(): expected %d matching objects. found: %d", expectedCount, expectedFound) + } + return +} + +func testDirectoryObjectsClient_Delete(t *testing.T, c DirectoryObjectsClientTest, id string) { + status, err := c.client.Delete(c.connection.Context, id) + if err != nil { + t.Fatalf("DirectoryObjectsClient.Delete(): %v", err) + } + if status < 200 || status >= 300 { + t.Fatalf("DirectoryObjectsClient.Delete(): invalid status: %d", status) + } +} diff --git a/msgraph/directory_roles.go b/msgraph/directory_roles.go index 94bb0500..73486494 100644 --- a/msgraph/directory_roles.go +++ b/msgraph/directory_roles.go @@ -108,8 +108,8 @@ func (c *DirectoryRolesClient) ListMembers(ctx context.Context, id string) (*[]s return &ret, status, nil } -// AddMembers adds a new member to a Directory Role. -// First populate the Members field of the DirectoryRole using the AppendMember method of the model, then call this method. +// AddMembers adds new members to a Directory Role. +// First populate the `members` field, then call this method func (c *DirectoryRolesClient) AddMembers(ctx context.Context, directoryRole *DirectoryRole) (int, error) { var status int if directoryRole.ID == nil { @@ -129,12 +129,11 @@ func (c *DirectoryRolesClient) AddMembers(ctx context.Context, directoryRole *Di return false } - data := struct { - Member string `json:"@odata.id"` + body, err := json.Marshal(struct { + Member odata.Id `json:"@odata.id"` }{ - Member: member, - } - body, err := json.Marshal(data) + Member: *member.ODataId, + }) if err != nil { return status, fmt.Errorf("json.Marshal(): %v", err) } diff --git a/msgraph/directory_roles_test.go b/msgraph/directory_roles_test.go index ad7ec20e..4ae2c7da 100644 --- a/msgraph/directory_roles_test.go +++ b/msgraph/directory_roles_test.go @@ -52,7 +52,7 @@ func TestDirectoryRolesClient(t *testing.T) { group := testGroupsClient_Create(t, groupsClient, newGroup) // add the test group as a member of directory role - directoryRole.AppendMember(dirRolesClient.client.BaseClient.Endpoint, dirRolesClient.client.BaseClient.ApiVersion, *group.ID) + directoryRole.Members = &msgraph.Members{*group.DirectoryObject} testDirectoryRolesClient_AddMembers(t, dirRolesClient, &directoryRole) // list members of the directory role; then remove the added group member to clean up diff --git a/msgraph/groups.go b/msgraph/groups.go index fcde6be7..8997944c 100644 --- a/msgraph/groups.go +++ b/msgraph/groups.go @@ -348,27 +348,15 @@ func (c *GroupsClient) GetMember(ctx context.Context, groupId, memberId string) return &data.Id, status, nil } -// AddMembers adds a new member to a Group. -// First populate the Members field of the Group using the AppendMember method of the model, then call this method. +// AddMembers adds new members to a Group. +// First populate the `members` field, then call this method func (c *GroupsClient) AddMembers(ctx context.Context, group *Group) (int, error) { var status int - // Patching group members support up to 20 members per request - var memberChunks [][]string if group.Members == nil || len(*group.Members) == 0 { return status, fmt.Errorf("no members specified") } - members := *group.Members - max := len(members) - // Chunk into slices of 20 for batching - for i := 0; i < max; i += 20 { - end := i + 20 - if end > max { - end = max - } - memberChunks = append(memberChunks, members[i:end]) - } - for _, members := range memberChunks { - // don't fail if a member already exists + for _, member := range *group.Members { + // don't fail if an member already exists checkMemberAlreadyExists := func(resp *http.Response, o *odata.OData) bool { if resp.StatusCode == http.StatusBadRequest && o.Error != nil { return o.Error.Match(odata.ErrorAddedObjectReferencesAlreadyExist) @@ -376,25 +364,26 @@ func (c *GroupsClient) AddMembers(ctx context.Context, group *Group) (int, error return false } - data := Group{ - Members: &members, - } - body, err := json.Marshal(data) + body, err := json.Marshal(struct { + Member odata.Id `json:"@odata.id"` + }{ + Member: *member.ODataId, + }) if err != nil { return status, fmt.Errorf("json.Marshal(): %v", err) } - _, status, _, err = c.BaseClient.Patch(ctx, PatchHttpRequestInput{ + _, status, _, err = c.BaseClient.Post(ctx, PostHttpRequestInput{ Body: body, ConsistencyFailureFunc: RetryOn404ConsistencyFailureFunc, ValidStatusCodes: []int{http.StatusNoContent}, ValidStatusFunc: checkMemberAlreadyExists, Uri: Uri{ - Entity: fmt.Sprintf("/groups/%s", *group.ID), + Entity: fmt.Sprintf("/groups/%s/members/$ref", *group.ID), HasTenantId: true, }, }) if err != nil { - return status, fmt.Errorf("GroupsClient.BaseClient.Patch(): %v", err) + return status, fmt.Errorf("GroupsClient.BaseClient.Post(): %v", err) } } return status, nil @@ -511,8 +500,8 @@ func (c *GroupsClient) GetOwner(ctx context.Context, groupId, ownerId string) (* return &data.Id, status, nil } -// AddOwners adds a new owner to a Group. -// First populate the Owners field of the Group using the AppendOwner method of the model, then call this method. +// AddOwners adds new owners to a Group. +// First populate the `owners` field, then call this method func (c *GroupsClient) AddOwners(ctx context.Context, group *Group) (int, error) { var status int if group.Owners == nil || len(*group.Owners) == 0 { @@ -527,12 +516,11 @@ func (c *GroupsClient) AddOwners(ctx context.Context, group *Group) (int, error) return false } - data := struct { - Owner string `json:"@odata.id"` + body, err := json.Marshal(struct { + Owner odata.Id `json:"@odata.id"` }{ - Owner: owner, - } - body, err := json.Marshal(data) + Owner: *owner.ODataId, + }) if err != nil { return status, fmt.Errorf("json.Marshal(): %v", err) } diff --git a/msgraph/groups_test.go b/msgraph/groups_test.go index 88be8016..7b749097 100644 --- a/msgraph/groups_test.go +++ b/msgraph/groups_test.go @@ -42,14 +42,23 @@ func TestGroupsClient(t *testing.T) { u.client = msgraph.NewUsersClient(c.connection.AuthConfig.TenantID) u.client.BaseClient.Authorizer = c.connection.Authorizer + o := DirectoryObjectsClientTest{ + connection: test.NewConnection(auth.MsGraph, auth.TokenVersion2), + randomString: rs, + } + o.client = msgraph.NewDirectoryObjectsClient(c.connection.AuthConfig.TenantID) + o.client.BaseClient.Authorizer = o.connection.Authorizer + + self := testDirectoryObjectsClient_Get(t, o, claims.ObjectId) + newGroup := msgraph.Group{ DisplayName: utils.StringPtr("test-group"), MailEnabled: utils.BoolPtr(false), MailNickname: utils.StringPtr(fmt.Sprintf("test-group-%s", c.randomString)), SecurityEnabled: utils.BoolPtr(true), + Owners: &msgraph.Owners{*self}, + Members: &msgraph.Members{*self}, } - newGroup.AppendOwner(c.client.BaseClient.Endpoint, c.client.BaseClient.ApiVersion, claims.ObjectId) - newGroup.AppendMember(c.client.BaseClient.Endpoint, c.client.BaseClient.ApiVersion, claims.ObjectId) group := testGroupsClient_Create(t, c, newGroup) testGroupsClient_Get(t, c, *group.ID) @@ -72,11 +81,11 @@ func TestGroupsClient(t *testing.T) { }, }) - group.AppendOwner(c.client.BaseClient.Endpoint, c.client.BaseClient.ApiVersion, *user.ID) + group.Owners = &msgraph.Owners{*user.DirectoryObject} testGroupsClient_AddOwners(t, c, group) testGroupsClient_RemoveOwners(t, c, *group.ID, &([]string{claims.ObjectId})) - group.AppendMember(c.client.BaseClient.Endpoint, c.client.BaseClient.ApiVersion, *user.ID) + group.Members = &msgraph.Members{*user.DirectoryObject} testGroupsClient_AddMembers(t, c, group) testGroupsClient_RemoveMembers(t, c, *group.ID, &([]string{claims.ObjectId})) diff --git a/msgraph/identity_providers_test.go b/msgraph/identity_providers_test.go index 747a4ddb..d8cbfdb2 100644 --- a/msgraph/identity_providers_test.go +++ b/msgraph/identity_providers_test.go @@ -4,6 +4,8 @@ import ( "strings" "testing" + "github.com/manicminer/hamilton/odata" + "github.com/manicminer/hamilton/auth" "github.com/manicminer/hamilton/internal/test" "github.com/manicminer/hamilton/internal/utils" @@ -35,7 +37,7 @@ func TestIdentityProvidersClient(t *testing.T) { testIdentityProvidersClient_ListAvailableProviderTypes(t, c) identityProvider := testIdentityProvidersClient_Create(t, c, msgraph.IdentityProvider{ - ODataType: utils.StringPtr("microsoft.graph.socialIdentityProvider"), + ODataType: utils.StringPtr(odata.TypeSocialIdentityProvider), Name: utils.StringPtr("Login with Google"), Type: utils.StringPtr("Google"), ClientId: utils.StringPtr("56433757-cadd-4135-8431-2c9e3fd68ae8"), diff --git a/msgraph/models.go b/msgraph/models.go index 73a09a42..f571beff 100644 --- a/msgraph/models.go +++ b/msgraph/models.go @@ -7,6 +7,8 @@ import ( "strings" "time" + "github.com/manicminer/hamilton/odata" + "github.com/manicminer/hamilton/environments" "github.com/manicminer/hamilton/errors" ) @@ -36,7 +38,9 @@ type AppIdentity struct { // Application describes an Application object. type Application struct { - ID *string `json:"id,omitempty"` + *DirectoryObject + Owners *Owners `json:"owners@odata.bind,omitempty"` + AddIns *[]AddIn `json:"addIns,omitempty"` Api *ApplicationApi `json:"api,omitempty"` AppId *string `json:"appId,omitempty"` @@ -46,7 +50,7 @@ type Application struct { DeletedDateTime *time.Time `json:"deletedDateTime,omitempty"` DisabledByMicrosoftStatus interface{} `json:"disabledByMicrosoftStatus,omitempty"` DisplayName *string `json:"displayName,omitempty"` - GroupMembershipClaims *[]GroupMembershipClaim `json:"groupMembershipClaims,omitempty"` + GroupMembershipClaims *[]GroupMembershipClaim `json:"groupMembershipClaims,omitempty"` // TODO: tag needed? IdentifierUris *[]string `json:"identifierUris,omitempty"` Info *InformationalUrl `json:"info,omitempty"` IsAuthorizationServiceEnabled *bool `json:"isAuthorizationServiceEnabled,omitempty"` @@ -69,8 +73,6 @@ type Application struct { UniqueName *string `json:"uniqueName,omitempty"` VerifiedPublisher *VerifiedPublisher `json:"verifiedPublisher,omitempty"` Web *ApplicationWeb `json:"web,omitempty"` - - Owners *[]string `json:"owners@odata.bind,omitempty"` } func (a Application) MarshalJSON() ([]byte, error) { @@ -84,24 +86,29 @@ func (a Application) MarshalJSON() ([]byte, error) { val = &theClaims } type application Application - return json.Marshal(&struct { + app := struct { GroupMembershipClaims *StringNullWhenEmpty `json:"groupMembershipClaims,omitempty"` *application }{ GroupMembershipClaims: val, application: (*application)(&a), - }) + } + buf, err := json.Marshal(&app) + return buf, err } func (a *Application) UnmarshalJSON(data []byte) error { + if a.DirectoryObject == nil { + a.DirectoryObject = &DirectoryObject{} + } type application Application - app := &struct { + app := struct { GroupMembershipClaims *string `json:"groupMembershipClaims"` *application }{ application: (*application)(a), } - if err := json.Unmarshal(data, app); err != nil { + if err := json.Unmarshal(data, &app); err != nil { return err } if app.GroupMembershipClaims != nil { @@ -114,17 +121,6 @@ func (a *Application) UnmarshalJSON(data []byte) error { 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) - var owners []string - if a.Owners != nil { - owners = *a.Owners - } - owners = append(owners, val) - a.Owners = &owners -} - // AppendAppRole adds a new AppRole to an Application, checking to see if it already exists. func (a *Application) AppendAppRole(role AppRole) error { if role.ID == nil { @@ -337,11 +333,11 @@ type AuditActivityInitiator struct { } type BaseNamedLocation struct { - ODataType *string `json:"@odata.type,omitempty"` - ID *string `json:"id,omitempty"` - DisplayName *string `json:"displayName,omitempty"` - CreatedDateTime *time.Time `json:"createdDateTime,omitempty"` - ModifiedDateTime *time.Time `json:"modifiedDateTime,omitempty"` + ODataType *odata.Type `json:"@odata.type,omitempty"` + ID *string `json:"id,omitempty"` + DisplayName *string `json:"displayName,omitempty"` + CreatedDateTime *time.Time `json:"createdDateTime,omitempty"` + ModifiedDateTime *time.Time `json:"modifiedDateTime,omitempty"` } type CloudAppSecurityControl struct { @@ -465,24 +461,38 @@ type DirectoryAudit struct { TargetResources *[]TargetResource `json:"targetResources,omitempty"` } +type DirectoryObject struct { + ODataId *odata.Id `json:"@odata.id,omitempty"` + ODataType *odata.Type `json:"@odata.type,omitempty"` + ID *string `json:"id,omitempty"` +} + +func (o *DirectoryObject) Uri(endpoint environments.ApiEndpoint, apiVersion ApiVersion) string { + if o.ID == nil { + return "" + } + return fmt.Sprintf("%s/%s/directoryObjects/%s", endpoint, apiVersion, *o.ID) +} + type DirectoryRole struct { - ID *string `json:"id,omitempty"` + *DirectoryObject + Members *Members `json:"-"` + Description *string `json:"description,omitempty"` DisplayName *string `json:"displayName,omitempty"` RoleTemplateId *string `json:"roleTemplateId,omitempty"` - - Members *[]string `json:"-"` } -// AppendMember appends a new member object URI to the Members slice. -func (d *DirectoryRole) AppendMember(endpoint environments.ApiEndpoint, apiVersion ApiVersion, id string) { - val := fmt.Sprintf("%s/%s/directoryObjects/%s", endpoint, apiVersion, id) - var members []string - if d.Members != nil { - members = *d.Members +func (r *DirectoryRole) UnmarshalJSON(data []byte) error { + if r.DirectoryObject == nil { + r.DirectoryObject = &DirectoryObject{} } - members = append(members, val) - d.Members = &members + type directoryrole DirectoryRole + r2 := (*directoryrole)(r) + if err := json.Unmarshal(data, r2); err != nil { + return err + } + return nil } // DirectoryRoleTemplate describes a Directory Role Template. @@ -533,7 +543,11 @@ type GeoCoordinates struct { // Group describes a Group object. type Group struct { - ID *string `json:"id,omitempty"` + *DirectoryObject + Members *Members `json:"members@odata.bind,omitempty"` + Owners *Owners `json:"owners@odata.bind,omitempty"` + SchemaExtensions *[]SchemaExtensionData `json:"-"` + AllowExternalSenders *string `json:"allowExternalSenders,omitempty"` AssignedLabels *[]GroupAssignedLabel `json:"assignedLabels,omitempty"` AssignedLicenses *[]GroupAssignedLicense `json:"assignLicenses,omitempty"` @@ -574,17 +588,12 @@ type Group struct { UnseenCount *int `json:"unseenCount,omitempty"` Visibility *GroupVisibility `json:"visibility,omitempty"` IsAssignableToRole *bool `json:"isAssignableToRole,omitempty"` - - SchemaExtensions *[]SchemaExtensionData `json:"-"` - - Members *[]string `json:"members@odata.bind,omitempty"` - Owners *[]string `json:"owners@odata.bind,omitempty"` } func (g Group) MarshalJSON() ([]byte, error) { docs := make([][]byte, 0) type group Group - d, err := json.Marshal(group(g)) + d, err := json.Marshal((*group)(&g)) if err != nil { return d, err } @@ -602,6 +611,9 @@ func (g Group) MarshalJSON() ([]byte, error) { } func (g *Group) UnmarshalJSON(data []byte) error { + if g.DirectoryObject == nil { + g.DirectoryObject = &DirectoryObject{} + } type group Group g2 := (*group)(g) if err := json.Unmarshal(data, g2); err != nil { @@ -623,28 +635,6 @@ func (g *Group) UnmarshalJSON(data []byte) error { return nil } -// AppendMember appends a new member object URI to the Members slice. -func (g *Group) AppendMember(endpoint environments.ApiEndpoint, apiVersion ApiVersion, id string) { - val := fmt.Sprintf("%s/%s/directoryObjects/%s", endpoint, apiVersion, id) - var members []string - if g.Members != nil { - members = *g.Members - } - members = append(members, val) - g.Members = &members -} - -// AppendOwner appends a new owner object URI to the Owners slice. -func (g *Group) AppendOwner(endpoint environments.ApiEndpoint, apiVersion ApiVersion, id string) { - val := fmt.Sprintf("%s/%s/directoryObjects/%s", endpoint, apiVersion, id) - var owners []string - if g.Owners != nil { - owners = *g.Owners - } - owners = append(owners, val) - g.Owners = &owners -} - // HasTypes returns true if the group has all the specified GroupTypes func (g *Group) HasTypes(types []GroupType) bool { for _, t := range types { @@ -680,12 +670,12 @@ type GroupOnPremisesProvisioningError struct { } 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"` + ODataType *odata.Type `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 { @@ -923,7 +913,9 @@ func (se SchemaExtensionData) MarshalJSON() ([]byte, error) { // ServicePrincipal describes a Service Principal object. type ServicePrincipal struct { - ID *string `json:"id,omitempty"` + *DirectoryObject + Owners *Owners `json:"-"` + AccountEnabled *bool `json:"accountEnabled,omitempty"` AddIns *[]AddIn `json:"addIns,omitempty"` AlternativeNames *[]string `json:"alternativeNames,omitempty"` @@ -957,19 +949,18 @@ type ServicePrincipal struct { Tags *[]string `json:"tags,omitempty"` TokenEncryptionKeyId *string `json:"tokenEncryptionKeyId,omitempty"` VerifiedPublisher *VerifiedPublisher `json:"verifiedPublisher,omitempty"` - - Owners *[]string `json:"owners@odata.bind,omitempty"` } -// AppendOwner appends a new owner object URI to the Owners slice. -func (a *ServicePrincipal) AppendOwner(endpoint string, apiVersion string, id string) { - val := fmt.Sprintf("%s/%s/directoryObjects/%s", endpoint, apiVersion, id) - var owners []string - if a.Owners != nil { - owners = *a.Owners +func (s *ServicePrincipal) UnmarshalJSON(data []byte) error { + if s.DirectoryObject == nil { + s.DirectoryObject = &DirectoryObject{} } - owners = append(owners, val) - a.Owners = &owners + type serviceprincipal ServicePrincipal + s2 := (*serviceprincipal)(s) + if err := json.Unmarshal(data, s2); err != nil { + return err + } + return nil } type SignInActivity struct { @@ -1033,7 +1024,8 @@ type TargetResource struct { // User describes a User object. type User struct { - ID *string `json:"id,omitempty"` + *DirectoryObject + AboutMe *string `json:"aboutMe,omitempty"` AccountEnabled *bool `json:"accountEnabled,omitempty"` AgeGroup *AgeGroup `json:"ageGroup,omitempty"` @@ -1118,6 +1110,9 @@ func (u User) MarshalJSON() ([]byte, error) { } func (u *User) UnmarshalJSON(data []byte) error { + if u.DirectoryObject == nil { + u.DirectoryObject = &DirectoryObject{} + } type user User u2 := (*user)(u) if err := json.Unmarshal(data, u2); err != nil { diff --git a/msgraph/namedlocations.go b/msgraph/namedlocations.go index b2acf753..c0ca2df0 100644 --- a/msgraph/namedlocations.go +++ b/msgraph/namedlocations.go @@ -71,13 +71,13 @@ func (c *NamedLocationsClient) List(ctx context.Context, query odata.Query) (*[] continue } switch *o.Type { - case "#microsoft.graph.countryNamedLocation": + case odata.TypeCountryNamedLocation: var loc CountryNamedLocation if err := json.Unmarshal(namedLocation, &loc); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } ret = append(ret, loc) - case "#microsoft.graph.ipNamedLocation": + case odata.TypeIpNamedLocation: var loc IPNamedLocation if err := json.Unmarshal(namedLocation, &loc); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) @@ -110,7 +110,7 @@ func (c *NamedLocationsClient) Delete(ctx context.Context, id string) (int, erro func (c *NamedLocationsClient) CreateIP(ctx context.Context, ipNamedLocation IPNamedLocation) (*IPNamedLocation, int, error) { var status int - ipNamedLocation.ODataType = utils.StringPtr("#microsoft.graph.ipNamedLocation") + ipNamedLocation.ODataType = utils.StringPtr(odata.TypeIpNamedLocation) body, err := json.Marshal(ipNamedLocation) if err != nil { return nil, status, fmt.Errorf("json.Marshal(): %v", err) @@ -142,7 +142,7 @@ func (c *NamedLocationsClient) CreateIP(ctx context.Context, ipNamedLocation IPN func (c *NamedLocationsClient) CreateCountry(ctx context.Context, countryNamedLocation CountryNamedLocation) (*CountryNamedLocation, int, error) { var status int - countryNamedLocation.ODataType = utils.StringPtr("#microsoft.graph.countryNamedLocation") + countryNamedLocation.ODataType = utils.StringPtr(odata.TypeCountryNamedLocation) body, err := json.Marshal(countryNamedLocation) if err != nil { @@ -231,13 +231,13 @@ func (c *NamedLocationsClient) Get(ctx context.Context, id string, query odata.Q } switch *o.Type { - case "#microsoft.graph.countryNamedLocation": + case odata.TypeCountryNamedLocation: var loc CountryNamedLocation if err := json.Unmarshal(respBody, &loc); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } ret = loc - case "#microsoft.graph.ipNamedLocation": + case odata.TypeIpNamedLocation: var loc IPNamedLocation if err := json.Unmarshal(respBody, &loc); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) @@ -279,7 +279,7 @@ func (c *NamedLocationsClient) GetCountry(ctx context.Context, id string, query func (c *NamedLocationsClient) UpdateIP(ctx context.Context, ipNamedLocation IPNamedLocation) (int, error) { var status int - ipNamedLocation.ODataType = utils.StringPtr("#microsoft.graph.ipNamedLocation") + ipNamedLocation.ODataType = utils.StringPtr(odata.TypeIpNamedLocation) body, err := json.Marshal(ipNamedLocation) if err != nil { @@ -304,7 +304,7 @@ func (c *NamedLocationsClient) UpdateIP(ctx context.Context, ipNamedLocation IPN func (c *NamedLocationsClient) UpdateCountry(ctx context.Context, countryNamedLocation CountryNamedLocation) (int, error) { var status int - countryNamedLocation.ODataType = utils.StringPtr("#microsoft.graph.countryNamedLocation") + countryNamedLocation.ODataType = utils.StringPtr(odata.TypeCountryNamedLocation) body, err := json.Marshal(countryNamedLocation) if err != nil { diff --git a/msgraph/serviceprincipals.go b/msgraph/serviceprincipals.go index 0b0aa9f2..0b646255 100644 --- a/msgraph/serviceprincipals.go +++ b/msgraph/serviceprincipals.go @@ -221,8 +221,8 @@ func (c *ServicePrincipalsClient) GetOwner(ctx context.Context, servicePrincipal return &data.Id, status, nil } -// AddOwners adds a new owner to a Service Principal. -// First populate the Owners field of the ServicePrincipal using the AppendOwner method of the model, then call this method. +// AddOwners adds owners to a Service Principal. +// First populate the `owners` field, then call this method func (c *ServicePrincipalsClient) AddOwners(ctx context.Context, servicePrincipal *ServicePrincipal) (int, error) { var status int if servicePrincipal.ID == nil { @@ -240,12 +240,11 @@ func (c *ServicePrincipalsClient) AddOwners(ctx context.Context, servicePrincipa return false } - data := struct { - Owner string `json:"@odata.id"` + body, err := json.Marshal(struct { + Owner odata.Id `json:"@odata.id"` }{ - Owner: owner, - } - body, err := json.Marshal(data) + Owner: *owner.ODataId, + }) if err != nil { return status, fmt.Errorf("json.Marshal(): %v", err) } diff --git a/msgraph/serviceprincipals_test.go b/msgraph/serviceprincipals_test.go index 87115305..9b3ea7f2 100644 --- a/msgraph/serviceprincipals_test.go +++ b/msgraph/serviceprincipals_test.go @@ -53,7 +53,7 @@ func TestServicePrincipalsClient(t *testing.T) { DisplayName: appChild.DisplayName, }) - spChild.AppendOwner(string(c.client.BaseClient.Endpoint), string(c.client.BaseClient.ApiVersion), *sp.ID) + spChild.Owners = &msgraph.Owners{*sp.DirectoryObject} testServicePrincipalsClient_AddOwners(t, c, spChild) testServicePrincipalsClient_ListOwners(t, c, *spChild.ID, []string{*sp.ID}) testServicePrincipalsClient_GetOwner(t, c, *spChild.ID, *sp.ID) @@ -86,9 +86,9 @@ func TestServicePrincipalsClient(t *testing.T) { groupParent := testGroupsClient_Create(t, g, newGroupParent) groupChild := testGroupsClient_Create(t, g, newGroupChild) - groupParent.AppendMember(g.client.BaseClient.Endpoint, g.client.BaseClient.ApiVersion, *groupChild.ID) + groupParent.Members = &msgraph.Members{*groupChild.DirectoryObject} testGroupsClient_AddMembers(t, g, groupParent) - groupChild.AppendMember(g.client.BaseClient.Endpoint, g.client.BaseClient.ApiVersion, *sp.ID) + groupChild.Members = &msgraph.Members{*sp.DirectoryObject} testGroupsClient_AddMembers(t, g, groupChild) testServicePrincipalsClient_ListGroupMemberships(t, c, *sp.ID) @@ -172,9 +172,9 @@ func TestServicePrincipalsClient_AppRoleAssignments(t *testing.T) { groupParent := testGroupsClient_Create(t, g, newGroupParent) groupChild := testGroupsClient_Create(t, g, newGroupChild) - groupParent.AppendMember(g.client.BaseClient.Endpoint, g.client.BaseClient.ApiVersion, *groupChild.ID) + groupParent.Members = &msgraph.Members{*groupChild.DirectoryObject} testGroupsClient_AddMembers(t, g, groupParent) - groupChild.AppendMember(g.client.BaseClient.Endpoint, g.client.BaseClient.ApiVersion, *sp.ID) + groupChild.Members = &msgraph.Members{*sp.DirectoryObject} testGroupsClient_AddMembers(t, g, groupChild) testServicePrincipalsClient_ListGroupMemberships(t, c, *sp.ID) diff --git a/msgraph/users_test.go b/msgraph/users_test.go index 5d618c41..62978e2f 100644 --- a/msgraph/users_test.go +++ b/msgraph/users_test.go @@ -62,9 +62,9 @@ func TestUsersClient(t *testing.T) { groupParent := testGroupsClient_Create(t, g, newGroupParent) groupChild := testGroupsClient_Create(t, g, newGroupChild) - groupParent.AppendMember(g.client.BaseClient.Endpoint, g.client.BaseClient.ApiVersion, *groupChild.ID) + groupParent.Members = &msgraph.Members{*groupChild.DirectoryObject} testGroupsClient_AddMembers(t, g, groupParent) - groupChild.AppendMember(g.client.BaseClient.Endpoint, g.client.BaseClient.ApiVersion, *user.ID) + groupChild.Members = &msgraph.Members{*user.DirectoryObject} testGroupsClient_AddMembers(t, g, groupChild) testUsersClient_ListGroupMemberships(t, c, *user.ID) diff --git a/msgraph/valuetypes.go b/msgraph/valuetypes.go index 0e406850..e3db24c8 100644 --- a/msgraph/valuetypes.go +++ b/msgraph/valuetypes.go @@ -1,6 +1,11 @@ package msgraph -import "encoding/json" +import ( + "encoding/json" + goerrors "errors" + + "github.com/manicminer/hamilton/odata" +) // 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 @@ -183,6 +188,54 @@ const ( KeyCredentialUsageVerify KeyCredentialUsage = "Verify" ) +type Members []DirectoryObject + +func (o Members) MarshalJSON() ([]byte, error) { + members := make([]odata.Id, len(o)) + for i, v := range o { + if v.ODataId == nil { + return nil, goerrors.New("marshaling Members: encountered DirectoryObject with nil ODataId") + } + members[i] = *v.ODataId + } + return json.Marshal(members) +} + +func (o *Members) UnmarshalJSON(data []byte) error { + var members []odata.Id + if err := json.Unmarshal(data, &members); err != nil { + return err + } + for _, v := range members { + *o = append(*o, DirectoryObject{ODataId: &v}) + } + return nil +} + +type Owners []DirectoryObject + +func (o Owners) MarshalJSON() ([]byte, error) { + owners := make([]odata.Id, len(o)) + for i, v := range o { + if v.ODataId == nil { + return nil, goerrors.New("marshaling Owners: encountered DirectoryObject with nil ODataId") + } + owners[i] = *v.ODataId + } + return json.Marshal(owners) +} + +func (o *Owners) UnmarshalJSON(data []byte) error { + var owners []odata.Id + if err := json.Unmarshal(data, &owners); err != nil { + return err + } + for _, v := range owners { + *o = append(*o, DirectoryObject{ODataId: &v}) + } + return nil +} + type PermissionScopeType = string const ( diff --git a/odata/odata.go b/odata/odata.go index 1a7e09ba..7cb3ca2d 100644 --- a/odata/odata.go +++ b/odata/odata.go @@ -14,16 +14,47 @@ const ( ErrorServicePrincipalInvalidAppId = "The appId '.+' of the service principal does not reference a valid application object." ) +type Id string + +func (o *Id) UnmarshalJSON(data []byte) error { + var id string + if err := json.Unmarshal(data, &id); err != nil { + return err + } + *o = Id(regexp.MustCompile(`/v2/`).ReplaceAllString(id, `/v1.0/`)) + return nil +} + +type Type = string + +const ( + TypeAdministrativeUnit Type = "#microsoft.graph.administrativeUnit" + TypeApplication Type = "#microsoft.graph.application" + TypeConditionalAccessPolicy Type = "#microsoft.graph.conditionalAccessPolicy" + TypeCountryNamedLocation Type = "#microsoft.graph.countryNamedLocation" + TypeDevice Type = "#microsoft.graph.device" + TypeDirectoryRole Type = "#microsoft.graph.directoryRole" + TypeDirectoryRoleTemplate Type = "#microsoft.graph.directoryRoleTemplate" + TypeDomain Type = "#microsoft.graph.domain" + TypeGroup Type = "#microsoft.graph.group" + TypeIpNamedLocation Type = "#microsoft.graph.ipNamedLocation" + TypeNamedLocation Type = "#microsoft.graph.namedLocation" + TypeOrganization Type = "#microsoft.graph.organization" + TypeServicePrincipal Type = "#microsoft.graph.servicePrincipal" + TypeSocialIdentityProvider Type = "#microsoft.graph.socialIdentityProvider" + TypeUser Type = "#microsoft.graph.user" +) + // OData is used to unmarshall OData metadata from an API response. type OData struct { Context *string `json:"@odata.context"` MetadataEtag *string `json:"@odata.metadataEtag"` - Type *string `json:"@odata.type"` + Type *Type `json:"@odata.type"` Count *string `json:"@odata.count"` NextLink *string `json:"@odata.nextLink"` Delta *string `json:"@odata.delta"` DeltaLink *string `json:"@odata.deltaLink"` - Id *string `json:"@odata.id"` + Id *Id `json:"@odata.id"` Etag *string `json:"@odata.etag"` Error *Error `json:"-"` From 10e9ffdd4b862cb4843b6f2a04c8fe76d6e2fbce Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Fri, 13 Aug 2021 02:41:10 +0100 Subject: [PATCH 03/10] Add the GetByIds() method to DirectoryObjectsClient --- msgraph/directory_objects.go | 39 +++++++++++++++++++++++++++++++ msgraph/directory_objects_test.go | 18 ++++++++++++++ odata/odata.go | 20 ++++++++++++++++ 3 files changed, 77 insertions(+) diff --git a/msgraph/directory_objects.go b/msgraph/directory_objects.go index 9487cc9a..2835d9b7 100644 --- a/msgraph/directory_objects.go +++ b/msgraph/directory_objects.go @@ -49,6 +49,45 @@ func (c *DirectoryObjectsClient) Get(ctx context.Context, id string, query odata return &directoryObject, status, nil } +// GetByIds retrieves multiple DirectoryObjects from a list of IDs. +func (c *DirectoryObjectsClient) GetByIds(ctx context.Context, ids []string, types []odata.ShortType) (*[]DirectoryObject, int, error) { + var status int + body, err := json.Marshal(struct { + IDs []string `json:"ids"` + Types []odata.Type `json:"types"` + }{ + IDs: ids, + Types: types, + }) + if err != nil { + return nil, status, fmt.Errorf("json.Marshal(): %v", err) + } + resp, status, _, err := c.BaseClient.Post(ctx, PostHttpRequestInput{ + Body: body, + ConsistencyFailureFunc: RetryOn404ConsistencyFailureFunc, + ValidStatusCodes: []int{http.StatusOK}, + Uri: Uri{ + Entity: "/directoryObjects/getByIds", + HasTenantId: true, + }, + }) + if err != nil { + return nil, status, fmt.Errorf("DirectoryObjects.BaseClient.Post(): %v", err) + } + defer resp.Body.Close() + respBody, err := io.ReadAll(resp.Body) + if err != nil { + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) + } + var data struct { + Objects []DirectoryObject `json:"value"` + } + if err := json.Unmarshal(respBody, &data); err != nil { + return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) + } + return &data.Objects, status, nil +} + // Delete removes a DirectoryObject. func (c *DirectoryObjectsClient) Delete(ctx context.Context, id string) (int, error) { _, status, _, err := c.BaseClient.Delete(ctx, DeleteHttpRequestInput{ diff --git a/msgraph/directory_objects_test.go b/msgraph/directory_objects_test.go index 7445d8e5..33151560 100644 --- a/msgraph/directory_objects_test.go +++ b/msgraph/directory_objects_test.go @@ -75,6 +75,7 @@ func TestDirectoryObjectsClient(t *testing.T) { testDirectoryObjectsClient_Get(t, c, *group1.ID) testDirectoryObjectsClient_GetMemberGroups(t, c, *user.ID, true, []string{*group1.ID, *group2.ID}) testDirectoryObjectsClient_GetMemberObjects(t, c, *group1.ID, true, []string{*group2.ID}) + testDirectoryObjectsClient_GetByIds(t, c, []string{*group1.ID, *group2.ID, *user.ID}, []string{odata.ShortTypeGroup}) testDirectoryObjectsClient_Delete(t, c, *group1.ID) } @@ -95,6 +96,23 @@ func testDirectoryObjectsClient_Get(t *testing.T, c DirectoryObjectsClientTest, return } +func testDirectoryObjectsClient_GetByIds(t *testing.T, c DirectoryObjectsClientTest, ids []string, types []odata.ShortType) (directoryObjects *[]msgraph.DirectoryObject) { + directoryObjects, status, err := c.client.GetByIds(c.connection.Context, ids, types) + if err != nil { + t.Fatalf("DirectoryObjectsClient.GetByIds(): %v", err) + } + if status < 200 || status >= 300 { + t.Fatalf("DirectoryObjectsClient.GetByIds(): invalid status: %d", status) + } + if directoryObjects == nil { + t.Fatal("DirectoryObjectsClient.GetByIds(): directoryObject was nil") + } + if len(*directoryObjects) == 0 { + t.Fatal("DirectoryObjectsClient.GetByIds(): directoryObjects was empty") + } + return +} + func testDirectoryObjectsClient_GetMemberGroups(t *testing.T, c DirectoryObjectsClientTest, id string, securityEnabledOnly bool, expected []string) (directoryObjects *[]msgraph.DirectoryObject) { directoryObjects, status, err := c.client.GetMemberGroups(c.connection.Context, id, securityEnabledOnly) if err != nil { diff --git a/odata/odata.go b/odata/odata.go index 7cb3ca2d..0376325e 100644 --- a/odata/odata.go +++ b/odata/odata.go @@ -25,6 +25,26 @@ func (o *Id) UnmarshalJSON(data []byte) error { return nil } +type ShortType = string + +const ( + ShortTypeAdministrativeUnit ShortType = "administrativeUnit" + ShortTypeApplication ShortType = "application" + ShortTypeConditionalAccessPolicy ShortType = "conditionalAccessPolicy" + ShortTypeCountryNamedLocation ShortType = "countryNamedLocation" + ShortTypeDevice ShortType = "device" + ShortTypeDirectoryRole ShortType = "directoryRole" + ShortTypeDirectoryRoleTemplate ShortType = "directoryRoleTemplate" + ShortTypeDomain ShortType = "domain" + ShortTypeGroup ShortType = "group" + ShortTypeIpNamedLocation ShortType = "ipNamedLocation" + ShortTypeNamedLocation ShortType = "namedLocation" + ShortTypeOrganization ShortType = "organization" + ShortTypeServicePrincipal ShortType = "servicePrincipal" + ShortTypeSocialIdentityProvider ShortType = "socialIdentityProvider" + ShortTypeUser ShortType = "user" +) + type Type = string const ( From 30f2a5cef4475d06d5b2451ec0492ec6150b3dd6 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Fri, 13 Aug 2021 02:42:07 +0100 Subject: [PATCH 04/10] Eventual consistency handling for group creation where owners have not yet replicated --- msgraph/groups.go | 8 ++++++-- odata/odata.go | 3 ++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/msgraph/groups.go b/msgraph/groups.go index 8997944c..907e2ba2 100644 --- a/msgraph/groups.go +++ b/msgraph/groups.go @@ -57,9 +57,13 @@ func (c *GroupsClient) Create(ctx context.Context, group Group) (*Group, int, er if err != nil { return nil, status, fmt.Errorf("json.Marshal(): %v", err) } + ownersNotReplicated := func(resp *http.Response, o *odata.OData) bool { + return o.Error != nil && o.Error.Match(odata.ErrorResourceDoesNotExist) + } resp, status, _, err := c.BaseClient.Post(ctx, PostHttpRequestInput{ - Body: body, - ValidStatusCodes: []int{http.StatusCreated}, + Body: body, + ConsistencyFailureFunc: ownersNotReplicated, + ValidStatusCodes: []int{http.StatusCreated}, Uri: Uri{ Entity: "/groups", HasTenantId: true, diff --git a/odata/odata.go b/odata/odata.go index 0376325e..e8dbbe29 100644 --- a/odata/odata.go +++ b/odata/odata.go @@ -10,8 +10,9 @@ import ( const ( ErrorAddedObjectReferencesAlreadyExist = "One or more added object references already exist" ErrorConflictingObjectPresentInDirectory = "A conflicting object with one or more of the specified property values is present in the directory" + ErrorResourceDoesNotExist = "Resource '.+' does not exist or one of its queried reference-property objects are not present" ErrorRemovedObjectReferencesDoNotExist = "One or more removed object references do not exist" - ErrorServicePrincipalInvalidAppId = "The appId '.+' of the service principal does not reference a valid application object." + ErrorServicePrincipalInvalidAppId = "The appId '.+' of the service principal does not reference a valid application object" ) type Id string From 8c8ec5eab37b8c6bac7b165fce7db4200325ffd2 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Fri, 13 Aug 2021 02:43:02 +0100 Subject: [PATCH 05/10] Export the retryablehttp client to consuming apps can adjust timeouts and retry limits --- msgraph/client.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/msgraph/client.go b/msgraph/client.go index 8610bba1..8a7902de 100644 --- a/msgraph/client.go +++ b/msgraph/client.go @@ -85,7 +85,7 @@ type Client struct { // HttpClient is the underlying http.Client, which by default uses a retryable client HttpClient *http.Client - retryableClient *retryablehttp.Client + RetryableClient *retryablehttp.Client } // NewClient returns a new Client configured with the specified API version and tenant ID. @@ -99,7 +99,7 @@ func NewClient(apiVersion ApiVersion, tenantId string) Client { TenantId: tenantId, UserAgent: "Hamilton (Go-http-client/1.1)", HttpClient: r.StandardClient(), - retryableClient: r, + RetryableClient: r, } } @@ -152,7 +152,7 @@ func (c Client) performRequest(req *http.Request, input HttpRequestInput) (*http } } - c.retryableClient.CheckRetry = func(ctx context.Context, resp *http.Response, err error) (bool, error) { + c.RetryableClient.CheckRetry = func(ctx context.Context, resp *http.Response, err error) (bool, error) { if resp != nil && !c.DisableRetries { if resp.StatusCode == http.StatusFailedDependency { return true, nil From 95bfa551628795f58f0a31b935f47a6668505493 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Fri, 13 Aug 2021 17:25:25 +0100 Subject: [PATCH 06/10] Fix some crashes --- msgraph/applications.go | 4 ++-- msgraph/directory_roles.go | 12 ++++-------- msgraph/groups.go | 10 +++++----- msgraph/serviceprincipals.go | 6 +++--- 4 files changed, 14 insertions(+), 18 deletions(-) diff --git a/msgraph/applications.go b/msgraph/applications.go index 9e0dd76f..f1aba9f7 100644 --- a/msgraph/applications.go +++ b/msgraph/applications.go @@ -386,7 +386,7 @@ func (c *ApplicationsClient) AddOwners(ctx context.Context, application *Applica for _, owner := range *application.Owners { // don't fail if an owner already exists checkOwnerAlreadyExists := func(resp *http.Response, o *odata.OData) bool { - if resp.StatusCode == http.StatusBadRequest && o.Error != nil { + if resp.StatusCode == http.StatusBadRequest && o != nil && o.Error != nil { return o.Error.Match(odata.ErrorAddedObjectReferencesAlreadyExist) } return false @@ -432,7 +432,7 @@ func (c *ApplicationsClient) RemoveOwners(ctx context.Context, applicationId str // despite the above check, sometimes owners are just gone checkOwnerGone := func(resp *http.Response, o *odata.OData) bool { - if resp.StatusCode == http.StatusBadRequest && o.Error != nil { + if resp.StatusCode == http.StatusBadRequest && o != nil && o.Error != nil { return o.Error.Match(odata.ErrorRemovedObjectReferencesDoNotExist) } return false diff --git a/msgraph/directory_roles.go b/msgraph/directory_roles.go index 73486494..fc41d170 100644 --- a/msgraph/directory_roles.go +++ b/msgraph/directory_roles.go @@ -121,10 +121,8 @@ func (c *DirectoryRolesClient) AddMembers(ctx context.Context, directoryRole *Di for _, member := range *directoryRole.Members { // don't fail if a member already exists checkMemberAlreadyExists := func(resp *http.Response, o *odata.OData) bool { - if resp.StatusCode == http.StatusBadRequest { - if o.Error != nil { - return o.Error.Match(odata.ErrorAddedObjectReferencesAlreadyExist) - } + if resp.StatusCode == http.StatusBadRequest && o != nil && o.Error != nil { + return o.Error.Match(odata.ErrorAddedObjectReferencesAlreadyExist) } return false } @@ -223,10 +221,8 @@ func (c *DirectoryRolesClient) Activate(ctx context.Context, roleTemplateID stri // don't fail if a role is already activated checkRoleAlreadyActivated := func(resp *http.Response, o *odata.OData) bool { - if resp.StatusCode == http.StatusBadRequest { - if o.Error != nil { - return o.Error.Match(odata.ErrorConflictingObjectPresentInDirectory) - } + if resp.StatusCode == http.StatusBadRequest && o != nil && o.Error != nil { + return o.Error.Match(odata.ErrorConflictingObjectPresentInDirectory) } return false } diff --git a/msgraph/groups.go b/msgraph/groups.go index 907e2ba2..49a2f31e 100644 --- a/msgraph/groups.go +++ b/msgraph/groups.go @@ -58,7 +58,7 @@ func (c *GroupsClient) Create(ctx context.Context, group Group) (*Group, int, er return nil, status, fmt.Errorf("json.Marshal(): %v", err) } ownersNotReplicated := func(resp *http.Response, o *odata.OData) bool { - return o.Error != nil && o.Error.Match(odata.ErrorResourceDoesNotExist) + return o != nil && o.Error != nil && o.Error.Match(odata.ErrorResourceDoesNotExist) } resp, status, _, err := c.BaseClient.Post(ctx, PostHttpRequestInput{ Body: body, @@ -362,7 +362,7 @@ func (c *GroupsClient) AddMembers(ctx context.Context, group *Group) (int, error for _, member := range *group.Members { // don't fail if an member already exists checkMemberAlreadyExists := func(resp *http.Response, o *odata.OData) bool { - if resp.StatusCode == http.StatusBadRequest && o.Error != nil { + if resp.StatusCode == http.StatusBadRequest && o != nil && o.Error != nil { return o.Error.Match(odata.ErrorAddedObjectReferencesAlreadyExist) } return false @@ -412,7 +412,7 @@ func (c *GroupsClient) RemoveMembers(ctx context.Context, id string, memberIds * // despite the above check, sometimes members are just gone checkMemberGone := func(resp *http.Response, o *odata.OData) bool { - if resp.StatusCode == http.StatusBadRequest && o.Error != nil { + if resp.StatusCode == http.StatusBadRequest && o != nil && o.Error != nil { return o.Error.Match(odata.ErrorRemovedObjectReferencesDoNotExist) } return false @@ -514,7 +514,7 @@ func (c *GroupsClient) AddOwners(ctx context.Context, group *Group) (int, error) for _, owner := range *group.Owners { // don't fail if an owner already exists checkOwnerAlreadyExists := func(resp *http.Response, o *odata.OData) bool { - if resp.StatusCode == http.StatusBadRequest && o.Error != nil { + if resp.StatusCode == http.StatusBadRequest && o != nil && o.Error != nil { return o.Error.Match(odata.ErrorAddedObjectReferencesAlreadyExist) } return false @@ -564,7 +564,7 @@ func (c *GroupsClient) RemoveOwners(ctx context.Context, id string, ownerIds *[] // despite the above check, sometimes owners are just gone checkOwnerGone := func(resp *http.Response, o *odata.OData) bool { - if resp.StatusCode == http.StatusBadRequest && o.Error != nil { + if resp.StatusCode == http.StatusBadRequest && o != nil && o.Error != nil { return o.Error.Match(odata.ErrorRemovedObjectReferencesDoNotExist) } return false diff --git a/msgraph/serviceprincipals.go b/msgraph/serviceprincipals.go index 0b646255..8bace3c7 100644 --- a/msgraph/serviceprincipals.go +++ b/msgraph/serviceprincipals.go @@ -59,7 +59,7 @@ func (c *ServicePrincipalsClient) Create(ctx context.Context, servicePrincipal S return nil, status, fmt.Errorf("json.Marshal(): %v", err) } appNotReplicated := func(resp *http.Response, o *odata.OData) bool { - return o.Error != nil && o.Error.Match(odata.ErrorServicePrincipalInvalidAppId) + return o != nil && o.Error != nil && o.Error.Match(odata.ErrorServicePrincipalInvalidAppId) } resp, status, _, err := c.BaseClient.Post(ctx, PostHttpRequestInput{ Body: body, @@ -234,7 +234,7 @@ func (c *ServicePrincipalsClient) AddOwners(ctx context.Context, servicePrincipa for _, owner := range *servicePrincipal.Owners { // don't fail if an owner already exists checkOwnerAlreadyExists := func(resp *http.Response, o *odata.OData) bool { - if resp.StatusCode == http.StatusBadRequest && o.Error != nil { + if resp.StatusCode == http.StatusBadRequest && o != nil && o.Error != nil { return o.Error.Match(odata.ErrorAddedObjectReferencesAlreadyExist) } return false @@ -284,7 +284,7 @@ func (c *ServicePrincipalsClient) RemoveOwners(ctx context.Context, servicePrinc // despite the above check, sometimes owners are just gone checkOwnerGone := func(resp *http.Response, o *odata.OData) bool { - if resp.StatusCode == http.StatusBadRequest && o.Error != nil { + if resp.StatusCode == http.StatusBadRequest && o != nil && o.Error != nil { return o.Error.Match(odata.ErrorRemovedObjectReferencesDoNotExist) } return false From f4b01bc7eff19c36fa61ad6ada06763e3bc37837 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Tue, 17 Aug 2021 02:39:23 +0100 Subject: [PATCH 07/10] Fix a potential crash --- msgraph/client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msgraph/client.go b/msgraph/client.go index 8a7902de..1d56f08d 100644 --- a/msgraph/client.go +++ b/msgraph/client.go @@ -35,7 +35,7 @@ type ResponseMiddleware func(*http.Request, *http.Response) (*http.Response, err // RetryOn404ConsistencyFailureFunc can be used to retry a request when a 404 response is received func RetryOn404ConsistencyFailureFunc(resp *http.Response, _ *odata.OData) bool { - return resp.StatusCode == http.StatusNotFound + return resp != nil && resp.StatusCode == http.StatusNotFound } // ValidStatusFunc is a function that tests whether an HTTP response is considered valid for the particular request. From 481bf0ed0edc4cc73f27a15eeebcda788115bf93 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Tue, 17 Aug 2021 13:19:58 +0100 Subject: [PATCH 08/10] Embedded DirectoryObject doesn't need to be a pointer --- msgraph/applications_test.go | 4 ++-- msgraph/directory_objects_test.go | 22 ++++++++++---------- msgraph/directory_roles_test.go | 2 +- msgraph/groups_test.go | 4 ++-- msgraph/models.go | 34 +++++++++++++------------------ msgraph/serviceprincipals_test.go | 10 ++++----- msgraph/users_test.go | 4 ++-- 7 files changed, 37 insertions(+), 43 deletions(-) diff --git a/msgraph/applications_test.go b/msgraph/applications_test.go index fafc8b51..474b8188 100644 --- a/msgraph/applications_test.go +++ b/msgraph/applications_test.go @@ -63,7 +63,7 @@ func TestApplicationsClient(t *testing.T) { app := testApplicationsClient_Create(t, c, msgraph.Application{ DisplayName: utils.StringPtr(fmt.Sprintf("test-application-%s", c.randomString)), - Owners: &msgraph.Owners{*self}, + Owners: &msgraph.Owners{*self}, }) testApplicationsClient_Get(t, c, *app.ID) app.DisplayName = utils.StringPtr(fmt.Sprintf("test-app-updated-%s", c.randomString)) @@ -82,7 +82,7 @@ func TestApplicationsClient(t *testing.T) { owners := testApplicationsClient_ListOwners(t, c, *app.ID) testApplicationsClient_GetOwner(t, c, *app.ID, (*owners)[0]) testApplicationsClient_RemoveOwners(t, c, *app.ID, owners) - app.Owners = &msgraph.Owners{*user.DirectoryObject} + app.Owners = &msgraph.Owners{user.DirectoryObject} testApplicationsClient_AddOwners(t, c, app) pwd := testApplicationsClient_AddPassword(t, c, app) testApplicationsClient_RemovePassword(t, c, app, pwd) diff --git a/msgraph/directory_objects_test.go b/msgraph/directory_objects_test.go index 33151560..dd769cee 100644 --- a/msgraph/directory_objects_test.go +++ b/msgraph/directory_objects_test.go @@ -56,7 +56,7 @@ func TestDirectoryObjectsClient(t *testing.T) { MailNickname: utils.StringPtr(fmt.Sprintf("test-group-directoryobject-member-%s", c.randomString)), SecurityEnabled: utils.BoolPtr(true), } - newGroup1.Members = &msgraph.Members{*user.DirectoryObject} + newGroup1.Members = &msgraph.Members{user.DirectoryObject} group1 := testGroupsClient_Create(t, g, newGroup1) newGroup2 := msgraph.Group{ @@ -65,8 +65,8 @@ func TestDirectoryObjectsClient(t *testing.T) { MailNickname: utils.StringPtr(fmt.Sprintf("test-group-directoryobject-%s", c.randomString)), SecurityEnabled: utils.BoolPtr(true), Members: &msgraph.Members{ - *group1.DirectoryObject, - *user.DirectoryObject, + group1.DirectoryObject, + user.DirectoryObject, }, } group2 := testGroupsClient_Create(t, g, newGroup2) @@ -132,16 +132,16 @@ func testDirectoryObjectsClient_GetMemberGroups(t *testing.T, c DirectoryObjects if len(*directoryObjects) < expectedCount { t.Fatalf("DirectoryObjectsClient.GetMemberGroups(): expected at least %d result. has: %d", expectedCount, len(*directoryObjects)) } - var expectedFound int + var actualCount int for _, e := range expected { for _, o := range *directoryObjects { if o.ID != nil && e == *o.ID { - expectedFound++ + actualCount++ } } } - if expectedFound < expectedCount { - t.Fatalf("DirectoryObjectsClient.GetMemberGroups(): expected %d matching objects. found: %d", expectedCount, expectedFound) + if actualCount < expectedCount { + t.Fatalf("DirectoryObjectsClient.GetMemberGroups(): expected %d matching objects. found: %d", expectedCount, actualCount) } return } @@ -165,16 +165,16 @@ func testDirectoryObjectsClient_GetMemberObjects(t *testing.T, c DirectoryObject if len(*directoryObjects) < expectedCount { t.Fatalf("DirectoryObjectsClient.GetMemberObjects(): expected at least %d result. has: %d", expectedCount, len(*directoryObjects)) } - var expectedFound int + var actualCount int for _, e := range expected { for _, o := range *directoryObjects { if o.ID != nil && e == *o.ID { - expectedFound++ + actualCount++ } } } - if expectedFound < expectedCount { - t.Fatalf("DirectoryObjectsClient.GetMemberObjects(): expected %d matching objects. found: %d", expectedCount, expectedFound) + if actualCount < expectedCount { + t.Fatalf("DirectoryObjectsClient.GetMemberObjects(): expected %d matching objects. found: %d", expectedCount, actualCount) } return } diff --git a/msgraph/directory_roles_test.go b/msgraph/directory_roles_test.go index 4ae2c7da..512f98a6 100644 --- a/msgraph/directory_roles_test.go +++ b/msgraph/directory_roles_test.go @@ -52,7 +52,7 @@ func TestDirectoryRolesClient(t *testing.T) { group := testGroupsClient_Create(t, groupsClient, newGroup) // add the test group as a member of directory role - directoryRole.Members = &msgraph.Members{*group.DirectoryObject} + directoryRole.Members = &msgraph.Members{group.DirectoryObject} testDirectoryRolesClient_AddMembers(t, dirRolesClient, &directoryRole) // list members of the directory role; then remove the added group member to clean up diff --git a/msgraph/groups_test.go b/msgraph/groups_test.go index 7b749097..5bef4a15 100644 --- a/msgraph/groups_test.go +++ b/msgraph/groups_test.go @@ -81,11 +81,11 @@ func TestGroupsClient(t *testing.T) { }, }) - group.Owners = &msgraph.Owners{*user.DirectoryObject} + group.Owners = &msgraph.Owners{user.DirectoryObject} testGroupsClient_AddOwners(t, c, group) testGroupsClient_RemoveOwners(t, c, *group.ID, &([]string{claims.ObjectId})) - group.Members = &msgraph.Members{*user.DirectoryObject} + group.Members = &msgraph.Members{user.DirectoryObject} testGroupsClient_AddMembers(t, c, group) testGroupsClient_RemoveMembers(t, c, *group.ID, &([]string{claims.ObjectId})) diff --git a/msgraph/models.go b/msgraph/models.go index f571beff..a4b6a90b 100644 --- a/msgraph/models.go +++ b/msgraph/models.go @@ -38,7 +38,7 @@ type AppIdentity struct { // Application describes an Application object. type Application struct { - *DirectoryObject + DirectoryObject Owners *Owners `json:"owners@odata.bind,omitempty"` AddIns *[]AddIn `json:"addIns,omitempty"` @@ -85,6 +85,8 @@ func (a Application) MarshalJSON() ([]byte, error) { theClaims := StringNullWhenEmpty(strings.Join(claims, ",")) val = &theClaims } + + // Local type needed to avoid recursive MarshalJSON calls type application Application app := struct { GroupMembershipClaims *StringNullWhenEmpty `json:"groupMembershipClaims,omitempty"` @@ -98,9 +100,7 @@ func (a Application) MarshalJSON() ([]byte, error) { } func (a *Application) UnmarshalJSON(data []byte) error { - if a.DirectoryObject == nil { - a.DirectoryObject = &DirectoryObject{} - } + // Local type needed to avoid recursive UnmarshalJSON calls type application Application app := struct { GroupMembershipClaims *string `json:"groupMembershipClaims"` @@ -475,7 +475,7 @@ func (o *DirectoryObject) Uri(endpoint environments.ApiEndpoint, apiVersion ApiV } type DirectoryRole struct { - *DirectoryObject + DirectoryObject Members *Members `json:"-"` Description *string `json:"description,omitempty"` @@ -484,9 +484,7 @@ type DirectoryRole struct { } func (r *DirectoryRole) UnmarshalJSON(data []byte) error { - if r.DirectoryObject == nil { - r.DirectoryObject = &DirectoryObject{} - } + // Local type needed to avoid recursive UnmarshalJSON calls type directoryrole DirectoryRole r2 := (*directoryrole)(r) if err := json.Unmarshal(data, r2); err != nil { @@ -543,7 +541,7 @@ type GeoCoordinates struct { // Group describes a Group object. type Group struct { - *DirectoryObject + DirectoryObject Members *Members `json:"members@odata.bind,omitempty"` Owners *Owners `json:"owners@odata.bind,omitempty"` SchemaExtensions *[]SchemaExtensionData `json:"-"` @@ -592,6 +590,7 @@ type Group struct { func (g Group) MarshalJSON() ([]byte, error) { docs := make([][]byte, 0) + // Local type needed to avoid recursive MarshalJSON calls type group Group d, err := json.Marshal((*group)(&g)) if err != nil { @@ -611,9 +610,7 @@ func (g Group) MarshalJSON() ([]byte, error) { } func (g *Group) UnmarshalJSON(data []byte) error { - if g.DirectoryObject == nil { - g.DirectoryObject = &DirectoryObject{} - } + // Local type needed to avoid recursive UnmarshalJSON calls type group Group g2 := (*group)(g) if err := json.Unmarshal(data, g2); err != nil { @@ -913,7 +910,7 @@ func (se SchemaExtensionData) MarshalJSON() ([]byte, error) { // ServicePrincipal describes a Service Principal object. type ServicePrincipal struct { - *DirectoryObject + DirectoryObject Owners *Owners `json:"-"` AccountEnabled *bool `json:"accountEnabled,omitempty"` @@ -952,9 +949,7 @@ type ServicePrincipal struct { } func (s *ServicePrincipal) UnmarshalJSON(data []byte) error { - if s.DirectoryObject == nil { - s.DirectoryObject = &DirectoryObject{} - } + // Local type needed to avoid recursive UnmarshalJSON calls type serviceprincipal ServicePrincipal s2 := (*serviceprincipal)(s) if err := json.Unmarshal(data, s2); err != nil { @@ -1024,7 +1019,7 @@ type TargetResource struct { // User describes a User object. type User struct { - *DirectoryObject + DirectoryObject AboutMe *string `json:"aboutMe,omitempty"` AccountEnabled *bool `json:"accountEnabled,omitempty"` @@ -1091,6 +1086,7 @@ type User struct { func (u User) MarshalJSON() ([]byte, error) { docs := make([][]byte, 0) + // Local type needed to avoid recursive MarshalJSON calls type user User d, err := json.Marshal(user(u)) if err != nil { @@ -1110,9 +1106,7 @@ func (u User) MarshalJSON() ([]byte, error) { } func (u *User) UnmarshalJSON(data []byte) error { - if u.DirectoryObject == nil { - u.DirectoryObject = &DirectoryObject{} - } + // Local type needed to avoid recursive UnmarshalJSON calls type user User u2 := (*user)(u) if err := json.Unmarshal(data, u2); err != nil { diff --git a/msgraph/serviceprincipals_test.go b/msgraph/serviceprincipals_test.go index 9b3ea7f2..040afbc2 100644 --- a/msgraph/serviceprincipals_test.go +++ b/msgraph/serviceprincipals_test.go @@ -53,7 +53,7 @@ func TestServicePrincipalsClient(t *testing.T) { DisplayName: appChild.DisplayName, }) - spChild.Owners = &msgraph.Owners{*sp.DirectoryObject} + spChild.Owners = &msgraph.Owners{sp.DirectoryObject} testServicePrincipalsClient_AddOwners(t, c, spChild) testServicePrincipalsClient_ListOwners(t, c, *spChild.ID, []string{*sp.ID}) testServicePrincipalsClient_GetOwner(t, c, *spChild.ID, *sp.ID) @@ -86,9 +86,9 @@ func TestServicePrincipalsClient(t *testing.T) { groupParent := testGroupsClient_Create(t, g, newGroupParent) groupChild := testGroupsClient_Create(t, g, newGroupChild) - groupParent.Members = &msgraph.Members{*groupChild.DirectoryObject} + groupParent.Members = &msgraph.Members{groupChild.DirectoryObject} testGroupsClient_AddMembers(t, g, groupParent) - groupChild.Members = &msgraph.Members{*sp.DirectoryObject} + groupChild.Members = &msgraph.Members{sp.DirectoryObject} testGroupsClient_AddMembers(t, g, groupChild) testServicePrincipalsClient_ListGroupMemberships(t, c, *sp.ID) @@ -172,9 +172,9 @@ func TestServicePrincipalsClient_AppRoleAssignments(t *testing.T) { groupParent := testGroupsClient_Create(t, g, newGroupParent) groupChild := testGroupsClient_Create(t, g, newGroupChild) - groupParent.Members = &msgraph.Members{*groupChild.DirectoryObject} + groupParent.Members = &msgraph.Members{groupChild.DirectoryObject} testGroupsClient_AddMembers(t, g, groupParent) - groupChild.Members = &msgraph.Members{*sp.DirectoryObject} + groupChild.Members = &msgraph.Members{sp.DirectoryObject} testGroupsClient_AddMembers(t, g, groupChild) testServicePrincipalsClient_ListGroupMemberships(t, c, *sp.ID) diff --git a/msgraph/users_test.go b/msgraph/users_test.go index 62978e2f..d351b5e1 100644 --- a/msgraph/users_test.go +++ b/msgraph/users_test.go @@ -62,9 +62,9 @@ func TestUsersClient(t *testing.T) { groupParent := testGroupsClient_Create(t, g, newGroupParent) groupChild := testGroupsClient_Create(t, g, newGroupChild) - groupParent.Members = &msgraph.Members{*groupChild.DirectoryObject} + groupParent.Members = &msgraph.Members{groupChild.DirectoryObject} testGroupsClient_AddMembers(t, g, groupParent) - groupChild.Members = &msgraph.Members{*user.DirectoryObject} + groupChild.Members = &msgraph.Members{user.DirectoryObject} testGroupsClient_AddMembers(t, g, groupChild) testUsersClient_ListGroupMemberships(t, c, *user.ID) From 0a1e0f0a8582cfaed8fdc7911724834d703d207c Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Tue, 17 Aug 2021 13:20:40 +0100 Subject: [PATCH 09/10] Application.GroupMembershipClaims field doesn't need a tag --- msgraph/applications_test.go | 5 +++++ msgraph/models.go | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/msgraph/applications_test.go b/msgraph/applications_test.go index 474b8188..3eb81f2f 100644 --- a/msgraph/applications_test.go +++ b/msgraph/applications_test.go @@ -63,6 +63,11 @@ func TestApplicationsClient(t *testing.T) { app := testApplicationsClient_Create(t, c, msgraph.Application{ DisplayName: utils.StringPtr(fmt.Sprintf("test-application-%s", c.randomString)), + GroupMembershipClaims: &[]msgraph.GroupMembershipClaim{ + msgraph.GroupMembershipClaimApplicationGroup, + msgraph.GroupMembershipClaimDirectoryRole, + msgraph.GroupMembershipClaimSecurityGroup, + }, Owners: &msgraph.Owners{*self}, }) testApplicationsClient_Get(t, c, *app.ID) diff --git a/msgraph/models.go b/msgraph/models.go index a4b6a90b..c72ec74e 100644 --- a/msgraph/models.go +++ b/msgraph/models.go @@ -50,7 +50,7 @@ type Application struct { DeletedDateTime *time.Time `json:"deletedDateTime,omitempty"` DisabledByMicrosoftStatus interface{} `json:"disabledByMicrosoftStatus,omitempty"` DisplayName *string `json:"displayName,omitempty"` - GroupMembershipClaims *[]GroupMembershipClaim `json:"groupMembershipClaims,omitempty"` // TODO: tag needed? + GroupMembershipClaims *[]GroupMembershipClaim `json:"-"` // see Application.MarshalJSON / Application.UnmarshalJSON IdentifierUris *[]string `json:"identifierUris,omitempty"` Info *InformationalUrl `json:"info,omitempty"` IsAuthorizationServiceEnabled *bool `json:"isAuthorizationServiceEnabled,omitempty"` From 5025cd451c1e71bdd06148e8ce788c3e8ae686d9 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Tue, 17 Aug 2021 13:41:48 +0100 Subject: [PATCH 10/10] More whitespace can make read easy --- msgraph/app_role_assignments.go | 9 +++++ msgraph/applications.go | 53 +++++++++++++++++++++++++++ msgraph/conditionalaccesspolicy.go | 14 ++++++++ msgraph/directory_audit_reports.go | 6 ++++ msgraph/directory_objects.go | 19 ++++++++++ msgraph/directory_role_templates.go | 6 ++++ msgraph/directory_roles.go | 24 +++++++++++++ msgraph/domains.go | 6 ++-- msgraph/groups.go | 55 +++++++++++++++++++++++++++++ msgraph/identity_providers.go | 19 ++++++++++ msgraph/invitations.go | 5 +++ msgraph/me.go | 11 ++++++ msgraph/namedlocations.go | 23 ++++++++++-- msgraph/reports.go | 18 ++++++++-- msgraph/schema_extensions.go | 15 ++++++++ msgraph/serviceprincipals.go | 55 ++++++++++++++++++++++++++++- msgraph/sign_in_reports.go | 6 ++++ msgraph/users.go | 32 +++++++++++++++++ 18 files changed, 368 insertions(+), 8 deletions(-) diff --git a/msgraph/app_role_assignments.go b/msgraph/app_role_assignments.go index b32172b6..8ac0d0a4 100644 --- a/msgraph/app_role_assignments.go +++ b/msgraph/app_role_assignments.go @@ -58,17 +58,20 @@ func (c *AppRoleAssignmentsClient) List(ctx context.Context, id string) (*[]AppR if err != nil { return nil, status, fmt.Errorf("AppRoleAssignmentsClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var data struct { AppRoleAssignments []AppRoleAssignment `json:"value"` } if err := json.Unmarshal(respBody, &data); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &data.AppRoleAssignments, status, nil } @@ -85,12 +88,14 @@ func (c *AppRoleAssignmentsClient) Remove(ctx context.Context, id, appRoleAssign if err != nil { return status, fmt.Errorf("AppRoleAssignmentsClient.BaseClient.Delete(): %v", err) } + return status, nil } // Assign assigns an app role to a user, group or service principal depending on client resource type. func (c *AppRoleAssignmentsClient) Assign(ctx context.Context, clientServicePrincipalId, resourceServicePrincipalId, appRoleId string) (*AppRoleAssignment, int, error) { var status int + data := struct { PrincipalId string `json:"principalId"` ResourceId string `json:"resourceId"` @@ -105,6 +110,7 @@ func (c *AppRoleAssignmentsClient) Assign(ctx context.Context, clientServicePrin if err != nil { return nil, status, fmt.Errorf("json.Marshal(): %v", err) } + resp, status, _, err := c.BaseClient.Post(ctx, PostHttpRequestInput{ Body: body, ConsistencyFailureFunc: RetryOn404ConsistencyFailureFunc, @@ -117,14 +123,17 @@ func (c *AppRoleAssignmentsClient) Assign(ctx context.Context, clientServicePrin if err != nil { return nil, status, fmt.Errorf("AppRoleAssignmentsClient.BaseClient.Post(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var appRoleAssignment AppRoleAssignment if err := json.Unmarshal(respBody, &appRoleAssignment); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &appRoleAssignment, status, nil } diff --git a/msgraph/applications.go b/msgraph/applications.go index f1aba9f7..a7effa11 100644 --- a/msgraph/applications.go +++ b/msgraph/applications.go @@ -37,27 +37,32 @@ func (c *ApplicationsClient) List(ctx context.Context, query odata.Query) (*[]Ap if err != nil { return nil, status, fmt.Errorf("ApplicationsClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var data struct { Applications []Application `json:"value"` } if err := json.Unmarshal(respBody, &data); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &data.Applications, status, nil } // Create creates a new Application. func (c *ApplicationsClient) Create(ctx context.Context, application Application) (*Application, int, error) { var status int + body, err := json.Marshal(application) if err != nil { return nil, status, fmt.Errorf("json.Marshal(): %v", err) } + resp, status, _, err := c.BaseClient.Post(ctx, PostHttpRequestInput{ Body: body, ValidStatusCodes: []int{http.StatusCreated}, @@ -69,15 +74,18 @@ func (c *ApplicationsClient) Create(ctx context.Context, application Application if err != nil { return nil, status, fmt.Errorf("ApplicationsClient.BaseClient.Post(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var newApplication Application if err := json.Unmarshal(respBody, &newApplication); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &newApplication, status, nil } @@ -95,15 +103,18 @@ func (c *ApplicationsClient) Get(ctx context.Context, id string, query odata.Que if err != nil { return nil, status, fmt.Errorf("ApplicationsClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var application Application if err := json.Unmarshal(respBody, &application); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &application, status, nil } @@ -122,28 +133,34 @@ func (c *ApplicationsClient) GetDeleted(ctx context.Context, id string, query od if err != nil { return nil, status, fmt.Errorf("ApplicationsClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var application Application if err := json.Unmarshal(respBody, &application); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &application, status, nil } // Update amends the manifest of an existing Application. func (c *ApplicationsClient) Update(ctx context.Context, application Application) (int, error) { var status int + if application.ID == nil { return status, errors.New("ApplicationsClient.Update(): cannot update application with nil ID") } + body, err := json.Marshal(application) if err != nil { return status, fmt.Errorf("json.Marshal(): %v", err) } + _, status, _, err = c.BaseClient.Patch(ctx, PatchHttpRequestInput{ Body: body, ConsistencyFailureFunc: RetryOn404ConsistencyFailureFunc, @@ -156,6 +173,7 @@ func (c *ApplicationsClient) Update(ctx context.Context, application Application if err != nil { return status, fmt.Errorf("ApplicationsClient.BaseClient.Patch(): %v", err) } + return status, nil } @@ -172,6 +190,7 @@ func (c *ApplicationsClient) Delete(ctx context.Context, id string) (int, error) if err != nil { return status, fmt.Errorf("ApplicationsClient.BaseClient.Delete(): %v", err) } + return status, nil } @@ -189,6 +208,7 @@ func (c *ApplicationsClient) DeletePermanently(ctx context.Context, id string) ( if err != nil { return status, fmt.Errorf("ApplicationsClient.BaseClient.Delete(): %v", err) } + return status, nil } @@ -206,6 +226,7 @@ func (c *ApplicationsClient) ListDeleted(ctx context.Context, query odata.Query) if err != nil { return nil, status, err } + defer resp.Body.Close() respBody, _ := io.ReadAll(resp.Body) var data struct { @@ -214,6 +235,7 @@ func (c *ApplicationsClient) ListDeleted(ctx context.Context, query odata.Query) if err = json.Unmarshal(respBody, &data); err != nil { return nil, status, err } + return &data.DeletedApps, status, nil } @@ -231,21 +253,25 @@ func (c *ApplicationsClient) RestoreDeleted(ctx context.Context, id string) (*Ap if err != nil { return nil, status, fmt.Errorf("ApplicationsClient.BaseClient.Post(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var restoredApplication Application if err = json.Unmarshal(respBody, &restoredApplication); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &restoredApplication, status, nil } // AddPassword appends a new password credential to an Application. func (c *ApplicationsClient) AddPassword(ctx context.Context, applicationId string, passwordCredential PasswordCredential) (*PasswordCredential, int, error) { var status int + body, err := json.Marshal(struct { PwdCredential PasswordCredential `json:"passwordCredential"` }{ @@ -254,6 +280,7 @@ func (c *ApplicationsClient) AddPassword(ctx context.Context, applicationId stri if err != nil { return nil, status, fmt.Errorf("json.Marshal(): %v", err) } + resp, status, _, err := c.BaseClient.Post(ctx, PostHttpRequestInput{ Body: body, ConsistencyFailureFunc: RetryOn404ConsistencyFailureFunc, @@ -266,21 +293,25 @@ func (c *ApplicationsClient) AddPassword(ctx context.Context, applicationId stri if err != nil { return nil, status, fmt.Errorf("ApplicationsClient.BaseClient.Post(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var newPasswordCredential PasswordCredential if err := json.Unmarshal(respBody, &newPasswordCredential); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &newPasswordCredential, status, nil } // RemovePassword removes a password credential from an Application. func (c *ApplicationsClient) RemovePassword(ctx context.Context, applicationId string, keyId string) (int, error) { var status int + body, err := json.Marshal(struct { KeyId string `json:"keyId"` }{ @@ -289,6 +320,7 @@ func (c *ApplicationsClient) RemovePassword(ctx context.Context, applicationId s if err != nil { return status, fmt.Errorf("json.Marshal(): %v", err) } + _, status, _, err = c.BaseClient.Post(ctx, PostHttpRequestInput{ Body: body, ConsistencyFailureFunc: RetryOn404ConsistencyFailureFunc, @@ -301,6 +333,7 @@ func (c *ApplicationsClient) RemovePassword(ctx context.Context, applicationId s if err != nil { return status, fmt.Errorf("ApplicationsClient.BaseClient.Post(): %v", err) } + return status, nil } @@ -319,11 +352,13 @@ func (c *ApplicationsClient) ListOwners(ctx context.Context, id string) (*[]stri if err != nil { return nil, status, fmt.Errorf("ApplicationsClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var data struct { Owners []struct { Type string `json:"@odata.type"` @@ -333,10 +368,12 @@ func (c *ApplicationsClient) ListOwners(ctx context.Context, id string) (*[]stri if err := json.Unmarshal(respBody, &data); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + ret := make([]string, len(data.Owners)) for i, v := range data.Owners { ret[i] = v.Id } + return &ret, status, nil } @@ -356,11 +393,13 @@ func (c *ApplicationsClient) GetOwner(ctx context.Context, applicationId, ownerI if err != nil { return nil, status, fmt.Errorf("ApplicationsClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var data struct { Context string `json:"@odata.context"` Type string `json:"@odata.type"` @@ -370,6 +409,7 @@ func (c *ApplicationsClient) GetOwner(ctx context.Context, applicationId, ownerI if err := json.Unmarshal(respBody, &data); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &data.Id, status, nil } @@ -377,12 +417,14 @@ func (c *ApplicationsClient) GetOwner(ctx context.Context, applicationId, ownerI // First populate the `owners` field, then call this method func (c *ApplicationsClient) AddOwners(ctx context.Context, application *Application) (int, error) { var status int + if application.ID == nil { return status, errors.New("cannot update application with nil ID") } if application.Owners == nil { return status, errors.New("cannot update application with nil Owners") } + for _, owner := range *application.Owners { // don't fail if an owner already exists checkOwnerAlreadyExists := func(resp *http.Response, o *odata.OData) bool { @@ -396,6 +438,7 @@ func (c *ApplicationsClient) AddOwners(ctx context.Context, application *Applica if err != nil { return status, fmt.Errorf("json.Marshal(): %v", err) } + _, status, _, err = c.BaseClient.Post(ctx, PostHttpRequestInput{ Body: body, ConsistencyFailureFunc: RetryOn404ConsistencyFailureFunc, @@ -410,6 +453,7 @@ func (c *ApplicationsClient) AddOwners(ctx context.Context, application *Applica return status, fmt.Errorf("ApplicationsClient.BaseClient.Post(): %v", err) } } + return status, nil } @@ -418,9 +462,11 @@ func (c *ApplicationsClient) AddOwners(ctx context.Context, application *Applica // ownerIds is a *[]string containing object IDs of owners to remove. func (c *ApplicationsClient) RemoveOwners(ctx context.Context, applicationId string, ownerIds *[]string) (int, error) { var status int + if ownerIds == nil { return status, errors.New("cannot remove, nil ownerIds") } + for _, ownerId := range *ownerIds { // check for ownership before attempting deletion if _, status, err := c.GetOwner(ctx, applicationId, ownerId); err != nil { @@ -452,6 +498,7 @@ func (c *ApplicationsClient) RemoveOwners(ctx context.Context, applicationId str return status, fmt.Errorf("ApplicationsClient.BaseClient.Delete(): %v", err) } } + return status, nil } @@ -468,6 +515,7 @@ func (c *ApplicationsClient) ListExtensions(ctx context.Context, id string, quer if err != nil { return nil, status, fmt.Errorf("ApplicationsClient.BaseClient.List(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { @@ -480,16 +528,19 @@ func (c *ApplicationsClient) ListExtensions(ctx context.Context, id string, quer if err := json.Unmarshal(respBody, &data); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &data.ApplicationExtension, status, nil } // Create creates a new ApplicationExtension. func (c *ApplicationsClient) CreateExtension(ctx context.Context, applicationExtension ApplicationExtension, id string) (*ApplicationExtension, int, error) { var status int + body, err := json.Marshal(applicationExtension) if err != nil { return nil, status, fmt.Errorf("json.Marshal(): %v", err) } + resp, status, _, err := c.BaseClient.Post(ctx, PostHttpRequestInput{ Body: body, ValidStatusCodes: []int{http.StatusCreated}, @@ -501,6 +552,7 @@ func (c *ApplicationsClient) CreateExtension(ctx context.Context, applicationExt if err != nil { return nil, status, fmt.Errorf("ApplicationsClient.BaseClient.Post(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { @@ -528,5 +580,6 @@ func (c *ApplicationsClient) DeleteExtension(ctx context.Context, applicationId, if err != nil { return status, fmt.Errorf("ApplicationsClient.BaseClient.Delete(): %v", err) } + return status, nil } diff --git a/msgraph/conditionalaccesspolicy.go b/msgraph/conditionalaccesspolicy.go index db9d98ae..0c99d3a2 100644 --- a/msgraph/conditionalaccesspolicy.go +++ b/msgraph/conditionalaccesspolicy.go @@ -37,17 +37,20 @@ func (c *ConditionalAccessPolicyClient) List(ctx context.Context, query odata.Qu if err != nil { return nil, status, fmt.Errorf("ConditionalAccessPolicyClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var data struct { ConditionalAccessPolicys []ConditionalAccessPolicy `json:"value"` } if err := json.Unmarshal(respBody, &data); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &data.ConditionalAccessPolicys, status, nil } @@ -58,6 +61,7 @@ func (c *ConditionalAccessPolicyClient) Create(ctx context.Context, conditionalA if err != nil { return nil, status, fmt.Errorf("json.Marshal(): %v", err) } + resp, status, _, err := c.BaseClient.Post(ctx, PostHttpRequestInput{ Body: body, ValidStatusCodes: []int{http.StatusCreated}, @@ -69,15 +73,18 @@ func (c *ConditionalAccessPolicyClient) Create(ctx context.Context, conditionalA if err != nil { return nil, status, fmt.Errorf("ConditionalAccessPolicyClient.BaseClient.Post(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var newConditionalAccessPolicy ConditionalAccessPolicy if err := json.Unmarshal(respBody, &newConditionalAccessPolicy); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &newConditionalAccessPolicy, status, nil } @@ -95,21 +102,25 @@ func (c *ConditionalAccessPolicyClient) Get(ctx context.Context, id string, quer if err != nil { return nil, status, fmt.Errorf("ConditionalAccessPolicyClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var conditionalAccessPolicy ConditionalAccessPolicy if err := json.Unmarshal(respBody, &conditionalAccessPolicy); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &conditionalAccessPolicy, status, nil } // Update amends an existing ConditionalAccessPolicy. func (c *ConditionalAccessPolicyClient) Update(ctx context.Context, conditionalAccessPolicy ConditionalAccessPolicy) (int, error) { var status int + if conditionalAccessPolicy.ID == nil { return status, errors.New("cannot update conditionalAccessPolicy with nil ID") } @@ -118,6 +129,7 @@ func (c *ConditionalAccessPolicyClient) Update(ctx context.Context, conditionalA if err != nil { return status, fmt.Errorf("json.Marshal(): %v", err) } + _, status, _, err = c.BaseClient.Patch(ctx, PatchHttpRequestInput{ Body: body, ConsistencyFailureFunc: RetryOn404ConsistencyFailureFunc, @@ -130,6 +142,7 @@ func (c *ConditionalAccessPolicyClient) Update(ctx context.Context, conditionalA if err != nil { return status, fmt.Errorf("ConditionalAccessPolicyClient.BaseClient.Patch(): %v", err) } + return status, nil } @@ -146,5 +159,6 @@ func (c *ConditionalAccessPolicyClient) Delete(ctx context.Context, id string) ( if err != nil { return status, fmt.Errorf("ConditionalAccessPolicyClient.BaseClient.Delete(): %v", err) } + return status, nil } diff --git a/msgraph/directory_audit_reports.go b/msgraph/directory_audit_reports.go index 1c6a69ff..38cb78b0 100644 --- a/msgraph/directory_audit_reports.go +++ b/msgraph/directory_audit_reports.go @@ -36,17 +36,20 @@ func (c *DirectoryAuditReportsClient) List(ctx context.Context, query odata.Quer if err != nil { return nil, status, fmt.Errorf("DirectoryAuditReportsClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var data struct { DirectoryAuditReports []DirectoryAudit `json:"value"` } if err := json.Unmarshal(respBody, &data); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &data.DirectoryAuditReports, status, nil } @@ -64,14 +67,17 @@ func (c *DirectoryAuditReportsClient) Get(ctx context.Context, id string, query if err != nil { return nil, status, fmt.Errorf("DirectoryAuditReportsClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var directoryAuditReport DirectoryAudit if err := json.Unmarshal(respBody, &directoryAuditReport); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &directoryAuditReport, status, nil } diff --git a/msgraph/directory_objects.go b/msgraph/directory_objects.go index 2835d9b7..f9183fd7 100644 --- a/msgraph/directory_objects.go +++ b/msgraph/directory_objects.go @@ -37,21 +37,25 @@ func (c *DirectoryObjectsClient) Get(ctx context.Context, id string, query odata if err != nil { return nil, status, fmt.Errorf("DirectoryObjects.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var directoryObject DirectoryObject if err := json.Unmarshal(respBody, &directoryObject); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &directoryObject, status, nil } // GetByIds retrieves multiple DirectoryObjects from a list of IDs. func (c *DirectoryObjectsClient) GetByIds(ctx context.Context, ids []string, types []odata.ShortType) (*[]DirectoryObject, int, error) { var status int + body, err := json.Marshal(struct { IDs []string `json:"ids"` Types []odata.Type `json:"types"` @@ -62,6 +66,7 @@ func (c *DirectoryObjectsClient) GetByIds(ctx context.Context, ids []string, typ if err != nil { return nil, status, fmt.Errorf("json.Marshal(): %v", err) } + resp, status, _, err := c.BaseClient.Post(ctx, PostHttpRequestInput{ Body: body, ConsistencyFailureFunc: RetryOn404ConsistencyFailureFunc, @@ -74,17 +79,20 @@ func (c *DirectoryObjectsClient) GetByIds(ctx context.Context, ids []string, typ if err != nil { return nil, status, fmt.Errorf("DirectoryObjects.BaseClient.Post(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var data struct { Objects []DirectoryObject `json:"value"` } if err := json.Unmarshal(respBody, &data); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &data.Objects, status, nil } @@ -101,6 +109,7 @@ func (c *DirectoryObjectsClient) Delete(ctx context.Context, id string) (int, er if err != nil { return status, fmt.Errorf("DirectoryObjects.BaseClient.Get(): %v", err) } + return status, nil } @@ -108,6 +117,7 @@ func (c *DirectoryObjectsClient) Delete(ctx context.Context, id string) (int, er // id is the object ID of the directory object. func (c *DirectoryObjectsClient) GetMemberGroups(ctx context.Context, id string, securityEnabledOnly bool) (*[]DirectoryObject, int, error) { var status int + body, err := json.Marshal(struct { SecurityEnabledOnly bool `json:"securityEnabledOnly"` }{ @@ -116,6 +126,7 @@ func (c *DirectoryObjectsClient) GetMemberGroups(ctx context.Context, id string, if err != nil { return nil, status, fmt.Errorf("json.Marshal(): %v", err) } + resp, status, _, err := c.BaseClient.Post(ctx, PostHttpRequestInput{ Body: body, ConsistencyFailureFunc: RetryOn404ConsistencyFailureFunc, @@ -128,11 +139,13 @@ func (c *DirectoryObjectsClient) GetMemberGroups(ctx context.Context, id string, if err != nil { return nil, status, fmt.Errorf("DirectoryObjectsClient.BaseClient.Post(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var data struct { IDs []string `json:"value"` } @@ -144,6 +157,7 @@ func (c *DirectoryObjectsClient) GetMemberGroups(ctx context.Context, id string, for i, id := range data.IDs { result[i].ID = utils.StringPtr(id) } + return &result, status, nil } @@ -151,6 +165,7 @@ func (c *DirectoryObjectsClient) GetMemberGroups(ctx context.Context, id string, // id is the object ID of the directory object. func (c *DirectoryObjectsClient) GetMemberObjects(ctx context.Context, id string, securityEnabledOnly bool) (*[]DirectoryObject, int, error) { var status int + body, err := json.Marshal(struct { SecurityEnabledOnly bool `json:"securityEnabledOnly"` }{ @@ -159,6 +174,7 @@ func (c *DirectoryObjectsClient) GetMemberObjects(ctx context.Context, id string if err != nil { return nil, status, fmt.Errorf("json.Marshal(): %v", err) } + resp, status, _, err := c.BaseClient.Post(ctx, PostHttpRequestInput{ Body: body, ConsistencyFailureFunc: RetryOn404ConsistencyFailureFunc, @@ -171,11 +187,13 @@ func (c *DirectoryObjectsClient) GetMemberObjects(ctx context.Context, id string if err != nil { return nil, status, fmt.Errorf("DirectoryObjectsClient.BaseClient.Post(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var data struct { IDs []string `json:"value"` } @@ -187,5 +205,6 @@ func (c *DirectoryObjectsClient) GetMemberObjects(ctx context.Context, id string for i, id := range data.IDs { result[i].ID = utils.StringPtr(id) } + return &result, status, nil } diff --git a/msgraph/directory_role_templates.go b/msgraph/directory_role_templates.go index f719f6bc..ab95032b 100644 --- a/msgraph/directory_role_templates.go +++ b/msgraph/directory_role_templates.go @@ -32,17 +32,20 @@ func (c *DirectoryRoleTemplatesClient) List(ctx context.Context) (*[]DirectoryRo if err != nil { return nil, status, fmt.Errorf("DirectoryRoleTemplatesClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var data struct { DirectoryRoleTemplates []DirectoryRoleTemplate `json:"value"` } if err := json.Unmarshal(respBody, &data); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &data.DirectoryRoleTemplates, status, nil } @@ -59,14 +62,17 @@ func (c *DirectoryRoleTemplatesClient) Get(ctx context.Context, id string) (*Dir if err != nil { return nil, status, fmt.Errorf("DirectoryRoleTemplatesClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var dirRoleTemplate DirectoryRoleTemplate if err := json.Unmarshal(respBody, &dirRoleTemplate); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &dirRoleTemplate, status, nil } diff --git a/msgraph/directory_roles.go b/msgraph/directory_roles.go index fc41d170..5612da1d 100644 --- a/msgraph/directory_roles.go +++ b/msgraph/directory_roles.go @@ -35,17 +35,20 @@ func (c *DirectoryRolesClient) List(ctx context.Context) (*[]DirectoryRole, int, if err != nil { return nil, status, fmt.Errorf("DirectoryRolesClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var data struct { DirectoryRoles []DirectoryRole `json:"value"` } if err := json.Unmarshal(respBody, &data); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &data.DirectoryRoles, status, nil } @@ -61,15 +64,18 @@ func (c *DirectoryRolesClient) Get(ctx context.Context, id string) (*DirectoryRo if err != nil { return nil, status, fmt.Errorf("DirectoryRolesClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var dirRole DirectoryRole if err := json.Unmarshal(respBody, &dirRole); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &dirRole, status, nil } @@ -87,11 +93,13 @@ func (c *DirectoryRolesClient) ListMembers(ctx context.Context, id string) (*[]s if err != nil { return nil, status, fmt.Errorf("DirectoryRolesClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var data struct { Members []struct { Type string `json:"@odata.type"` @@ -101,10 +109,12 @@ func (c *DirectoryRolesClient) ListMembers(ctx context.Context, id string) (*[]s if err := json.Unmarshal(respBody, &data); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + ret := make([]string, len(data.Members)) for i, v := range data.Members { ret[i] = v.Id } + return &ret, status, nil } @@ -112,12 +122,14 @@ func (c *DirectoryRolesClient) ListMembers(ctx context.Context, id string) (*[]s // First populate the `members` field, then call this method func (c *DirectoryRolesClient) AddMembers(ctx context.Context, directoryRole *DirectoryRole) (int, error) { var status int + if directoryRole.ID == nil { return status, errors.New("cannot update directory role with nil ID") } if directoryRole.Members == nil { return status, errors.New("cannot update directory role with nil Owners") } + for _, member := range *directoryRole.Members { // don't fail if a member already exists checkMemberAlreadyExists := func(resp *http.Response, o *odata.OData) bool { @@ -135,6 +147,7 @@ func (c *DirectoryRolesClient) AddMembers(ctx context.Context, directoryRole *Di if err != nil { return status, fmt.Errorf("json.Marshal(): %v", err) } + _, status, _, err = c.BaseClient.Post(ctx, PostHttpRequestInput{ Body: body, ValidStatusCodes: []int{http.StatusNoContent}, @@ -148,6 +161,7 @@ func (c *DirectoryRolesClient) AddMembers(ctx context.Context, directoryRole *Di return status, fmt.Errorf("DirectoryRolesClient.BaseClient.Post(): %v", err) } } + return status, nil } @@ -156,9 +170,11 @@ func (c *DirectoryRolesClient) AddMembers(ctx context.Context, directoryRole *Di // memberIds is a *[]string containing object IDs of members to remove. func (c *DirectoryRolesClient) RemoveMembers(ctx context.Context, directoryRoleId string, memberIds *[]string) (int, error) { var status int + if memberIds == nil { return status, errors.New("cannot remove, nil memberIds") } + for _, memberId := range *memberIds { // check for membership before attempting deletion if _, status, err := c.GetMember(ctx, directoryRoleId, memberId); err != nil { @@ -167,6 +183,7 @@ func (c *DirectoryRolesClient) RemoveMembers(ctx context.Context, directoryRoleI } return status, err } + var err error _, status, _, err = c.BaseClient.Delete(ctx, DeleteHttpRequestInput{ ValidStatusCodes: []int{http.StatusNoContent}, @@ -179,6 +196,7 @@ func (c *DirectoryRolesClient) RemoveMembers(ctx context.Context, directoryRoleI return status, fmt.Errorf("DirectoryRolesClient.BaseClient.Delete(): %v", err) } } + return status, nil } @@ -197,11 +215,13 @@ func (c *DirectoryRolesClient) GetMember(ctx context.Context, directoryRoleId, m if err != nil { return nil, status, fmt.Errorf("DirectoryRolesClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var data struct { Context string `json:"@odata.context"` Type string `json:"@odata.type"` @@ -211,6 +231,7 @@ func (c *DirectoryRolesClient) GetMember(ctx context.Context, directoryRoleId, m if err := json.Unmarshal(respBody, &data); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &data.Id, status, nil } @@ -249,14 +270,17 @@ func (c *DirectoryRolesClient) Activate(ctx context.Context, roleTemplateID stri if err != nil { return nil, status, fmt.Errorf("DirectoryRolesClient.BaseClient.Post(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var newDirRole DirectoryRole if err := json.Unmarshal(respBody, &newDirRole); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &newDirRole, status, nil } diff --git a/msgraph/domains.go b/msgraph/domains.go index e10762d9..7a14c78b 100644 --- a/msgraph/domains.go +++ b/msgraph/domains.go @@ -33,7 +33,6 @@ func (c *DomainsClient) List(ctx context.Context, query odata.Query) (*[]Domain, HasTenantId: true, }, }) - if err != nil { return nil, status, fmt.Errorf("DomainsClient.BaseClient.Get(): %v", err) } @@ -47,7 +46,6 @@ func (c *DomainsClient) List(ctx context.Context, query odata.Query) (*[]Domain, var data struct { Domains []Domain `json:"value"` } - if err := json.Unmarshal(respBody, &data); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } @@ -58,6 +56,7 @@ func (c *DomainsClient) List(ctx context.Context, query odata.Query) (*[]Domain, // Get retrieves a Domain. func (c *DomainsClient) Get(ctx context.Context, id string, query odata.Query) (*Domain, int, error) { var status int + resp, status, _, err := c.BaseClient.Get(ctx, GetHttpRequestInput{ ConsistencyFailureFunc: RetryOn404ConsistencyFailureFunc, ValidStatusCodes: []int{http.StatusOK}, @@ -70,14 +69,17 @@ func (c *DomainsClient) Get(ctx context.Context, id string, query odata.Query) ( if err != nil { return nil, status, fmt.Errorf("DomainsClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var domain Domain if err := json.Unmarshal(respBody, &domain); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &domain, status, nil } diff --git a/msgraph/groups.go b/msgraph/groups.go index 49a2f31e..816ee9f1 100644 --- a/msgraph/groups.go +++ b/msgraph/groups.go @@ -36,30 +36,36 @@ func (c *GroupsClient) List(ctx context.Context, query odata.Query) (*[]Group, i if err != nil { return nil, status, fmt.Errorf("GroupsClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var data struct { Groups []Group `json:"value"` } if err := json.Unmarshal(respBody, &data); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &data.Groups, status, nil } // Create creates a new Group. func (c *GroupsClient) Create(ctx context.Context, group Group) (*Group, int, error) { var status int + body, err := json.Marshal(group) if err != nil { return nil, status, fmt.Errorf("json.Marshal(): %v", err) } + ownersNotReplicated := func(resp *http.Response, o *odata.OData) bool { return o != nil && o.Error != nil && o.Error.Match(odata.ErrorResourceDoesNotExist) } + resp, status, _, err := c.BaseClient.Post(ctx, PostHttpRequestInput{ Body: body, ConsistencyFailureFunc: ownersNotReplicated, @@ -72,15 +78,18 @@ func (c *GroupsClient) Create(ctx context.Context, group Group) (*Group, int, er if err != nil { return nil, status, fmt.Errorf("GroupsClient.BaseClient.Post(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var newGroup Group if err := json.Unmarshal(respBody, &newGroup); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &newGroup, status, nil } @@ -98,15 +107,18 @@ func (c *GroupsClient) Get(ctx context.Context, id string, query odata.Query) (* if err != nil { return nil, status, fmt.Errorf("GroupsClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var group Group if err := json.Unmarshal(respBody, &group); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &group, status, nil } @@ -140,6 +152,7 @@ func (c *GroupsClient) GetWithSchemaExtensions(ctx context.Context, id string, q if err != nil { return nil, status, fmt.Errorf("GroupsClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { @@ -150,6 +163,7 @@ func (c *GroupsClient) GetWithSchemaExtensions(ctx context.Context, id string, q if err := json.Unmarshal(respBody, group); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return group, status, nil } @@ -167,25 +181,30 @@ func (c *GroupsClient) GetDeleted(ctx context.Context, id string, query odata.Qu if err != nil { return nil, status, fmt.Errorf("GroupsClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var group Group if err := json.Unmarshal(respBody, &group); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &group, status, nil } // Update amends an existing Group. func (c *GroupsClient) Update(ctx context.Context, group Group) (int, error) { var status int + body, err := json.Marshal(group) if err != nil { return status, fmt.Errorf("json.Marshal(): %v", err) } + _, status, _, err = c.BaseClient.Patch(ctx, PatchHttpRequestInput{ Body: body, ConsistencyFailureFunc: RetryOn404ConsistencyFailureFunc, @@ -198,6 +217,7 @@ func (c *GroupsClient) Update(ctx context.Context, group Group) (int, error) { if err != nil { return status, fmt.Errorf("GroupsClient.BaseClient.Patch(): %v", err) } + return status, nil } @@ -214,6 +234,7 @@ func (c *GroupsClient) Delete(ctx context.Context, id string) (int, error) { if err != nil { return status, fmt.Errorf("GroupsClient.BaseClient.Delete(): %v", err) } + return status, nil } @@ -230,6 +251,7 @@ func (c *GroupsClient) DeletePermanently(ctx context.Context, id string) (int, e if err != nil { return status, fmt.Errorf("GroupsClient.BaseClient.Delete(): %v", err) } + return status, nil } @@ -247,6 +269,7 @@ func (c *GroupsClient) ListDeleted(ctx context.Context, query odata.Query) (*[]G if err != nil { return nil, status, err } + defer resp.Body.Close() respBody, _ := io.ReadAll(resp.Body) var data struct { @@ -255,6 +278,7 @@ func (c *GroupsClient) ListDeleted(ctx context.Context, query odata.Query) (*[]G if err = json.Unmarshal(respBody, &data); err != nil { return nil, status, err } + return &data.DeletedGroups, status, nil } @@ -271,15 +295,18 @@ func (c *GroupsClient) RestoreDeleted(ctx context.Context, id string) (*Group, i if err != nil { return nil, status, fmt.Errorf("GroupsClient.BaseClient.Post(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var restoredGroup Group if err = json.Unmarshal(respBody, &restoredGroup); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &restoredGroup, status, nil } @@ -298,11 +325,13 @@ func (c *GroupsClient) ListMembers(ctx context.Context, id string) (*[]string, i if err != nil { return nil, status, fmt.Errorf("GroupsClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var data struct { Members []struct { Type string `json:"@odata.type"` @@ -312,10 +341,12 @@ func (c *GroupsClient) ListMembers(ctx context.Context, id string) (*[]string, i if err := json.Unmarshal(respBody, &data); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + ret := make([]string, len(data.Members)) for i, v := range data.Members { ret[i] = v.Id } + return &ret, status, nil } @@ -335,11 +366,13 @@ func (c *GroupsClient) GetMember(ctx context.Context, groupId, memberId string) if err != nil { return nil, status, fmt.Errorf("GroupsClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var data struct { Context string `json:"@odata.context"` Type string `json:"@odata.type"` @@ -349,6 +382,7 @@ func (c *GroupsClient) GetMember(ctx context.Context, groupId, memberId string) if err := json.Unmarshal(respBody, &data); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &data.Id, status, nil } @@ -356,9 +390,11 @@ func (c *GroupsClient) GetMember(ctx context.Context, groupId, memberId string) // First populate the `members` field, then call this method func (c *GroupsClient) AddMembers(ctx context.Context, group *Group) (int, error) { var status int + if group.Members == nil || len(*group.Members) == 0 { return status, fmt.Errorf("no members specified") } + for _, member := range *group.Members { // don't fail if an member already exists checkMemberAlreadyExists := func(resp *http.Response, o *odata.OData) bool { @@ -376,6 +412,7 @@ func (c *GroupsClient) AddMembers(ctx context.Context, group *Group) (int, error if err != nil { return status, fmt.Errorf("json.Marshal(): %v", err) } + _, status, _, err = c.BaseClient.Post(ctx, PostHttpRequestInput{ Body: body, ConsistencyFailureFunc: RetryOn404ConsistencyFailureFunc, @@ -390,6 +427,7 @@ func (c *GroupsClient) AddMembers(ctx context.Context, group *Group) (int, error return status, fmt.Errorf("GroupsClient.BaseClient.Post(): %v", err) } } + return status, nil } @@ -398,9 +436,11 @@ func (c *GroupsClient) AddMembers(ctx context.Context, group *Group) (int, error // memberIds is a *[]string containing object IDs of members to remove. func (c *GroupsClient) RemoveMembers(ctx context.Context, id string, memberIds *[]string) (int, error) { var status int + if memberIds == nil || len(*memberIds) == 0 { return status, fmt.Errorf("no members specified") } + for _, memberId := range *memberIds { // check for membership before attempting deletion if _, status, err := c.GetMember(ctx, id, memberId); err != nil { @@ -432,6 +472,7 @@ func (c *GroupsClient) RemoveMembers(ctx context.Context, id string, memberIds * return status, fmt.Errorf("GroupsClient.BaseClient.Delete(): %v", err) } } + return status, nil } @@ -450,11 +491,13 @@ func (c *GroupsClient) ListOwners(ctx context.Context, id string) (*[]string, in if err != nil { return nil, status, fmt.Errorf("GroupsClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var data struct { Owners []struct { Type string `json:"@odata.type"` @@ -464,10 +507,12 @@ func (c *GroupsClient) ListOwners(ctx context.Context, id string) (*[]string, in if err := json.Unmarshal(respBody, &data); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + ret := make([]string, len(data.Owners)) for i, v := range data.Owners { ret[i] = v.Id } + return &ret, status, nil } @@ -487,11 +532,13 @@ func (c *GroupsClient) GetOwner(ctx context.Context, groupId, ownerId string) (* if err != nil { return nil, status, fmt.Errorf("GroupsClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var data struct { Context string `json:"@odata.context"` Type string `json:"@odata.type"` @@ -501,6 +548,7 @@ func (c *GroupsClient) GetOwner(ctx context.Context, groupId, ownerId string) (* if err := json.Unmarshal(respBody, &data); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &data.Id, status, nil } @@ -508,9 +556,11 @@ func (c *GroupsClient) GetOwner(ctx context.Context, groupId, ownerId string) (* // First populate the `owners` field, then call this method func (c *GroupsClient) AddOwners(ctx context.Context, group *Group) (int, error) { var status int + if group.Owners == nil || len(*group.Owners) == 0 { return status, fmt.Errorf("no owners specified") } + for _, owner := range *group.Owners { // don't fail if an owner already exists checkOwnerAlreadyExists := func(resp *http.Response, o *odata.OData) bool { @@ -528,6 +578,7 @@ func (c *GroupsClient) AddOwners(ctx context.Context, group *Group) (int, error) if err != nil { return status, fmt.Errorf("json.Marshal(): %v", err) } + _, status, _, err = c.BaseClient.Post(ctx, PostHttpRequestInput{ Body: body, ConsistencyFailureFunc: RetryOn404ConsistencyFailureFunc, @@ -542,6 +593,7 @@ func (c *GroupsClient) AddOwners(ctx context.Context, group *Group) (int, error) return status, fmt.Errorf("GroupsClient.BaseClient.Post(): %v", err) } } + return status, nil } @@ -550,9 +602,11 @@ func (c *GroupsClient) AddOwners(ctx context.Context, group *Group) (int, error) // ownerIds is a *[]string containing object IDs of owners to remove. func (c *GroupsClient) RemoveOwners(ctx context.Context, id string, ownerIds *[]string) (int, error) { var status int + if ownerIds == nil || len(*ownerIds) == 0 { return status, fmt.Errorf("no owners specified") } + for _, ownerId := range *ownerIds { // check for ownership before attempting deletion if _, status, err := c.GetOwner(ctx, id, ownerId); err != nil { @@ -584,5 +638,6 @@ func (c *GroupsClient) RemoveOwners(ctx context.Context, id string, ownerIds *[] return status, fmt.Errorf("GroupsClient.BaseClient.Delete(): %v", err) } } + return status, nil } diff --git a/msgraph/identity_providers.go b/msgraph/identity_providers.go index 12978031..734cc747 100644 --- a/msgraph/identity_providers.go +++ b/msgraph/identity_providers.go @@ -33,27 +33,32 @@ func (c *IdentityProvidersClient) List(ctx context.Context) (*[]IdentityProvider if err != nil { return nil, status, fmt.Errorf("IdentityProvidersClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var data struct { IdentityProviders []IdentityProvider `json:"value"` } if err := json.Unmarshal(respBody, &data); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &data.IdentityProviders, status, nil } // Create creates a new IdentityProvider. func (c *IdentityProvidersClient) Create(ctx context.Context, provider IdentityProvider) (*IdentityProvider, int, error) { var status int + body, err := json.Marshal(provider) if err != nil { return nil, status, fmt.Errorf("json.Marshal(): %v", err) } + resp, status, _, err := c.BaseClient.Post(ctx, PostHttpRequestInput{ Body: body, ValidStatusCodes: []int{http.StatusCreated}, @@ -65,15 +70,18 @@ func (c *IdentityProvidersClient) Create(ctx context.Context, provider IdentityP if err != nil { return nil, status, fmt.Errorf("IdentityProvidersClient.BaseClient.Post(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var newProvider IdentityProvider if err := json.Unmarshal(respBody, &newProvider); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &newProvider, status, nil } @@ -90,28 +98,34 @@ func (c *IdentityProvidersClient) Get(ctx context.Context, id string) (*Identity if err != nil { return nil, status, fmt.Errorf("IdentityProvidersClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var provider IdentityProvider if err := json.Unmarshal(respBody, &provider); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &provider, status, nil } // Update amends an existing IdentityProvider. func (c *IdentityProvidersClient) Update(ctx context.Context, provider IdentityProvider) (int, error) { var status int + if provider.ID == nil { return status, errors.New("IdentityProvidersClient.Update(): cannot update identity provider with nil ID") } + body, err := json.Marshal(provider) if err != nil { return status, fmt.Errorf("json.Marshal(): %v", err) } + _, status, _, err = c.BaseClient.Patch(ctx, PatchHttpRequestInput{ Body: body, ConsistencyFailureFunc: RetryOn404ConsistencyFailureFunc, @@ -124,6 +138,7 @@ func (c *IdentityProvidersClient) Update(ctx context.Context, provider IdentityP if err != nil { return status, fmt.Errorf("IdentityProvidersClient.BaseClient.Patch(): %v", err) } + return status, nil } @@ -140,6 +155,7 @@ func (c *IdentityProvidersClient) Delete(ctx context.Context, id string) (int, e if err != nil { return status, fmt.Errorf("IdentityProvidersClient.BaseClient.Delete(): %v", err) } + return status, nil } @@ -155,16 +171,19 @@ func (c *IdentityProvidersClient) ListAvailableProviderTypes(ctx context.Context if err != nil { return nil, status, fmt.Errorf("IdentityProvidersClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var data struct { IdentityProviderTypes []string `json:"value"` } if err := json.Unmarshal(respBody, &data); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &data.IdentityProviderTypes, status, nil } diff --git a/msgraph/invitations.go b/msgraph/invitations.go index f986fd7f..82859f00 100644 --- a/msgraph/invitations.go +++ b/msgraph/invitations.go @@ -23,10 +23,12 @@ func NewInvitationsClient(tenantId string) *InvitationsClient { // Create creates a new Invitation. func (c *InvitationsClient) Create(ctx context.Context, invitation Invitation) (*Invitation, int, error) { var status int + body, err := json.Marshal(invitation) if err != nil { return nil, status, fmt.Errorf("json.Marshal(): %v", err) } + resp, status, _, err := c.BaseClient.Post(ctx, PostHttpRequestInput{ Body: body, ValidStatusCodes: []int{http.StatusCreated}, @@ -38,14 +40,17 @@ func (c *InvitationsClient) Create(ctx context.Context, invitation Invitation) ( if err != nil { return nil, status, fmt.Errorf("InvitationsClient.BaseClient.Post(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var newInvitation Invitation if err := json.Unmarshal(respBody, &newInvitation); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &newInvitation, status, nil } diff --git a/msgraph/me.go b/msgraph/me.go index 6abac353..40b3970f 100644 --- a/msgraph/me.go +++ b/msgraph/me.go @@ -25,6 +25,7 @@ func NewMeClient(tenantId string) *MeClient { // Get retrieves information about the authenticated user. func (c *MeClient) Get(ctx context.Context, query odata.Query) (*Me, int, error) { var status int + resp, status, _, err := c.BaseClient.Get(ctx, GetHttpRequestInput{ ValidStatusCodes: []int{http.StatusOK}, Uri: Uri{ @@ -36,21 +37,25 @@ func (c *MeClient) Get(ctx context.Context, query odata.Query) (*Me, int, error) if err != nil { return nil, status, fmt.Errorf("MeClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var me Me if err := json.Unmarshal(respBody, &me); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &me, status, nil } // GetProfile retrieves the profile of the authenticated user. func (c *MeClient) GetProfile(ctx context.Context, query odata.Query) (*Me, int, error) { var status int + resp, status, _, err := c.BaseClient.Get(ctx, GetHttpRequestInput{ ValidStatusCodes: []int{http.StatusOK}, Uri: Uri{ @@ -62,15 +67,18 @@ func (c *MeClient) GetProfile(ctx context.Context, query odata.Query) (*Me, int, if err != nil { return nil, status, fmt.Errorf("MeClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var me Me if err := json.Unmarshal(respBody, &me); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &me, status, nil } @@ -78,10 +86,12 @@ func (c *MeClient) GetProfile(ctx context.Context, query odata.Query) (*Me, int, // TODO: Needs testing with an O365 user principal func (c *MeClient) Sendmail(ctx context.Context, message MailMessage) (int, error) { var status int + body, err := json.Marshal(message) if err != nil { return status, fmt.Errorf("json.Marshal(): %v", err) } + _, status, _, err = c.BaseClient.Post(ctx, PostHttpRequestInput{ Body: body, ValidStatusCodes: []int{http.StatusOK, http.StatusAccepted}, @@ -93,5 +103,6 @@ func (c *MeClient) Sendmail(ctx context.Context, message MailMessage) (int, erro if err != nil { return status, fmt.Errorf("MeClient.BaseClient.Post(): %v", err) } + return status, nil } diff --git a/msgraph/namedlocations.go b/msgraph/namedlocations.go index c0ca2df0..ac5c5845 100644 --- a/msgraph/namedlocations.go +++ b/msgraph/namedlocations.go @@ -103,6 +103,7 @@ func (c *NamedLocationsClient) Delete(ctx context.Context, id string) (int, erro if err != nil { return status, fmt.Errorf("NamedLocationsClient.BaseClient.Delete(): %v", err) } + return status, nil } @@ -115,6 +116,7 @@ func (c *NamedLocationsClient) CreateIP(ctx context.Context, ipNamedLocation IPN if err != nil { return nil, status, fmt.Errorf("json.Marshal(): %v", err) } + resp, status, _, err := c.BaseClient.Post(ctx, PostHttpRequestInput{ Body: body, ValidStatusCodes: []int{http.StatusCreated}, @@ -126,15 +128,18 @@ func (c *NamedLocationsClient) CreateIP(ctx context.Context, ipNamedLocation IPN if err != nil { return nil, status, fmt.Errorf("NamedLocationsClient.BaseClient.Post(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var newIPNamedLocation IPNamedLocation if err := json.Unmarshal(respBody, &newIPNamedLocation); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &newIPNamedLocation, status, nil } @@ -143,11 +148,11 @@ func (c *NamedLocationsClient) CreateCountry(ctx context.Context, countryNamedLo var status int countryNamedLocation.ODataType = utils.StringPtr(odata.TypeCountryNamedLocation) - body, err := json.Marshal(countryNamedLocation) if err != nil { return nil, status, fmt.Errorf("json.Marshal(): %v", err) } + resp, status, _, err := c.BaseClient.Post(ctx, PostHttpRequestInput{ Body: body, ValidStatusCodes: []int{http.StatusCreated}, @@ -159,15 +164,18 @@ func (c *NamedLocationsClient) CreateCountry(ctx context.Context, countryNamedLo if err != nil { return nil, status, fmt.Errorf("NamedLocationsClient.BaseClient.Post(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var newCountryNamedLocation CountryNamedLocation if err := json.Unmarshal(respBody, &newCountryNamedLocation); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &newCountryNamedLocation, status, nil } @@ -185,15 +193,18 @@ func (c *NamedLocationsClient) GetIP(ctx context.Context, id string, query odata if err != nil { return nil, status, fmt.Errorf("NamedLocationsClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var ipNamedLocation IPNamedLocation if err := json.Unmarshal(respBody, &ipNamedLocation); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &ipNamedLocation, status, nil } @@ -211,6 +222,7 @@ func (c *NamedLocationsClient) Get(ctx context.Context, id string, query odata.Q if err != nil { return nil, status, fmt.Errorf("NamedLocationsClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { @@ -263,15 +275,18 @@ func (c *NamedLocationsClient) GetCountry(ctx context.Context, id string, query if err != nil { return nil, status, fmt.Errorf("NamedLocationsClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var countryNamedLocation CountryNamedLocation if err := json.Unmarshal(respBody, &countryNamedLocation); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &countryNamedLocation, status, nil } @@ -280,11 +295,11 @@ func (c *NamedLocationsClient) UpdateIP(ctx context.Context, ipNamedLocation IPN var status int ipNamedLocation.ODataType = utils.StringPtr(odata.TypeIpNamedLocation) - body, err := json.Marshal(ipNamedLocation) if err != nil { return status, fmt.Errorf("json.Marshal(): %v", err) } + _, status, _, err = c.BaseClient.Patch(ctx, PatchHttpRequestInput{ Body: body, ConsistencyFailureFunc: RetryOn404ConsistencyFailureFunc, @@ -297,6 +312,7 @@ func (c *NamedLocationsClient) UpdateIP(ctx context.Context, ipNamedLocation IPN if err != nil { return status, fmt.Errorf("NamedLocationsClient.BaseClient.Patch(): %v", err) } + return status, nil } @@ -305,11 +321,11 @@ func (c *NamedLocationsClient) UpdateCountry(ctx context.Context, countryNamedLo var status int countryNamedLocation.ODataType = utils.StringPtr(odata.TypeCountryNamedLocation) - body, err := json.Marshal(countryNamedLocation) if err != nil { return status, fmt.Errorf("json.Marshal(): %v", err) } + _, status, _, err = c.BaseClient.Patch(ctx, PatchHttpRequestInput{ Body: body, ConsistencyFailureFunc: RetryOn404ConsistencyFailureFunc, @@ -322,5 +338,6 @@ func (c *NamedLocationsClient) UpdateCountry(ctx context.Context, countryNamedLo if err != nil { return status, fmt.Errorf("NamedLocationsClient.BaseClient.Patch(): %v", err) } + return status, nil } diff --git a/msgraph/reports.go b/msgraph/reports.go index fba44ad1..61ca5524 100644 --- a/msgraph/reports.go +++ b/msgraph/reports.go @@ -35,17 +35,20 @@ func (c *ReportsClient) GetCredentialUserRegistrationCount(ctx context.Context, if err != nil { return nil, status, fmt.Errorf("ReportsClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var data struct { CredentialUserRegistrationCount []CredentialUserRegistrationCount `json:"value"` } if err := json.Unmarshal(respBody, &data); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &data.CredentialUserRegistrationCount, status, nil } @@ -62,17 +65,20 @@ func (c *ReportsClient) GetCredentialUserRegistrationDetails(ctx context.Context if err != nil { return nil, status, fmt.Errorf("ReportsClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var data struct { CredentialUserRegistrationDetails []CredentialUserRegistrationDetails `json:"value"` } if err := json.Unmarshal(respBody, &data); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &data.CredentialUserRegistrationDetails, status, nil } @@ -89,17 +95,20 @@ func (c *ReportsClient) GetUserCredentialUsageDetails(ctx context.Context, query if err != nil { return nil, status, fmt.Errorf("ReportsClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var data struct { UserCredentialUsageDetails []UserCredentialUsageDetails `json:"value"` } if err := json.Unmarshal(respBody, &data); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &data.UserCredentialUsageDetails, status, nil } @@ -116,17 +125,20 @@ func (c *ReportsClient) GetCredentialUsageSummary(ctx context.Context, period Cr if err != nil { return nil, status, fmt.Errorf("ReportsClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var data struct { CredentialUsageSummary []CredentialUsageSummary `json:"value"` } if err := json.Unmarshal(respBody, &data); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &data.CredentialUsageSummary, status, nil } @@ -143,6 +155,7 @@ func (c *ReportsClient) GetAuthenticationMethodsUsersRegisteredByFeature(ctx con if err != nil { return nil, status, fmt.Errorf("ReportsClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { @@ -150,10 +163,10 @@ func (c *ReportsClient) GetAuthenticationMethodsUsersRegisteredByFeature(ctx con } var userRegistrationFeatureSummary UserRegistrationFeatureSummary - if err := json.Unmarshal(respBody, &userRegistrationFeatureSummary); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &userRegistrationFeatureSummary, status, nil } @@ -170,6 +183,7 @@ func (c *ReportsClient) GetAuthenticationMethodsUsersRegisteredByMethod(ctx cont if err != nil { return nil, status, fmt.Errorf("ReportsClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { @@ -177,9 +191,9 @@ func (c *ReportsClient) GetAuthenticationMethodsUsersRegisteredByMethod(ctx cont } var userRegistrationMethodSummary UserRegistrationMethodSummary - if err := json.Unmarshal(respBody, &userRegistrationMethodSummary); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &userRegistrationMethodSummary, status, nil } diff --git a/msgraph/schema_extensions.go b/msgraph/schema_extensions.go index b5764941..9cb378bc 100644 --- a/msgraph/schema_extensions.go +++ b/msgraph/schema_extensions.go @@ -36,17 +36,20 @@ func (c *SchemaExtensionsClient) List(ctx context.Context, query odata.Query) (* if err != nil { return nil, status, fmt.Errorf("SchemaExtensionsClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var data struct { SchemaExtensions []SchemaExtension `json:"value"` } if err := json.Unmarshal(respBody, &data); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &data.SchemaExtensions, status, nil } @@ -64,25 +67,30 @@ func (c *SchemaExtensionsClient) Get(ctx context.Context, id string, query odata if err != nil { return nil, status, fmt.Errorf("SchemaExtensionsClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var schemaExtension SchemaExtension if err := json.Unmarshal(respBody, &schemaExtension); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &schemaExtension, status, nil } // Update amends an existing schema Extension. func (c *SchemaExtensionsClient) Update(ctx context.Context, schemaExtension SchemaExtension) (int, error) { var status int + body, err := json.Marshal(schemaExtension) if err != nil { return status, fmt.Errorf("json.Marshal(): %v", err) } + _, status, _, err = c.BaseClient.Patch(ctx, PatchHttpRequestInput{ Body: body, ConsistencyFailureFunc: RetryOn404ConsistencyFailureFunc, @@ -95,16 +103,19 @@ func (c *SchemaExtensionsClient) Update(ctx context.Context, schemaExtension Sch if err != nil { return status, fmt.Errorf("SchemaExtensionsClient.BaseClient.Patch(): %v", err) } + return status, nil } // Create creates a new Schema Extension func (c *SchemaExtensionsClient) Create(ctx context.Context, schemaExtension SchemaExtension) (*SchemaExtension, int, error) { var status int + body, err := json.Marshal(schemaExtension) if err != nil { return nil, status, fmt.Errorf("json.Marshal(): %v", err) } + resp, status, _, err := c.BaseClient.Post(ctx, PostHttpRequestInput{ Body: body, ValidStatusCodes: []int{http.StatusCreated}, @@ -116,15 +127,18 @@ func (c *SchemaExtensionsClient) Create(ctx context.Context, schemaExtension Sch if err != nil { return nil, status, fmt.Errorf("SchemaExtensionsClient.BaseClient.Post(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var newSchemaExtension SchemaExtension if err := json.Unmarshal(respBody, &newSchemaExtension); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &newSchemaExtension, status, nil } @@ -141,5 +155,6 @@ func (c *SchemaExtensionsClient) Delete(ctx context.Context, id string) (int, er if err != nil { return status, fmt.Errorf("SchemaExtensionsClient.BaseClient.Delete(): %v", err) } + return status, nil } diff --git a/msgraph/serviceprincipals.go b/msgraph/serviceprincipals.go index 8bace3c7..8aefea25 100644 --- a/msgraph/serviceprincipals.go +++ b/msgraph/serviceprincipals.go @@ -37,30 +37,36 @@ func (c *ServicePrincipalsClient) List(ctx context.Context, query odata.Query) ( if err != nil { return nil, status, fmt.Errorf("ServicePrincipalsClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var data struct { ServicePrincipals []ServicePrincipal `json:"value"` } if err := json.Unmarshal(respBody, &data); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &data.ServicePrincipals, status, nil } // Create creates a new Service Principal. func (c *ServicePrincipalsClient) Create(ctx context.Context, servicePrincipal ServicePrincipal) (*ServicePrincipal, int, error) { var status int + body, err := json.Marshal(servicePrincipal) if err != nil { return nil, status, fmt.Errorf("json.Marshal(): %v", err) } + appNotReplicated := func(resp *http.Response, o *odata.OData) bool { return o != nil && o.Error != nil && o.Error.Match(odata.ErrorServicePrincipalInvalidAppId) } + resp, status, _, err := c.BaseClient.Post(ctx, PostHttpRequestInput{ Body: body, ConsistencyFailureFunc: appNotReplicated, @@ -73,15 +79,18 @@ func (c *ServicePrincipalsClient) Create(ctx context.Context, servicePrincipal S if err != nil { return nil, status, fmt.Errorf("ServicePrincipalsClient.BaseClient.Post(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var newServicePrincipal ServicePrincipal if err := json.Unmarshal(respBody, &newServicePrincipal); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &newServicePrincipal, status, nil } @@ -99,28 +108,34 @@ func (c *ServicePrincipalsClient) Get(ctx context.Context, id string, query odat if err != nil { return nil, status, fmt.Errorf("ServicePrincipalsClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var servicePrincipal ServicePrincipal if err := json.Unmarshal(respBody, &servicePrincipal); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &servicePrincipal, status, nil } // Update amends an existing Service Principal. func (c *ServicePrincipalsClient) Update(ctx context.Context, servicePrincipal ServicePrincipal) (int, error) { var status int + if servicePrincipal.ID == nil { return status, errors.New("cannot update service principal with nil ID") } + body, err := json.Marshal(servicePrincipal) if err != nil { return status, fmt.Errorf("json.Marshal(): %v", err) } + _, status, _, err = c.BaseClient.Patch(ctx, PatchHttpRequestInput{ Body: body, ConsistencyFailureFunc: RetryOn404ConsistencyFailureFunc, @@ -133,6 +148,7 @@ func (c *ServicePrincipalsClient) Update(ctx context.Context, servicePrincipal S if err != nil { return status, fmt.Errorf("ServicePrincipalsClient.BaseClient.Patch(): %v", err) } + return status, nil } @@ -149,6 +165,7 @@ func (c *ServicePrincipalsClient) Delete(ctx context.Context, id string) (int, e if err != nil { return status, fmt.Errorf("ServicePrincipalsClient.BaseClient.Delete(): %v", err) } + return status, nil } @@ -167,11 +184,13 @@ func (c *ServicePrincipalsClient) ListOwners(ctx context.Context, id string) (*[ if err != nil { return nil, status, fmt.Errorf("ServicePrincipalsClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var data struct { Owners []struct { Type string `json:"@odata.type"` @@ -181,10 +200,12 @@ func (c *ServicePrincipalsClient) ListOwners(ctx context.Context, id string) (*[ if err := json.Unmarshal(respBody, &data); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + ret := make([]string, len(data.Owners)) for i, v := range data.Owners { ret[i] = v.Id } + return &ret, status, nil } @@ -204,11 +225,13 @@ func (c *ServicePrincipalsClient) GetOwner(ctx context.Context, servicePrincipal if err != nil { return nil, status, fmt.Errorf("ServicePrincipalsClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var data struct { Context string `json:"@odata.context"` Type string `json:"@odata.type"` @@ -218,6 +241,7 @@ func (c *ServicePrincipalsClient) GetOwner(ctx context.Context, servicePrincipal if err := json.Unmarshal(respBody, &data); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &data.Id, status, nil } @@ -225,12 +249,14 @@ func (c *ServicePrincipalsClient) GetOwner(ctx context.Context, servicePrincipal // First populate the `owners` field, then call this method func (c *ServicePrincipalsClient) AddOwners(ctx context.Context, servicePrincipal *ServicePrincipal) (int, error) { var status int + if servicePrincipal.ID == nil { return status, errors.New("cannot update service principal with nil ID") } if servicePrincipal.Owners == nil { return status, errors.New("cannot update service principal with nil Owners") } + for _, owner := range *servicePrincipal.Owners { // don't fail if an owner already exists checkOwnerAlreadyExists := func(resp *http.Response, o *odata.OData) bool { @@ -248,6 +274,7 @@ func (c *ServicePrincipalsClient) AddOwners(ctx context.Context, servicePrincipa if err != nil { return status, fmt.Errorf("json.Marshal(): %v", err) } + _, status, _, err = c.BaseClient.Post(ctx, PostHttpRequestInput{ Body: body, ConsistencyFailureFunc: RetryOn404ConsistencyFailureFunc, @@ -262,6 +289,7 @@ func (c *ServicePrincipalsClient) AddOwners(ctx context.Context, servicePrincipa return status, fmt.Errorf("ServicePrincipalsClient.BaseClient.Post(): %v", err) } } + return status, nil } @@ -270,9 +298,11 @@ func (c *ServicePrincipalsClient) AddOwners(ctx context.Context, servicePrincipa // ownerIds is a *[]string containing object IDs of owners to remove. func (c *ServicePrincipalsClient) RemoveOwners(ctx context.Context, servicePrincipalId string, ownerIds *[]string) (int, error) { var status int + if ownerIds == nil { return status, errors.New("cannot remove, nil ownerIds") } + for _, ownerId := range *ownerIds { // check for ownership before attempting deletion if _, status, err := c.GetOwner(ctx, servicePrincipalId, ownerId); err != nil { @@ -303,6 +333,7 @@ func (c *ServicePrincipalsClient) RemoveOwners(ctx context.Context, servicePrinc return status, fmt.Errorf("ServicePrincipalsClient.BaseClient.Delete(): %v", err) } } + return status, nil } @@ -321,23 +352,27 @@ func (c *ServicePrincipalsClient) ListGroupMemberships(ctx context.Context, id s if err != nil { return nil, status, fmt.Errorf("ServicePrincipalsClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var data struct { Groups []Group `json:"value"` } if err := json.Unmarshal(respBody, &data); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &data.Groups, status, nil } // AddPassword appends a new password credential to a Service Principal. func (c *ServicePrincipalsClient) AddPassword(ctx context.Context, servicePrincipalId string, passwordCredential PasswordCredential) (*PasswordCredential, int, error) { var status int + body, err := json.Marshal(struct { PwdCredential PasswordCredential `json:"passwordCredential"` }{ @@ -346,6 +381,7 @@ func (c *ServicePrincipalsClient) AddPassword(ctx context.Context, servicePrinci if err != nil { return nil, status, fmt.Errorf("json.Marshal(): %v", err) } + resp, status, _, err := c.BaseClient.Post(ctx, PostHttpRequestInput{ Body: body, ConsistencyFailureFunc: RetryOn404ConsistencyFailureFunc, @@ -358,21 +394,25 @@ func (c *ServicePrincipalsClient) AddPassword(ctx context.Context, servicePrinci if err != nil { return nil, status, fmt.Errorf("ServicePrincipalsClient.BaseClient.Post(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var newPasswordCredential PasswordCredential if err := json.Unmarshal(respBody, &newPasswordCredential); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &newPasswordCredential, status, nil } // RemovePassword removes a password credential from a Service Principal. func (c *ServicePrincipalsClient) RemovePassword(ctx context.Context, servicePrincipalId string, keyId string) (int, error) { var status int + body, err := json.Marshal(struct { KeyId string `json:"keyId"` }{ @@ -381,6 +421,7 @@ func (c *ServicePrincipalsClient) RemovePassword(ctx context.Context, servicePri if err != nil { return status, fmt.Errorf("json.Marshal(): %v", err) } + _, status, _, err = c.BaseClient.Post(ctx, PostHttpRequestInput{ Body: body, ConsistencyFailureFunc: RetryOn404ConsistencyFailureFunc, @@ -393,6 +434,7 @@ func (c *ServicePrincipalsClient) RemovePassword(ctx context.Context, servicePri if err != nil { return status, fmt.Errorf("ServicePrincipalsClient.BaseClient.Post(): %v", err) } + return status, nil } @@ -411,6 +453,7 @@ func (c *ServicePrincipalsClient) ListOwnedObjects(ctx context.Context, id strin if err != nil { return nil, status, err } + defer resp.Body.Close() respBody, _ := io.ReadAll(resp.Body) var data struct { @@ -422,10 +465,12 @@ func (c *ServicePrincipalsClient) ListOwnedObjects(ctx context.Context, id strin if err := json.Unmarshal(respBody, &data); err != nil { return nil, status, err } + ret := make([]string, len(data.OwnedObjects)) for i, v := range data.OwnedObjects { ret[i] = v.Id } + return &ret, status, nil } @@ -443,17 +488,20 @@ func (c *ServicePrincipalsClient) ListAppRoleAssignments(ctx context.Context, re if err != nil { return nil, status, fmt.Errorf("ServicePrincipalsClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var data struct { AppRoleAssignments []AppRoleAssignment `json:"value"` } if err := json.Unmarshal(respBody, &data); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &data.AppRoleAssignments, status, nil } @@ -470,6 +518,7 @@ func (c *ServicePrincipalsClient) RemoveAppRoleAssignment(ctx context.Context, r if err != nil { return status, fmt.Errorf("AppRoleAssignmentsClient.BaseClient.Delete(): %v", err) } + return status, nil } @@ -481,6 +530,7 @@ func (c *ServicePrincipalsClient) RemoveAppRoleAssignment(ctx context.Context, r // appRoleId: The id of the appRole (defined on the resource service principal) to assign to a user, group, or service principal. func (c *ServicePrincipalsClient) AssignAppRoleForResource(ctx context.Context, principalId, resourceId, appRoleId string) (*AppRoleAssignment, int, error) { var status int + data := struct { PrincipalId string `json:"principalId"` ResourceId string `json:"resourceId"` @@ -490,11 +540,11 @@ func (c *ServicePrincipalsClient) AssignAppRoleForResource(ctx context.Context, ResourceId: resourceId, AppRoleId: appRoleId, } - body, err := json.Marshal(data) if err != nil { return nil, status, fmt.Errorf("json.Marshal(): %v", err) } + resp, status, _, err := c.BaseClient.Post(ctx, PostHttpRequestInput{ Body: body, ConsistencyFailureFunc: RetryOn404ConsistencyFailureFunc, @@ -507,14 +557,17 @@ func (c *ServicePrincipalsClient) AssignAppRoleForResource(ctx context.Context, if err != nil { return nil, status, fmt.Errorf("ServicePrincipalsClient.BaseClient.Post(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var appRoleAssignment AppRoleAssignment if err := json.Unmarshal(respBody, &appRoleAssignment); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &appRoleAssignment, status, nil } diff --git a/msgraph/sign_in_reports.go b/msgraph/sign_in_reports.go index dd47698a..88ffa314 100644 --- a/msgraph/sign_in_reports.go +++ b/msgraph/sign_in_reports.go @@ -36,17 +36,20 @@ func (c *SignInReportsClient) List(ctx context.Context, query odata.Query) (*[]S if err != nil { return nil, status, fmt.Errorf("SignInLogsClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var data struct { SignInLogs []SignInReport `json:"value"` } if err := json.Unmarshal(respBody, &data); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &data.SignInLogs, status, nil } @@ -64,14 +67,17 @@ func (c *SignInReportsClient) Get(ctx context.Context, id string, query odata.Qu if err != nil { return nil, status, fmt.Errorf("SignInLogsClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var signInReport SignInReport if err := json.Unmarshal(respBody, &signInReport); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &signInReport, status, nil } diff --git a/msgraph/users.go b/msgraph/users.go index 52e742fc..83b36c9d 100644 --- a/msgraph/users.go +++ b/msgraph/users.go @@ -36,27 +36,32 @@ func (c *UsersClient) List(ctx context.Context, query odata.Query) (*[]User, int if err != nil { return nil, status, fmt.Errorf("UsersClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var data struct { Users []User `json:"value"` } if err := json.Unmarshal(respBody, &data); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &data.Users, status, nil } // Create creates a new User. func (c *UsersClient) Create(ctx context.Context, user User) (*User, int, error) { var status int + body, err := json.Marshal(user) if err != nil { return nil, status, fmt.Errorf("json.Marshal(): %v", err) } + resp, status, _, err := c.BaseClient.Post(ctx, PostHttpRequestInput{ Body: body, ValidStatusCodes: []int{http.StatusCreated}, @@ -68,15 +73,18 @@ func (c *UsersClient) Create(ctx context.Context, user User) (*User, int, error) if err != nil { return nil, status, fmt.Errorf("UsersClient.BaseClient.Post(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var newUser User if err := json.Unmarshal(respBody, &newUser); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &newUser, status, nil } @@ -94,15 +102,18 @@ func (c *UsersClient) Get(ctx context.Context, id string, query odata.Query) (*U if err != nil { return nil, status, fmt.Errorf("UsersClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var user User if err := json.Unmarshal(respBody, &user); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &user, status, nil } @@ -136,6 +147,7 @@ func (c *UsersClient) GetWithSchemaExtensions(ctx context.Context, id string, qu if err != nil { return nil, status, fmt.Errorf("UsersClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { @@ -146,6 +158,7 @@ func (c *UsersClient) GetWithSchemaExtensions(ctx context.Context, id string, qu if err := json.Unmarshal(respBody, user); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return user, status, nil } @@ -163,25 +176,30 @@ func (c *UsersClient) GetDeleted(ctx context.Context, id string, query odata.Que if err != nil { return nil, status, fmt.Errorf("UsersClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var user User if err := json.Unmarshal(respBody, &user); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &user, status, nil } // Update amends an existing User. func (c *UsersClient) Update(ctx context.Context, user User) (int, error) { var status int + body, err := json.Marshal(user) if err != nil { return status, fmt.Errorf("json.Marshal(): %v", err) } + _, status, _, err = c.BaseClient.Patch(ctx, PatchHttpRequestInput{ Body: body, ConsistencyFailureFunc: RetryOn404ConsistencyFailureFunc, @@ -194,6 +212,7 @@ func (c *UsersClient) Update(ctx context.Context, user User) (int, error) { if err != nil { return status, fmt.Errorf("UsersClient.BaseClient.Patch(): %v", err) } + return status, nil } @@ -210,6 +229,7 @@ func (c *UsersClient) Delete(ctx context.Context, id string) (int, error) { if err != nil { return status, fmt.Errorf("UsersClient.BaseClient.Delete(): %v", err) } + return status, nil } @@ -226,6 +246,7 @@ func (c *UsersClient) DeletePermanently(ctx context.Context, id string) (int, er if err != nil { return status, fmt.Errorf("UsersClient.BaseClient.Delete(): %v", err) } + return status, nil } @@ -243,6 +264,7 @@ func (c *UsersClient) ListDeleted(ctx context.Context, query odata.Query) (*[]Us if err != nil { return nil, status, err } + defer resp.Body.Close() respBody, _ := io.ReadAll(resp.Body) var data struct { @@ -251,6 +273,7 @@ func (c *UsersClient) ListDeleted(ctx context.Context, query odata.Query) (*[]Us if err = json.Unmarshal(respBody, &data); err != nil { return nil, status, err } + return &data.DeletedUsers, status, nil } @@ -267,15 +290,18 @@ func (c *UsersClient) RestoreDeleted(ctx context.Context, id string) (*User, int if err != nil { return nil, status, fmt.Errorf("UsersClient.BaseClient.Post(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var restoredUser User if err = json.Unmarshal(respBody, &restoredUser); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &restoredUser, status, nil } @@ -294,17 +320,20 @@ func (c *UsersClient) ListGroupMemberships(ctx context.Context, id string, query if err != nil { return nil, status, fmt.Errorf("UsersClient.BaseClient.Get(): %v", err) } + defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { return nil, status, fmt.Errorf("io.ReadAll(): %v", err) } + var data struct { Groups []Group `json:"value"` } if err := json.Unmarshal(respBody, &data); err != nil { return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) } + return &data.Groups, status, nil } @@ -312,10 +341,12 @@ func (c *UsersClient) ListGroupMemberships(ctx context.Context, id string, query // TODO: Needs testing with an O365 user principal func (c *UsersClient) Sendmail(ctx context.Context, id string, message MailMessage) (int, error) { var status int + body, err := json.Marshal(message) if err != nil { return status, fmt.Errorf("json.Marshal(): %v", err) } + _, status, _, err = c.BaseClient.Post(ctx, PostHttpRequestInput{ Body: body, ValidStatusCodes: []int{http.StatusOK, http.StatusAccepted}, @@ -327,5 +358,6 @@ func (c *UsersClient) Sendmail(ctx context.Context, id string, message MailMessa if err != nil { return status, fmt.Errorf("UsersClient.BaseClient.Post(): %v", err) } + return status, nil }