diff options
Diffstat (limited to 'lib/oauthbearer.go')
-rw-r--r-- | lib/oauthbearer.go | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/lib/oauthbearer.go b/lib/oauthbearer.go new file mode 100644 index 0000000..5bcba60 --- /dev/null +++ b/lib/oauthbearer.go @@ -0,0 +1,42 @@ +package lib + +import ( + "context" + "fmt" + "github.com/emersion/go-imap/client" + "github.com/emersion/go-sasl" + "golang.org/x/oauth2" +) + +type OAuthBearer struct { + OAuth2 *oauth2.Config + Enabled bool +} + +func (c *OAuthBearer) exchangeRefreshToken(refreshToken string) (*oauth2.Token, error) { + token := new(oauth2.Token) + token.RefreshToken = refreshToken + token.TokenType = "Bearer" + return c.OAuth2.TokenSource(context.TODO(), token).Token() +} + +func (c *OAuthBearer) Authenticate(username string, password string, client *client.Client) error { + if ok, err := client.SupportAuth(sasl.OAuthBearer); err != nil || !ok { + return fmt.Errorf("OAuthBearer not supported %v", err) + } + + if c.OAuth2.Endpoint.TokenURL != "" { + token, err := c.exchangeRefreshToken(password) + if err != nil { + return err + } + password = token.AccessToken + } + + saslClient := sasl.NewOAuthBearerClient(&sasl.OAuthBearerOptions{ + Username: username, + Token: password, + }) + + return client.Authenticate(saslClient) +} |