summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/matterbridge/msgraph.go/msauth/device_authorization_grant.go
diff options
context:
space:
mode:
authorWim <wim@42.be>2020-03-08 17:08:18 +0100
committerGitHub <noreply@github.com>2020-03-08 17:08:18 +0100
commit9785edd26366be8eb11c2435f50f90a5c8eea7fc (patch)
treee8e236b5b273e7535c607507cc059f3b957068a1 /vendor/github.com/matterbridge/msgraph.go/msauth/device_authorization_grant.go
parent2a0bc11b684f63305258e338c5f1d0e91eb24414 (diff)
downloadmatterbridge-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.go96
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
+ }
+ }
+}