mirror of
https://github.com/volatiletech/authboss.git
synced 2025-01-10 04:17:59 +02:00
48b33b0217
- Add helper to directly merge data into a request (common use case) - Allow parsing of OAuth2PID without panic - Add oauth2.* strings to the modules list in case people want to be able to switch on which oauth2 providers are available in their views.
181 lines
5.1 KiB
Go
181 lines
5.1 KiB
Go
package authboss
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
// User has functions for each piece of data it requires.
|
|
// Data should not be persisted on each function call.
|
|
// User has a PID (primary ID) that is used on the site as
|
|
// a single unique identifier to any given user (very typically e-mail
|
|
// or username).
|
|
//
|
|
// User interfaces return no errors or bools to signal that a value was
|
|
// not present. Instead 0-value = null = not present, this puts the onus
|
|
// on Authboss code to check for this.
|
|
type User interface {
|
|
GetPID() (pid string)
|
|
PutPID(pid string)
|
|
}
|
|
|
|
// AuthableUser is identified by a password
|
|
type AuthableUser interface {
|
|
User
|
|
|
|
GetPassword() (password string)
|
|
PutPassword(password string)
|
|
}
|
|
|
|
// ConfirmableUser can be in a state of confirmed or not
|
|
type ConfirmableUser interface {
|
|
User
|
|
|
|
GetConfirmed() (confirmed bool)
|
|
GetConfirmToken() (token string)
|
|
GetEmail() (email string)
|
|
|
|
PutConfirmed(confirmed bool)
|
|
PutConfirmToken(token string)
|
|
PutEmail(email string)
|
|
}
|
|
|
|
// LockableUser is a user that can be locked
|
|
type LockableUser interface {
|
|
User
|
|
|
|
GetAttemptCount() (attempts int)
|
|
GetLastAttempt() (last time.Time)
|
|
GetLocked() (locked time.Time)
|
|
|
|
PutAttemptCount(attempts int)
|
|
PutLastAttempt(last time.Time)
|
|
PutLocked(locked time.Time)
|
|
}
|
|
|
|
// RecoverableUser is a user that can be recovered via e-mail
|
|
type RecoverableUser interface {
|
|
AuthableUser
|
|
|
|
GetEmail() (email string)
|
|
GetRecoverToken() (token string)
|
|
GetRecoverExpiry() (expiry time.Time)
|
|
|
|
PutEmail(email string)
|
|
PutRecoverToken(token string)
|
|
PutRecoverExpiry(expiry time.Time)
|
|
}
|
|
|
|
// ArbitraryUser allows arbitrary data from the web form through. You should
|
|
// definitely only pull the keys you want from the map, since this is unfiltered
|
|
// input from a web request and is an attack vector.
|
|
type ArbitraryUser interface {
|
|
User
|
|
|
|
// GetArbitrary is used only to display the arbitrary data back to the user
|
|
// when the form is reset.
|
|
GetArbitrary() (arbitrary map[string]string)
|
|
// PutArbitrary allows arbitrary fields defined by the authboss library
|
|
// consumer to add fields to the user registration piece.
|
|
PutArbitrary(arbitrary map[string]string)
|
|
}
|
|
|
|
// OAuth2User allows reading and writing values relating to OAuth2
|
|
// Also see MakeOAuthPID/ParseOAuthPID for helpers to fullfill the User
|
|
// part of the interface.
|
|
type OAuth2User interface {
|
|
User
|
|
|
|
// IsOAuth2User checks to see if a user was registered in the site as an
|
|
// oauth2 user.
|
|
IsOAuth2User() bool
|
|
|
|
GetOAuth2UID() (uid string)
|
|
GetOAuth2Provider() (provider string)
|
|
GetOAuth2AccessToken() (token string)
|
|
GetOAuth2RefreshToken() (refreshToken string)
|
|
GetOAuth2Expiry() (expiry time.Time)
|
|
|
|
PutOAuth2UID(uid string)
|
|
PutOAuth2Provider(provider string)
|
|
PutOAuth2AccessToken(token string)
|
|
PutOAuth2RefreshToken(refreshToken string)
|
|
PutOAuth2Expiry(expiry time.Time)
|
|
}
|
|
|
|
// MustBeAuthable forces an upgrade to an AuthableUser or panic.
|
|
func MustBeAuthable(u User) AuthableUser {
|
|
if au, ok := u.(AuthableUser); ok {
|
|
return au
|
|
}
|
|
panic(fmt.Sprintf("could not upgrade user to an authable user, type: %T", u))
|
|
}
|
|
|
|
// MustBeConfirmable forces an upgrade to a ConfirmableUser or panic.
|
|
func MustBeConfirmable(u User) ConfirmableUser {
|
|
if cu, ok := u.(ConfirmableUser); ok {
|
|
return cu
|
|
}
|
|
panic(fmt.Sprintf("could not upgrade user to a confirmable user, type: %T", u))
|
|
}
|
|
|
|
// MustBeLockable forces an upgrade to a LockableUser or panic.
|
|
func MustBeLockable(u User) LockableUser {
|
|
if lu, ok := u.(LockableUser); ok {
|
|
return lu
|
|
}
|
|
panic(fmt.Sprintf("could not upgrade user to a lockable user, given type: %T", u))
|
|
}
|
|
|
|
// MustBeRecoverable forces an upgrade to a RecoverableUser or panic.
|
|
func MustBeRecoverable(u User) RecoverableUser {
|
|
if lu, ok := u.(RecoverableUser); ok {
|
|
return lu
|
|
}
|
|
panic(fmt.Sprintf("could not upgrade user to a recoverable user, given type: %T", u))
|
|
}
|
|
|
|
// MustBeOAuthable forces an upgrade to an OAuth2User or panic.
|
|
func MustBeOAuthable(u User) OAuth2User {
|
|
if ou, ok := u.(OAuth2User); ok {
|
|
return ou
|
|
}
|
|
panic(fmt.Sprintf("could not upgrade user to an oauthable user, given type: %T", u))
|
|
}
|
|
|
|
// MakeOAuth2PID is used to create a pid for users that don't have
|
|
// an e-mail address or username in the normal system. This allows
|
|
// all the modules to continue to working as intended without having
|
|
// a true primary id. As well as not having to divide the regular and oauth
|
|
// stuff all down the middle.
|
|
func MakeOAuth2PID(provider, uid string) string {
|
|
return fmt.Sprintf("oauth2;;%s;;%s", provider, uid)
|
|
}
|
|
|
|
// ParseOAuth2PID returns the uid and provider for a given OAuth2 pid
|
|
func ParseOAuth2PID(pid string) (provider, uid string, err error) {
|
|
splits := strings.Split(pid, ";;")
|
|
if len(splits) != 3 {
|
|
return "", "", errors.Errorf("failed to parse oauth2 pid, too many segments: %s", pid)
|
|
}
|
|
if splits[0] != "oauth2" {
|
|
return "", "", errors.Errorf("invalid oauth2 pid, did not start with oauth2: %s", pid)
|
|
}
|
|
|
|
return splits[1], splits[2], nil
|
|
}
|
|
|
|
// ParseOAuth2PIDP returns the uid and provider for a given OAuth2 pid
|
|
func ParseOAuth2PIDP(pid string) (provider, uid string) {
|
|
var err error
|
|
provider, uid, err = ParseOAuth2PID(pid)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
return provider, uid
|
|
}
|