Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for Privileged Identity Management Groups #248

Closed
wants to merge 22 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## 0.63.0 (July 27, 2023)

- Support for [Authentication Strength Policies](https://learn.microsoft.com/en-us/graph/api/resources/authenticationstrengthpolicy?view=graph-rest-1.0) ([#249](https://github.com/manicminer/hamilton/pull/249))
- Support `Manager` value for `AccessReviewReviewerType` ([#251](https://github.com/manicminer/hamilton/pull/251))
- Bugfix: Support for specifying `null` values for `grantControls` or `sessionControls` within [Conditional Access Policies](https://learn.microsoft.com/en-us/graph/api/resources/conditionalaccesspolicy?view=graph-rest-1.0) ([#250](https://github.com/manicminer/hamilton/pull/250))
- Bugfix: correct typo in names of `AccessReviewRecurrenceType` values, and in value of `AccessPackageRequestStateDelivered` ([#252](https://github.com/manicminer/hamilton/pull/252))

## 0.62.0 (July 14, 2023)

- Support for deleting an `accessPackageResourceRoleScope` ([#245](https://github.com/manicminer/hamilton/pull/245))
Expand Down
36 changes: 36 additions & 0 deletions internal/cmd/test-cleanup/authenticationstrengthpolicies.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package main

import (
"fmt"
"log"

"github.com/hashicorp/go-azure-sdk/sdk/odata"
"github.com/manicminer/hamilton/msgraph"
)

func cleanupAuthenticationStrengthPolicies() {
client := msgraph.NewAuthenticationStrengthPoliciesClient()
client.BaseClient.Authorizer = authorizer

authStrengthPolicies, _, err := client.List(ctx, odata.Query{Filter: fmt.Sprintf("startsWith(displayName, '%s')", displayNamePrefix)})
if err != nil {
log.Println(err)
return
}
if authStrengthPolicies == nil {
log.Println("bad API response, nil authStrengthPolicies result received")
return
}
for _, policy := range *authStrengthPolicies {
if policy.ID == nil || policy.DisplayName == nil {
log.Println("Authentication Strength Policy returned with nil ID or DisplayName")
continue
}

log.Printf("Deleting Authentication Strength Policy %q (DisplayName: %q)\n", *policy.ID, *policy.DisplayName)
_, err := client.Delete(ctx, *policy.ID)
if err != nil {
log.Printf("Error when deleting Authentication Strength Policy %q: %v\n", *policy.ID, err)
}
}
}
1 change: 1 addition & 0 deletions internal/cmd/test-cleanup/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ func main() {
cleanupConditionalAccessPolicies()
cleanupConnectedOrganizations()
cleanupNamedLocations()
cleanupAuthenticationStrengthPolicies()
cleanupServicePrincipals()
cleanupApplications()
cleanupGroups()
Expand Down
111 changes: 64 additions & 47 deletions internal/test/testing.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"os"
"strconv"
"testing"
"time"

"github.com/hashicorp/go-azure-sdk/sdk/auth"
"github.com/hashicorp/go-azure-sdk/sdk/claims"
Expand Down Expand Up @@ -90,59 +91,65 @@ type Test struct {
Claims *claims.Claims
Token *oauth2.Token

AccessPackageAssignmentPolicyClient *msgraph.AccessPackageAssignmentPolicyClient
AccessPackageAssignmentRequestClient *msgraph.AccessPackageAssignmentRequestClient
AccessPackageCatalogClient *msgraph.AccessPackageCatalogClient
AccessPackageClient *msgraph.AccessPackageClient
AccessPackageResourceClient *msgraph.AccessPackageResourceClient
AccessPackageResourceRequestClient *msgraph.AccessPackageResourceRequestClient
AccessPackageResourceRoleScopeClient *msgraph.AccessPackageResourceRoleScopeClient
AdministrativeUnitsClient *msgraph.AdministrativeUnitsClient
ApplicationTemplatesClient *msgraph.ApplicationTemplatesClient
ApplicationsClient *msgraph.ApplicationsClient
AppRoleAssignedToClient *msgraph.AppRoleAssignedToClient
AuthenticationMethodsClient *msgraph.AuthenticationMethodsClient
B2CUserFlowClient *msgraph.B2CUserFlowClient
ClaimsMappingPolicyClient *msgraph.ClaimsMappingPolicyClient
ConditionalAccessPoliciesClient *msgraph.ConditionalAccessPoliciesClient
ConnectedOrganizationClient *msgraph.ConnectedOrganizationClient
DelegatedPermissionGrantsClient *msgraph.DelegatedPermissionGrantsClient
DirectoryAuditReportsClient *msgraph.DirectoryAuditReportsClient
DirectoryObjectsClient *msgraph.DirectoryObjectsClient
DirectoryRoleTemplatesClient *msgraph.DirectoryRoleTemplatesClient
DirectoryRolesClient *msgraph.DirectoryRolesClient
DomainsClient *msgraph.DomainsClient
EntitlementRoleAssignmentsClient *msgraph.EntitlementRoleAssignmentsClient
EntitlementRoleDefinitionsClient *msgraph.EntitlementRoleDefinitionsClient
GroupsAppRoleAssignmentsClient *msgraph.AppRoleAssignmentsClient
GroupsClient *msgraph.GroupsClient
IdentityProvidersClient *msgraph.IdentityProvidersClient
InvitationsClient *msgraph.InvitationsClient
MeClient *msgraph.MeClient
NamedLocationsClient *msgraph.NamedLocationsClient
ReportsClient *msgraph.ReportsClient
RoleAssignmentsClient *msgraph.RoleAssignmentsClient
RoleDefinitionsClient *msgraph.RoleDefinitionsClient
RoleEligibilityScheduleRequestClient *msgraph.RoleEligibilityScheduleRequestClient
SchemaExtensionsClient *msgraph.SchemaExtensionsClient
ServicePrincipalsAppRoleAssignmentsClient *msgraph.AppRoleAssignmentsClient
ServicePrincipalsClient *msgraph.ServicePrincipalsClient
SignInReportsClient *msgraph.SignInReportsClient
SynchronizationJobClient *msgraph.SynchronizationJobClient
TermsOfUseAgreementClient *msgraph.TermsOfUseAgreementClient
TokenIssuancePolicyClient *msgraph.TokenIssuancePolicyClient
UserFlowAttributesClient *msgraph.UserFlowAttributesClient
UsersAppRoleAssignmentsClient *msgraph.AppRoleAssignmentsClient
UsersClient *msgraph.UsersClient
WindowsAutopilotDeploymentProfilesClient *msgraph.WindowsAutopilotDeploymentProfilesClient
AccessPackageAssignmentPolicyClient *msgraph.AccessPackageAssignmentPolicyClient
AccessPackageAssignmentRequestClient *msgraph.AccessPackageAssignmentRequestClient
AccessPackageCatalogClient *msgraph.AccessPackageCatalogClient
AccessPackageClient *msgraph.AccessPackageClient
AccessPackageResourceClient *msgraph.AccessPackageResourceClient
AccessPackageResourceRequestClient *msgraph.AccessPackageResourceRequestClient
AccessPackageResourceRoleScopeClient *msgraph.AccessPackageResourceRoleScopeClient
AdministrativeUnitsClient *msgraph.AdministrativeUnitsClient
ApplicationTemplatesClient *msgraph.ApplicationTemplatesClient
ApplicationsClient *msgraph.ApplicationsClient
AppRoleAssignedToClient *msgraph.AppRoleAssignedToClient
AuthenticationMethodsClient *msgraph.AuthenticationMethodsClient
AuthenticationStrengthPoliciesClient *msgraph.AuthenticationStrengthPoliciesClient
B2CUserFlowClient *msgraph.B2CUserFlowClient
ClaimsMappingPolicyClient *msgraph.ClaimsMappingPolicyClient
ConditionalAccessPoliciesClient *msgraph.ConditionalAccessPoliciesClient
ConnectedOrganizationClient *msgraph.ConnectedOrganizationClient
DelegatedPermissionGrantsClient *msgraph.DelegatedPermissionGrantsClient
DirectoryAuditReportsClient *msgraph.DirectoryAuditReportsClient
DirectoryObjectsClient *msgraph.DirectoryObjectsClient
DirectoryRoleTemplatesClient *msgraph.DirectoryRoleTemplatesClient
DirectoryRolesClient *msgraph.DirectoryRolesClient
DomainsClient *msgraph.DomainsClient
EntitlementRoleAssignmentsClient *msgraph.EntitlementRoleAssignmentsClient
EntitlementRoleDefinitionsClient *msgraph.EntitlementRoleDefinitionsClient
GroupsAppRoleAssignmentsClient *msgraph.AppRoleAssignmentsClient
GroupsClient *msgraph.GroupsClient
IdentityProvidersClient *msgraph.IdentityProvidersClient
InvitationsClient *msgraph.InvitationsClient
MeClient *msgraph.MeClient
NamedLocationsClient *msgraph.NamedLocationsClient
PrivilegedAccessGroupClient *msgraph.PrivilegedAccessGroupClient
PrivilegedAccessGroupAssignmentScheduleClient *msgraph.PrivilegedAccessGroupAssignmentScheduleClient
PrivilegedAccessGroupAssignmentScheduleRequestClient *msgraph.PrivilegedAccessGroupAssignmentScheduleRequestClient
ReportsClient *msgraph.ReportsClient
RoleAssignmentsClient *msgraph.RoleAssignmentsClient
RoleDefinitionsClient *msgraph.RoleDefinitionsClient
RoleEligibilityScheduleRequestClient *msgraph.RoleEligibilityScheduleRequestClient
SchemaExtensionsClient *msgraph.SchemaExtensionsClient
ServicePrincipalsAppRoleAssignmentsClient *msgraph.AppRoleAssignmentsClient
ServicePrincipalsClient *msgraph.ServicePrincipalsClient
SignInReportsClient *msgraph.SignInReportsClient
SynchronizationJobClient *msgraph.SynchronizationJobClient
TermsOfUseAgreementClient *msgraph.TermsOfUseAgreementClient
TokenIssuancePolicyClient *msgraph.TokenIssuancePolicyClient
UserFlowAttributesClient *msgraph.UserFlowAttributesClient
UsersAppRoleAssignmentsClient *msgraph.AppRoleAssignmentsClient
UsersClient *msgraph.UsersClient
WindowsAutopilotDeploymentProfilesClient *msgraph.WindowsAutopilotDeploymentProfilesClient
}

func NewTest(t *testing.T) (c *Test) {
ctx := context.Background()
var cancel context.CancelFunc = func() {}
var cancel context.CancelFunc

if deadline, ok := t.Deadline(); ok {
ctx, cancel = context.WithDeadline(context.Background(), deadline)
ctx, cancel = context.WithDeadline(ctx, deadline)
} else {
ctx, cancel = context.WithTimeout(ctx, 5*time.Minute)
}

c = &Test{
Expand Down Expand Up @@ -246,6 +253,11 @@ func NewTest(t *testing.T) (c *Test) {
c.AuthenticationMethodsClient.BaseClient.Endpoint = *endpoint
c.AuthenticationMethodsClient.BaseClient.RetryableClient.RetryMax = retry

c.AuthenticationStrengthPoliciesClient = msgraph.NewAuthenticationStrengthPoliciesClient()
c.AuthenticationStrengthPoliciesClient.BaseClient.Authorizer = c.Connections["default"].Authorizer
c.AuthenticationStrengthPoliciesClient.BaseClient.Endpoint = *endpoint
c.AuthenticationStrengthPoliciesClient.BaseClient.RetryableClient.RetryMax = retry

c.B2CUserFlowClient = msgraph.NewB2CUserFlowClient()
c.B2CUserFlowClient.BaseClient.Authorizer = c.Connections["b2c"].Authorizer
c.B2CUserFlowClient.BaseClient.Endpoint = *endpoint
Expand Down Expand Up @@ -336,6 +348,11 @@ func NewTest(t *testing.T) (c *Test) {
c.NamedLocationsClient.BaseClient.Endpoint = *endpoint
c.NamedLocationsClient.BaseClient.RetryableClient.RetryMax = retry

c.PrivilegedAccessGroupClient = msgraph.NewPrivilegedAccessGroupClient()
c.PrivilegedAccessGroupClient.BaseClient.Authorizer = c.Connections["default"].Authorizer
c.PrivilegedAccessGroupClient.BaseClient.Endpoint = *endpoint
c.PrivilegedAccessGroupClient.BaseClient.RetryableClient.RetryMax = retry

c.ReportsClient = msgraph.NewReportsClient()
c.ReportsClient.BaseClient.Authorizer = c.Connections["default"].Authorizer
c.ReportsClient.BaseClient.Endpoint = *endpoint
Expand Down
46 changes: 46 additions & 0 deletions msgraph/accesspackageassignmentapproval.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package msgraph

import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
)

type AccessPackageAssignmentApprovalClient struct {
BaseClient Client
}

func NewAccessPackageAssignmentApprovalClient() *AccessPackageAssignmentApprovalClient {
return &AccessPackageAssignmentApprovalClient{
BaseClient: NewClient(Version10),
}
}

// Get will get an approval
func (c *AccessPackageAssignmentApprovalClient) Get(ctx context.Context, id string) (*Approval, int, error) {
resp, status, _, err := c.BaseClient.Get(ctx, GetHttpRequestInput{
ConsistencyFailureFunc: RetryOn404ConsistencyFailureFunc,
ValidStatusCodes: []int{http.StatusOK},
Uri: Uri{
Entity: fmt.Sprintf("/identityGovernance/entitlementManagement/accessPackageAssignmentApprovals/%s", id),
},
})
if err != nil {
return nil, status, fmt.Errorf("AccessPackageAssignmentApprovalClient.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 approval Approval
if err := json.Unmarshal(respBody, &approval); err != nil {
return nil, status, fmt.Errorf("json.Unmarshal(): %v", err)
}

return &approval, status, nil
}
107 changes: 107 additions & 0 deletions msgraph/accesspackageassignmentapprovalstep.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package msgraph

import (
"context"
"encoding/json"
"errors"
"fmt"
"io"
"net/http"

"github.com/hashicorp/go-azure-sdk/sdk/odata"
)

type AccessPackageAssignmentApprovalStepClient struct {
BaseClient Client
}

func NewAccessPackageAssignmentApprovalStepClient() *AccessPackageAssignmentApprovalStepClient {
return &AccessPackageAssignmentApprovalStepClient{
BaseClient: NewClient(Version10),
}
}

// List returns a list of Approval Steps for an approval
func (c *AccessPackageAssignmentApprovalStepClient) List(ctx context.Context, approvalId string, query odata.Query) (*[]ApprovalStep, int, error) {
resp, status, _, err := c.BaseClient.Get(ctx, GetHttpRequestInput{
DisablePaging: query.Top > 0,
OData: query,
ValidStatusCodes: []int{http.StatusOK},
Uri: Uri{
Entity: fmt.Sprintf("/identityGovernance/entitlementManagement/accessPackageAssignmentApprovals/%s/steps", approvalId),
},
})
if err != nil {
return nil, status, fmt.Errorf("AccessPackageAssignmentPolicyClient.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 {
ApprovalStep []ApprovalStep `json:"value"`
}
if err := json.Unmarshal(respBody, &data); err != nil {
return nil, status, fmt.Errorf("json.Unmarshal(): %v", err)
}

return &data.ApprovalStep, status, nil
}

// Get will get an approval step
func (c *AccessPackageAssignmentApprovalStepClient) Get(ctx context.Context, id, approvalId string) (*ApprovalStep, int, error) {
resp, status, _, err := c.BaseClient.Get(ctx, GetHttpRequestInput{
ConsistencyFailureFunc: RetryOn404ConsistencyFailureFunc,
ValidStatusCodes: []int{http.StatusOK},
Uri: Uri{
Entity: fmt.Sprintf("/identityGovernance/entitlementManagement/accessPackageAssignmentApprovals/%s/steps/%s", approvalId, id),
},
})
if err != nil {
return nil, status, fmt.Errorf("AccessPackageAssignmentApprovalStepClient.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 step ApprovalStep
if err := json.Unmarshal(respBody, &step); err != nil {
return nil, status, fmt.Errorf("json.Unmarshal(): %v", err)
}

return &step, status, nil
}

// Update amends an existing AccessPackageAssignmentPolicy.
func (c *AccessPackageAssignmentApprovalStepClient) Update(ctx context.Context, step ApprovalStep, approvalId string) (int, error) {
var status int

if step.ID == nil {
return status, errors.New("cannot update ApprovalStep with nil ID")
}

body, err := json.Marshal(step)
if err != nil {
return status, fmt.Errorf("json.Marshal(): %v", err)
}

_, status, _, err = c.BaseClient.Put(ctx, PutHttpRequestInput{ //This is usually a patch but this endpoint uses PUT
Body: body,
ConsistencyFailureFunc: RetryOn404ConsistencyFailureFunc,
ValidStatusCodes: []int{http.StatusOK},
Uri: Uri{
Entity: fmt.Sprintf("/identityGovernance/entitlementManagement/accessPackageAssignmentApprovals/%s/steps/%s", approvalId, *step.ID),
},
})
if err != nil {
return status, fmt.Errorf("AccessPackageAssignmentApprovalStepClient.BaseClient.Put(): %v", err)
}

return status, nil
}
2 changes: 1 addition & 1 deletion msgraph/accesspackageassignmentpolicy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func TestAccessPackageAssignmentPolicyClient(t *testing.T) {
IsEnabled: utils.BoolPtr(true),
StartDateTime: &currentTimePlusDay,
DurationInDays: utils.Int32Ptr(5),
RecurrenceType: msgraph.AccessReviewRecurranceTypeMonthly,
RecurrenceType: msgraph.AccessReviewRecurrenceTypeMonthly,
ReviewerType: msgraph.AccessReviewReviewerTypeSelf,
IsAccessRecommendationEnabled: utils.BoolPtr(true),
IsApprovalJustificationRequired: utils.BoolPtr(true),
Expand Down
2 changes: 1 addition & 1 deletion msgraph/accesspackageassignmentrequest_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func TestAccessPackageAssignmentRequestClient(t *testing.T) {
IsEnabled: utils.BoolPtr(true),
StartDateTime: &currentTime,
DurationInDays: utils.Int32Ptr(5),
RecurrenceType: msgraph.AccessReviewRecurranceTypeMonthly,
RecurrenceType: msgraph.AccessReviewRecurrenceTypeMonthly,
ReviewerType: msgraph.AccessReviewReviewerTypeSelf,
IsAccessRecommendationEnabled: utils.BoolPtr(true),
IsApprovalJustificationRequired: utils.BoolPtr(true),
Expand Down
Loading