diff options
author | Wim <wim@42.be> | 2020-03-08 17:08:18 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-08 17:08:18 +0100 |
commit | 9785edd26366be8eb11c2435f50f90a5c8eea7fc (patch) | |
tree | e8e236b5b273e7535c607507cc059f3b957068a1 /vendor/github.com/matterbridge/msgraph.go/msauth/device_authorization_grant.go | |
parent | 2a0bc11b684f63305258e338c5f1d0e91eb24414 (diff) | |
download | matterbridge-msglm-9785edd26366be8eb11c2435f50f90a5c8eea7fc.tar.gz matterbridge-msglm-9785edd26366be8eb11c2435f50f90a5c8eea7fc.tar.bz2 matterbridge-msglm-9785edd26366be8eb11c2435f50f90a5c8eea7fc.zip |
Remove replace directives and use own fork to make go get work again (#1028)
See https://github.com/golang/go/issues/30354
go get doesn't honor the go.mod replace options.
Diffstat (limited to 'vendor/github.com/matterbridge/msgraph.go/msauth/device_authorization_grant.go')
-rw-r--r-- | vendor/github.com/matterbridge/msgraph.go/msauth/device_authorization_grant.go | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/vendor/github.com/matterbridge/msgraph.go/msauth/device_authorization_grant.go b/vendor/github.com/matterbridge/msgraph.go/msauth/device_authorization_grant.go new file mode 100644 index 00000000..4baafd8d --- /dev/null +++ b/vendor/github.com/matterbridge/msgraph.go/msauth/device_authorization_grant.go @@ -0,0 +1,96 @@ +package msauth + +import ( + "context" + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "net/url" + "os" + "strings" + "time" + + "golang.org/x/oauth2" + "golang.org/x/oauth2/microsoft" +) + +const ( + deviceCodeGrantType = "urn:ietf:params:oauth:grant-type:device_code" + authorizationPendingError = "authorization_pending" +) + +// DeviceCode is returned on device auth initiation +type DeviceCode struct { + DeviceCode string `json:"device_code"` + UserCode string `json:"user_code"` + VerificationURL string `json:"verification_url"` + ExpiresIn int `json:"expires_in"` + Interval int `json:"interval"` + Message string `json:"message"` +} + +// DeviceAuthorizationGrant performs OAuth 2.0 device authorization grant and returns auto-refreshing TokenSource +func (m *Manager) DeviceAuthorizationGrant(ctx context.Context, tenantID, clientID string, scopes []string, callback func(*DeviceCode) error) (oauth2.TokenSource, error) { + endpoint := microsoft.AzureADEndpoint(tenantID) + endpoint.AuthStyle = oauth2.AuthStyleInParams + config := &oauth2.Config{ + ClientID: clientID, + Endpoint: endpoint, + Scopes: scopes, + } + if t, ok := m.TokenCache[generateKey(tenantID, clientID)]; ok { + tt, err := config.TokenSource(ctx, t).Token() + if err == nil { + return config.TokenSource(ctx, tt), nil + } + if _, ok := err.(*oauth2.RetrieveError); !ok { + return nil, err + } + } + scope := strings.Join(scopes, " ") + res, err := http.PostForm(deviceCodeURL(tenantID), url.Values{"client_id": {clientID}, "scope": {scope}}) + if err != nil { + return nil, err + } + defer res.Body.Close() + if res.StatusCode != http.StatusOK { + b, _ := ioutil.ReadAll(res.Body) + return nil, fmt.Errorf("%s: %s", res.Status, string(b)) + } + dc := &DeviceCode{} + dec := json.NewDecoder(res.Body) + err = dec.Decode(&dc) + if err != nil { + return nil, err + } + if callback != nil { + err = callback(dc) + if err != nil { + return nil, err + } + } else { + fmt.Fprintln(os.Stderr, dc.Message) + } + values := url.Values{ + "client_id": {clientID}, + "grant_type": {deviceCodeGrantType}, + "device_code": {dc.DeviceCode}, + } + interval := dc.Interval + if interval == 0 { + interval = 5 + } + for { + time.Sleep(time.Second * time.Duration(interval)) + token, err := m.requestToken(ctx, tenantID, clientID, values) + if err == nil { + m.Cache(tenantID, clientID, token) + return config.TokenSource(ctx, token), nil + } + tokenError, ok := err.(*TokenError) + if !ok || tokenError.ErrorObject != authorizationPendingError { + return nil, err + } + } +} |