Skip to content

Commit

Permalink
Helper functions for getting object ID for service/user principals fr…
Browse files Browse the repository at this point in the history
…om MS Graph
  • Loading branch information
manicminer committed Feb 14, 2023
1 parent cd22390 commit f4cb642
Showing 1 changed file with 108 additions and 0 deletions.
108 changes: 108 additions & 0 deletions authentication/objectid.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package authentication

import (
"context"
"fmt"
"log"
"net/http"
"net/http/httputil"

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

func ServicePrincipalObjectID(ctx context.Context, authorizer auth.Authorizer, env environments.Environment, clientId, tenantId string) (*string, error) {
endpoint, ok := env.MicrosoftGraph.Endpoint()
if !ok {
return nil, fmt.Errorf("could not determine endpoint for Microsoft Graph in environment: %q", env.Name)
}

client := msgraph.NewServicePrincipalsClient(tenantId)
configureClient(&client.BaseClient, authorizer, *endpoint)

result, status, err := client.List(ctx, odata.Query{Filter: fmt.Sprintf("appId eq '%s'", clientId)})
if err != nil {
if status == http.StatusUnauthorized || status == http.StatusForbidden {
return nil, fmt.Errorf("access denied listing Service Principals: %+v", err)
}
return nil, fmt.Errorf("listing Service Principals: %+v", err)
}

if result == nil {
return nil, fmt.Errorf("unexpected Service Principal query result, was nil")
}

if len(*result) != 1 || (*result)[0].ID() == nil {
return nil, fmt.Errorf("unexpected Service Principal query result: %+v", *result)
}

val := (*result)[0]
return val.ID(), nil
}

func UserPrincipalObjectID(ctx context.Context, authorizer auth.Authorizer, env environments.Environment, tenantId string) (*string, error) {
endpoint, ok := env.MicrosoftGraph.Endpoint()
if !ok {
return nil, fmt.Errorf("could not determine endpoint for Microsoft Graph in environment: %q", env.Name)
}

client := msgraph.NewMeClient(tenantId)
configureClient(&client.BaseClient, authorizer, *endpoint)

result, status, err := client.Get(ctx, odata.Query{})
if err != nil {
if status == http.StatusUnauthorized || status == http.StatusForbidden {
return nil, fmt.Errorf("access denied retrieving profile: %+v", err)
}
return nil, fmt.Errorf("retrieving profile: %+v", err)
}

if result == nil {
return nil, fmt.Errorf("unexpected profile result, was nil")
}

return result.ID, nil
}

func configureClient(c *msgraph.Client, authorizer auth.Authorizer, endpoint string) {
c.ApiVersion = msgraph.Version10
c.Authorizer = authorizer
c.DisableRetries = true
c.Endpoint = endpoint
c.RequestMiddlewares = &[]msgraph.RequestMiddleware{hamiltonRequestLogger}
c.ResponseMiddlewares = &[]msgraph.ResponseMiddleware{hamiltonResponseLogger}
}

func hamiltonRequestLogger(req *http.Request) (*http.Request, error) {
if req == nil {
return nil, nil
}

if dump, err := httputil.DumpRequestOut(req, true); err == nil {
log.Printf("[DEBUG] GoAzureHelpers Request: \n%s\n", dump)
} else {
log.Printf("[DEBUG] GoAzureHelpers Request: %s to %s\n", req.Method, req.URL)
}

return req, nil
}

func hamiltonResponseLogger(req *http.Request, resp *http.Response) (*http.Response, error) {
if resp == nil {
log.Printf("[DEBUG] GoAzureHelpers Request for %s %s completed with no response", req.Method, req.URL)
return nil, nil
}

if dump, err := httputil.DumpResponse(resp, true); err == nil {
log.Printf("[DEBUG] GoAzureHelpers Response: \n%s\n", dump)
} else {
log.Printf("[DEBUG] GoAzureHelpers Response: %s for %s %s\n", resp.Status, req.Method, req.URL)
}

return resp, nil
}

0 comments on commit f4cb642

Please sign in to comment.