Skip to content

Commit

Permalink
Add domainHint parameter to Microsoft Connector (#2586)
Browse files Browse the repository at this point in the history
Signed-off-by: Joe Knight <josephtknight@users.noreply.github.com>
  • Loading branch information
josephtknight authored Jul 25, 2022
1 parent 367487d commit 27c25d0
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 1 deletion.
6 changes: 6 additions & 0 deletions connector/microsoft/microsoft.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ type Config struct {
// PromptType is used for the prompt query parameter.
// For valid values, see https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow#request-an-authorization-code.
PromptType string `json:"promptType"`
DomainHint string `json:"domainHint"`
}

// Open returns a strategy for logging in through Microsoft.
Expand All @@ -75,6 +76,7 @@ func (c *Config) Open(id string, logger log.Logger) (connector.Connector, error)
logger: logger,
emailToLowercase: c.EmailToLowercase,
promptType: c.PromptType,
domainHint: c.DomainHint,
}
// By default allow logins from both personal and business/school
// accounts.
Expand Down Expand Up @@ -119,6 +121,7 @@ type microsoftConnector struct {
logger log.Logger
emailToLowercase bool
promptType string
domainHint string
}

func (c *microsoftConnector) isOrgTenant() bool {
Expand Down Expand Up @@ -160,6 +163,9 @@ func (c *microsoftConnector) LoginURL(scopes connector.Scopes, callbackURL, stat
if c.promptType != "" {
options = append(options, oauth2.SetAuthURLParam("prompt", c.promptType))
}
if c.domainHint != "" {
options = append(options, oauth2.SetAuthURLParam("domain_hint", c.domainHint))
}

return c.oauth2Config(scopes).AuthCodeURL(state, options...), nil
}
Expand Down
58 changes: 57 additions & 1 deletion connector/microsoft/microsoft_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"net/http"
"net/http/httptest"
"net/url"
"os"
"reflect"
"testing"
Expand All @@ -16,13 +17,68 @@ type testResponse struct {
data interface{}
}

const tenant = "9b1c3439-a67e-4e92-bb0d-0571d44ca965"
const (
tenant = "9b1c3439-a67e-4e92-bb0d-0571d44ca965"
clientID = "a115ebf3-6020-4384-8eb1-c0c42e667b6f"
)

var dummyToken = testResponse{data: map[string]interface{}{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9",
"expires_in": "30",
}}

func TestLoginURL(t *testing.T) {
testURL := "https://test.com"
testState := "some-state"

conn := microsoftConnector{
apiURL: testURL,
graphURL: testURL,
redirectURI: testURL,
clientID: clientID,
tenant: tenant,
}

loginURL, _ := conn.LoginURL(connector.Scopes{}, conn.redirectURI, testState)

parsedLoginURL, _ := url.Parse(loginURL)
queryParams := parsedLoginURL.Query()

expectEquals(t, parsedLoginURL.Path, "/"+tenant+"/oauth2/v2.0/authorize")
expectEquals(t, queryParams.Get("client_id"), clientID)
expectEquals(t, queryParams.Get("redirect_uri"), testURL)
expectEquals(t, queryParams.Get("response_type"), "code")
expectEquals(t, queryParams.Get("scope"), "user.read")
expectEquals(t, queryParams.Get("state"), testState)
expectEquals(t, queryParams.Get("prompt"), "")
expectEquals(t, queryParams.Get("domain_hint"), "")
}

func TestLoginURLWithOptions(t *testing.T) {
testURL := "https://test.com"
promptType := "consent"
domainHint := "domain.hint"

conn := microsoftConnector{
apiURL: testURL,
graphURL: testURL,
redirectURI: testURL,
clientID: clientID,
tenant: tenant,

promptType: promptType,
domainHint: domainHint,
}

loginURL, _ := conn.LoginURL(connector.Scopes{}, conn.redirectURI, "some-state")

parsedLoginURL, _ := url.Parse(loginURL)
queryParams := parsedLoginURL.Query()

expectEquals(t, queryParams.Get("prompt"), promptType)
expectEquals(t, queryParams.Get("domain_hint"), domainHint)
}

func TestUserIdentityFromGraphAPI(t *testing.T) {
s := newTestServer(map[string]testResponse{
"/v1.0/me?$select=id,displayName,userPrincipalName": {
Expand Down

0 comments on commit 27c25d0

Please sign in to comment.