102 lines
2.3 KiB
Go
102 lines
2.3 KiB
Go
package credentials
|
|
|
|
import "time"
|
|
|
|
type AuthType string
|
|
|
|
const (
|
|
AuthPassword AuthType = "password"
|
|
AuthOAuth2 AuthType = "oauth2"
|
|
)
|
|
|
|
// Credential is the decrypted mail account secret material.
|
|
type Credential struct {
|
|
AuthType AuthType
|
|
Username string
|
|
Password string
|
|
AccessToken string
|
|
RefreshToken string
|
|
Expiry time.Time
|
|
OAuthProvider string // google | microsoft
|
|
}
|
|
|
|
func (c Credential) IsOAuth() bool {
|
|
return c.AuthType == AuthOAuth2
|
|
}
|
|
|
|
func (c Credential) NeedsRefresh() bool {
|
|
if !c.IsOAuth() || c.RefreshToken == "" {
|
|
return false
|
|
}
|
|
if c.Expiry.IsZero() {
|
|
return false
|
|
}
|
|
return time.Now().Add(2 * time.Minute).After(c.Expiry)
|
|
}
|
|
|
|
type storedPayload struct {
|
|
AuthType string `json:"auth_type,omitempty"`
|
|
Username string `json:"username"`
|
|
Password string `json:"password,omitempty"`
|
|
AccessToken string `json:"access_token,omitempty"`
|
|
RefreshToken string `json:"refresh_token,omitempty"`
|
|
Expiry string `json:"expiry,omitempty"`
|
|
OAuthProvider string `json:"oauth_provider,omitempty"`
|
|
}
|
|
|
|
func (c Credential) toStored() storedPayload {
|
|
p := storedPayload{
|
|
AuthType: string(c.AuthType),
|
|
Username: c.Username,
|
|
Password: c.Password,
|
|
AccessToken: c.AccessToken,
|
|
RefreshToken: c.RefreshToken,
|
|
OAuthProvider: c.OAuthProvider,
|
|
}
|
|
if !c.Expiry.IsZero() {
|
|
p.Expiry = c.Expiry.UTC().Format(time.RFC3339)
|
|
}
|
|
if p.AuthType == "" {
|
|
p.AuthType = string(AuthPassword)
|
|
}
|
|
return p
|
|
}
|
|
|
|
func storedToCredential(p storedPayload) (Credential, error) {
|
|
authType := AuthType(p.AuthType)
|
|
if authType == "" {
|
|
authType = AuthPassword
|
|
}
|
|
c := Credential{
|
|
AuthType: authType,
|
|
Username: p.Username,
|
|
Password: p.Password,
|
|
AccessToken: p.AccessToken,
|
|
RefreshToken: p.RefreshToken,
|
|
OAuthProvider: p.OAuthProvider,
|
|
}
|
|
if p.Expiry != "" {
|
|
t, err := time.Parse(time.RFC3339, p.Expiry)
|
|
if err != nil {
|
|
return Credential{}, err
|
|
}
|
|
c.Expiry = t
|
|
}
|
|
if c.Username == "" {
|
|
return Credential{}, errIncomplete
|
|
}
|
|
switch authType {
|
|
case AuthPassword:
|
|
if c.Password == "" {
|
|
return Credential{}, errIncomplete
|
|
}
|
|
case AuthOAuth2:
|
|
if c.AccessToken == "" {
|
|
return Credential{}, errIncomplete
|
|
}
|
|
default:
|
|
return Credential{}, errUnsupportedAuth
|
|
}
|
|
return c, nil
|
|
}
|