controller

package
v0.0.0-...-692b37b Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 8, 2022 License: MIT Imports: 25 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// Defaults
	DefaultTotpIssuer      = "simpleauth"
	DefaultTotpDigits      = 6
	DefaultPrivateKey      = "~/.simpleauth/simpleauth.key"
	DefaultCertificate     = "~/.simpleauth/simpleauth.cert"
	DefaultDatabasePath    = "postgresql://postgres@127.0.0.1:5432/auth"
	DefaultDatabaseDialect = database.DialectPostgres
)
View Source
const (
	// Access Token TTLs
	AccessTokenExpiration      = 1 * time.Hour
	RefreshTokenExpiration     = 24 * time.Hour
	TransactionTokenExpiration = 5 * time.Minute
)

Variables

View Source
var (
	// Errors
	ErrorUserNotFound      = errors.New("User not found")
	ErrorUserExists        = errors.New("The username, email or phone number already exists")
	ErrorBadCredentials    = errors.New("The username or password is incorrect")
	ErrorUsernameRequired  = errors.New("Username/Email is required")
	ErrorPasswordRequired  = errors.New("Password is required")
	ErrorPublicKeyRequired = errors.New("Public key is required")
	ErrorTotpNotFound      = errors.New("TOTP not set for user")
	ErrorPublicKeyNotFound = errors.New("A public key is not set for this user")
)
View Source
var Ctrl = func() Controller {
	controllerOnce.Do(func() {
		var cfg Config
		if err := config.Load(&cfg); err != nil {
			panic(err)
		}
		if cfg.TotpIssuer == "" {
			cfg.TotpIssuer = DefaultTotpIssuer
		}
		ctx := context.Background()
		db, err := database.New(ctx, cfg.DatabaseDialect, cfg.DatabasePath)
		if err != nil {
			panic(fmt.Sprintf(
				"Controller: failed to connect to database at "+
					"address ('%s')",
				cfg.DatabasePath,
			))
		}
		privateKey, publicKey, cert, err := readKeysFromConfig(cfg)
		if err != nil {
			panic(fmt.Sprintf("Controller: %s", err))
		}
		if len(cfg.AuthGrants) > 0 {
			err := grants.SetCustomGrants(cfg.AuthGrants)
			if err != nil {
				panic(fmt.Sprintf("Controller: %s", err))
			}
		}
		middleware.SetAuthPublicKey(publicKey)
		control = New(
			ctx,
			db,
			privateKey,
			publicKey,
			cert,
			cfg.TotpIssuer,
		)
	})
	return control
}

Ctrl is an instance of an authentication service controller.

View Source
var Routes = []server.Route{
	server.Route{
		Handler:          Login,
		Method:           http.MethodPost,
		Path:             "/users/login",
		ResponseSettings: []server.ResponseSetting{},
	},
	server.Route{
		Handler:          SignUp,
		Method:           http.MethodPost,
		Path:             "/users/signup",
		ResponseSettings: []server.ResponseSetting{},
	},
	server.Route{
		Handler:          middleware.Authorize(RefreshToken),
		Method:           http.MethodGet,
		Path:             "/users/refresh",
		ResponseSettings: []server.ResponseSetting{},
	},
	server.Route{
		Handler:          middleware.Authorize(RegisterPublicKey),
		Method:           http.MethodPost,
		Path:             "/keys",
		ResponseSettings: []server.ResponseSetting{},
	},
	server.Route{
		Handler:          LoginWithPublicKey,
		Method:           http.MethodPost,
		Path:             "/keys/login",
		ResponseSettings: []server.ResponseSetting{},
	},
	server.Route{
		Handler:          middleware.Authorize(SetTotp),
		Method:           http.MethodPost,
		Path:             "/otp",
		ResponseSettings: []server.ResponseSetting{},
	},
	server.Route{
		Handler:          middleware.Authorize(ValidateOtp),
		Method:           http.MethodGet,
		Path:             "/otp/validate/:otp",
		ResponseSettings: []server.ResponseSetting{},
	},
	server.Route{
		Handler:          middleware.Authorize(GetOtpQr),
		Method:           http.MethodGet,
		Path:             "/otp/qr",
		ResponseSettings: []server.ResponseSetting{},
	},
	server.Route{
		Handler:          GetJwk,
		Method:           http.MethodGet,
		Path:             "/.well-known/jwks.json",
		ResponseSettings: []server.ResponseSetting{},
	},
}

Routes represent the authentication HTTP service routes.

Functions

func DecodeTotp

func DecodeTotp(enc, issuer string) (*twofactor.Totp, error)

DecodeTotp returns the timed-based OTP for the given based64 encoded message and the OTP issuer.

func EncodeTotp

func EncodeTotp(totp *twofactor.Totp) (string, error)

EncodeTotp returns a base64 encoded message for the given timed-based OTP.

func GenerateTokens

func GenerateTokens(user models.User, pubKey, privKey []byte, options *TokenOptions) (string, string, error)

GenerateTokens returns a new access token, and an accompanying refresh token for the given user, and encryption key pair. By default, the generated access token will be given a grant of grants.GrantAuthenticated and a TTL of AccessTokenExpiration. This can be changed in the given token options. Skipping the refresh token, will return an empty string in its place.

func GetJwk

GetJwk handles the response to a request for the service's JSON web key.

func GetOtpQr

func GetOtpQr(w http.ResponseWriter, r *http.Request, p server.Parameters)

GetOtpQr handles the response for a request to retrieve the QR image of a users OTP.

func HashPassword

func HashPassword(pass string) (string, error)

HashPassword returns the bcrypt hash of the given password using the default cost of 10.

func Login

Login handles the response for a user login request.

func LoginWithPublicKey

func LoginWithPublicKey(w http.ResponseWriter, r *http.Request, p server.Parameters)

LoginWithPublicKey handles a request to login via public key authentication.

func RefreshToken

func RefreshToken(w http.ResponseWriter, r *http.Request, p server.Parameters)

RefreshToken handles the response for a request to refresh access tokens.

func RegisterPublicKey

func RegisterPublicKey(w http.ResponseWriter, r *http.Request, p server.Parameters)

RegisterPublicKey handles a request to register the public key for a given user.

func SetTotp

func SetTotp(w http.ResponseWriter, r *http.Request, p server.Parameters)

SetTotp handles the response to a request to enable TOTP for a user.

func SignUp

SignUp handles the response to a user signup request.

func ValidateOtp

func ValidateOtp(w http.ResponseWriter, r *http.Request, p server.Parameters)

ValidateOtp handles the response to a request to validate a user's OTP.

func VerifyPassword

func VerifyPassword(hashedPass, pass string) error

VerifyPassword returns nil if the given bcrypt hash matches the password. Otherwise, an error is returned.

Types

type Config

type Config struct {
	DatabasePath    string `toml:"database_path"`
	DatabaseDialect string `toml:"database_dialect"`

	PrivateKey  string   `toml:"private_key"`
	Certificate string   `toml:"certificate"`
	TotpIssuer  string   `toml:"totp_issuer"`
	AuthGrants  []string `toml:"auth_grants"`
}

Config represents the configuration of an authentication service controller.

type Controller

type Controller interface {
	// GetJwks returns the JSON web key of the authentication service.
	GetJwks() (jwk.Jwks, error)

	// GetOtpQr returns an image of the QR code for the given user ID.
	GetOtpQr(id string) ([]byte, error)

	// Login returns a new AccessToken for the given login request.
	// Effectively, logging in the user for as long the token remains valid.
	Login(login models.Login) (models.AccessToken, error)

	// LoginWithPublicKey returns a new AccessToken for the given public key
	// authentication request.
	LoginWithPublicKey(pubKey models.SignedPublicKey) (models.AccessToken, error)

	// RegisterPublicKey registers the public authentication key for the given
	// user.
	RegisterPublicKey(signedKey models.SignedPublicKey) error

	// SetAuthCert sets the authentication service JSON web key for
	// validating access tokens.
	SetAuthCert(cert io.Reader) error

	// SetAuthPrivateKey sets the JWT private key for generating access
	// tokens.
	SetAuthPrivateKey(privKey io.Reader) error

	// SetDatabase sets the user database for the authentication service at
	// the given address.
	SetDatabase(dialect, path string) error

	// SetTotp sets the TOTP for the given user ID. Implementations, should
	// only enable/disable TOTP for the given user.
	SetTotp(id string, totp models.Totp) (models.Totp, error)

	// SetTotpIssuer sets the TOTP issuer for the authentication service.
	SetTotpIssuer(issuer string)

	// SignUp adds the given user to the authentication service and returns
	// a new Accesstoken.
	SignUp(user models.User) (models.AccessToken, error)

	// RefreshToken returns a new AccessToken for the given user ID.
	// Effectively, refreshing the authenticated access.
	RefreshToken(id string) (models.AccessToken, error)

	// ValidateOtp returns a new AccessToken if the given OTP was valid for
	// the user ID.
	ValidateOtp(id, otp string) (models.AccessToken, error)
}

Controller represents an interface to an authentication service.

func New

func New(
	ctx context.Context,
	db database.Database,
	privateKey []byte,
	publicKey []byte,
	cert jwk.Certificate,
	totpIssuer string,
) Controller

New returns a new Controller.

type TokenOptions

type TokenOptions struct {
	Grant       grants.Grant  // Access grant of the token
	TTL         time.Duration // Time-To-Live of the token
	RefreshTTL  time.Duration // Time-To-Live of the refresh token
	SkipRefresh bool          // Whether to skip generating a refresh token
}

TokenOptions represents a container for options for generating an access token.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL