mirror of
https://git.sr.ht/~rjarry/aerc
synced 2026-02-25 05:35:24 +01:00
SASL and OAuth2 authentication logic was duplicated across the IMAP worker and the SMTP sender code. Both implementations handled XOAUTH2, OAUTHBEARER, and token caching independently, making maintenance difficult and bug fixes error-prone. Move this shared logic into lib/auth where it can be reused by all backends. The IMAP worker no longer needs its own OAuth structs and configuration parsing since it can now rely on the common implementation also used by the SMTP sender. Signed-off-by: Robin Jarry <robin@jarry.cc> Reviewed-by: Simon Martin <simon@nasilyan.com>
57 lines
1.3 KiB
Go
57 lines
1.3 KiB
Go
//
|
|
// This code is derived from the go-sasl library.
|
|
//
|
|
// Copyright (c) 2016 emersion
|
|
// Copyright (c) 2022, Oracle and/or its affiliates.
|
|
//
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package auth
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
|
|
"github.com/emersion/go-sasl"
|
|
)
|
|
|
|
// An XOAUTH2 error.
|
|
type Xoauth2Error struct {
|
|
Status string `json:"status"`
|
|
Schemes string `json:"schemes"`
|
|
Scope string `json:"scope"`
|
|
}
|
|
|
|
// Implements error.
|
|
func (err *Xoauth2Error) Error() string {
|
|
return fmt.Sprintf("XOAUTH2 authentication error (%v)", err.Status)
|
|
}
|
|
|
|
const XoauthMechanism string = "XOAUTH2"
|
|
|
|
type xoauth2Client struct {
|
|
Username string
|
|
Token string
|
|
}
|
|
|
|
func (a *xoauth2Client) Start() (mech string, ir []byte, err error) {
|
|
mech = XoauthMechanism
|
|
ir = []byte("user=" + a.Username + "\x01auth=Bearer " + a.Token + "\x01\x01")
|
|
return
|
|
}
|
|
|
|
func (a *xoauth2Client) Next(challenge []byte) ([]byte, error) {
|
|
// Server sent an error response
|
|
xoauth2Err := &Xoauth2Error{}
|
|
if err := json.Unmarshal(challenge, xoauth2Err); err != nil {
|
|
return nil, err
|
|
} else {
|
|
return nil, xoauth2Err
|
|
}
|
|
}
|
|
|
|
// An implementation of the XOAUTH2 authentication mechanism, as
|
|
// described in https://developers.google.com/gmail/xoauth2_protocol.
|
|
func NewXoauth2Client(username, token string) sasl.Client {
|
|
return &xoauth2Client{username, token}
|
|
}
|