user

package
v0.0.0-...-3975a26 Latest Latest
Warning

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

Go to latest
Published: Mar 2, 2021 License: MIT Imports: 17 Imported by: 0

Documentation

Overview

Package user provides user data handling functionality.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrTooManyTokens is returned when too many requests for new tokens
	// have been received.
	ErrTooManyTokens = httpflow.NewError(nil, http.StatusTooManyRequests, "too many requests")

	// ErrInvalidToken is returned when the provided token is incorrect or
	// already expired.
	ErrInvalidToken = httpflow.NewError(nil, http.StatusBadRequest, "invalid token")
)
View Source
var (
	// ErrInvalidEmail is returned when email is determined to be invalid.
	ErrInvalidEmail = httpflow.NewError(nil, http.StatusBadRequest, "invalid email")

	// ErrInvalidPassword is returned when password is determined to be
	// invalid.
	ErrInvalidPassword = httpflow.NewError(nil, http.StatusBadRequest, "invalid password")

	// ErrInvalidCredentials is returned when login credentials are
	// determined to be incorrect.
	ErrInvalidCredentials = httpflow.NewError(nil, http.StatusUnauthorized, "incorrect credentials")
)
View Source
var (
	// VerifLifetime is the default / recommended verification token
	// lifetime value.
	VerifLifetime = TokenLifetime{
		Interval: time.Hour * 24 * 7,
		Cooldown: time.Minute,
	}

	// RecovLifetime is the default / recommended recovery token lifetime
	// value.
	RecovLifetime = TokenLifetime{
		Interval: time.Hour * 3,
		Cooldown: time.Minute,
	}
)
View Source
var (
	// ErrNotActivated is returned when an action which is allowed only
	// by activated users is performed.
	ErrNotActivated = httpflow.NewError(nil, http.StatusForbidden, "not activated")
)
View Source
var (
	// SessionDuration is the default / recommended session duration
	// value.
	SessionDuration = time.Hour * 24 * 30 //nolint:gochecknoglobals // used as a constant
)

Functions

func CheckEmail

func CheckEmail(e string) error

CheckEmail determines whether the provided email address is of correct format or not.

func CheckFilterKey

func CheckFilterKey(k, _ string) error

CheckFilterKey determines whether the filter key is valid or not.

func CheckPassword

func CheckPassword(p string) error

CheckPassword determines whether the provided password is of correct format or not.

func CheckSortKey

func CheckSortKey(k string) error

CheckSortKey determines whether the sort key is valid or not.

func DefaultDeleteCheck

func DefaultDeleteCheck(_ context.Context, _ User) error

DefaultDeleteCheck does nothing, just fills the space and contemplates life.

func FromFullToken

func FromFullToken(t string) (string, xid.ID, error)

FromFullToken extracts token value and user's ID from the combined token form.

func SetCreator

func SetCreator(c Creator) setter

SetCreator sets a function that will be used to construct a new user.

func SetDeleteCheck

func SetDeleteCheck(c DeleteCheck) setter

SetDeleteCheck sets a function that will be called before user deletion.

func SetLoginCheck

func SetLoginCheck(c LoginCheck) setter

SetLoginCheck sets a function that will be called before user auth.

func SetParser

func SetParser(p Parser) setter

SetParser sets a function that will be used to parse user's request input.

func SetRecoveryLifetime

func SetRecoveryLifetime(t TokenLifetime) setter

SetRecoveryLifetime sets token time values for recovery process.

func SetSessionDuration

func SetSessionDuration(sd time.Duration) setter

SetSessionDuration sets the duration of persistent sessions.

func SetVerificationLifetime

func SetVerificationLifetime(t TokenLifetime) setter

SetVerificationLifetime sets token time values for verification process.

func SetupLinks(r string) map[httpflow.LinkKey]string

SetupLinks creates a link string map that should be used for email sending, etc. The parameter specifies the root of the link, example: "http://yoursite.com/user"

Types

type Core

type Core struct {
	// ID is the primary and unique user identification key.
	ID xid.ID `json:"id" db:"id"`

	// CreatedAt specifies the exact time when the user was created.
	CreatedAt time.Time `json:"created_at" db:"created_at"`

	// UpdatedAt specifies the exact time when the user was last updated.
	UpdatedAt time.Time `json:"updated_at" db:"updated_at"`

	// ActivatedAt specifies the exact time when user's account
	// was activated.
	ActivatedAt zero.Time `json:"activated_at" db:"activated_at"`

	// Email is user's active email address.
	Email string `json:"email" db:"email"`

	// UnverifiedEmail is a new email address yet to be verified by its
	// owner. When verified this field is empty.
	UnverifiedEmail zero.String `json:"unverified_email" db:"unverified_email"`

	// PasswordHash is already hashed version of user's password.
	PasswordHash []byte `json:"-" db:"password_hash"`

	// Verification holds data needed for account activation or email
	// update.
	Verification Token `json:"-" db:"verification"`

	// Recovery holds data needed for account recovery.
	Recovery Token `json:"-" db:"recovery"`
}

Core holds core fields needed for user data types.

func NewCore

func NewCore(inp Inputer) (*Core, error)

NewCore initializes all the values, user specified and default, needed for user's core to be usable and returns it.

func (*Core) ApplyInput

func (c *Core) ApplyInput(inp Inputer) (Summary, error)

ApplyInput applies modification to user's core fields and sets new update time.

func (*Core) CancelRecovery

func (c *Core) CancelRecovery(t string) error

CancelRecovery checks whether the provided Token is valid and clears all active recovery Token data. NOTE: provided Token must in its original / raw form - not combined with user's ID (as InitRecovery method returns).

func (*Core) CancelVerification

func (c *Core) CancelVerification(t string) error

CancelVerification checks whether the provided Token is valid and clears the active verification Token data. NOTE: provided Token must be in its original / raw form - not combined with user's ID (as InitVerification method returns).

func (*Core) ExposeCore

func (c *Core) ExposeCore() *Core

ExposeCore returns user's core fields.

func (*Core) InitRecovery

func (c *Core) InitRecovery(tl TokenLifetime) (string, error)

InitRecovery initializes account recovery and returns a combination of Token and user ID in a string format to send in recovery emails etc. First parameter determines how long the recovery Token should be active. Second parameter determines how much time has to pass until another Token can be generated.

func (*Core) InitVerification

func (c *Core) InitVerification(tl TokenLifetime) (string, error)

InitVerification initializes account / email verification and returns combination of token and user ID in a string format to send in verification emails etc. First parameter determines how long the verification Token should be active. Second parameter determines how much time has to pass until another Token can be generated.

func (*Core) IsActivated

func (c *Core) IsActivated() bool

IsActivated checks whether user's account is activated or not.

func (*Core) IsPasswordCorrect

func (c *Core) IsPasswordCorrect(p string) bool

IsPasswordCorrect checks whether the provided password matches the hash or not.

func (*Core) Recover

func (c *Core) Recover(t, p string) error

Recover checks whether the provided Token is valid and sets the provided password as the new account password. NOTE: provided Token must be in its original / raw form - not combined with user's ID (as InitRecovery method returns).

func (*Core) SetEmail

func (c *Core) SetEmail(e string) (bool, error)

SetEmail checks and updates user's email address. First return value determines whether the email was set or not.

func (*Core) SetPassword

func (c *Core) SetPassword(p string) (bool, error)

SetPassword checks and updates user's password. First return value determines whether the password was set or not.

func (*Core) SetUnverifiedEmail

func (c *Core) SetUnverifiedEmail(e string) (bool, error)

SetUnverifiedEmail checks and updates user's unverified email address. First return value determines whether the email was set or not.

func (*Core) UpdatePassword

func (c *Core) UpdatePassword(oldPass, newPass string) (bool, error)

UpdatePassword checks and update's users password. NOTE: it will also check the old/current password before setting a new one. First return value determines whether the password was set or not.

func (*Core) Verify

func (c *Core) Verify(t string) error

Verify checks whether the provided token is valid and activates the account (if it wasn't already) and/or, if unverified email address exists, confirms it as the main email address. NOTE: provided Token must in its original / raw form - not combined with user's ID (as InitVerification method returns).

type CoreInput

type CoreInput struct {
	// Email is user's email address submitted for further processing.
	Email string `json:"email"`

	// Password is user's plain-text password submitted for
	// further processing.
	Password string `json:"password"`

	// OldPassword is user's plain-text password submitted for
	// confirmation before password's update.
	OldPassword string `json:"old_password"`

	// RememberMe specifies whether a persistent session should be
	// created on registration / log in or not.
	RememberMe bool `json:"remember_me"`
}

CoreInput holds core fields needed for every user's ApplyInput call.

func (CoreInput) ExposeCore

func (c CoreInput) ExposeCore() CoreInput

ExposeCore returns user's core input fields.

type CoreStats

type CoreStats struct {
	// Total specifies the total number of users in the data store.
	Total int `json:"total" db:"total"`
}

CoreStats holds core user statistics.

func (CoreStats) ExposeCore

func (c CoreStats) ExposeCore() CoreStats

ExposeCore returns users' core statistics.

type CoreSummary

type CoreSummary struct {
	// Email specifies whether the email was modified during
	// input application or not.
	Email bool

	// Password specifies whether the password was modified
	// during input application or not.
	Password bool
}

CoreSummary holds core fields' information which determines whether they were modified or not.

func (CoreSummary) ExposeCore

func (c CoreSummary) ExposeCore() CoreSummary

ExposeCore returns user's core input fields' modification status.

type Creator

type Creator func(ctx context.Context, inp Inputer) (User, error)

Creator is a function that should be used for custom user creation. Used only during registration.

type DB

type DB interface {
	// UserStats should return users' data statistics from the
	// underlying data store.
	UserStats(ctx context.Context) (Stats, error)

	// CreateUser should insert a freshly created user into the
	// underlying data store.
	CreateUser(ctx context.Context, usr User) error

	// FetchManyUsers should retrieve multiple users from the
	// underlying data store by the provided query.
	// Int return value specifies the total page count.
	FetchManyUsers(ctx context.Context, qr httpflow.Query) ([]User, int, error)

	// FetchUserByID should retrieve a user from the underlying
	// data store by their ID.
	FetchUserByID(ctx context.Context, id xid.ID) (User, error)

	// FetchUserByEmail should retrieve a user from the
	// underlying data store by their email address.
	FetchUserByEmail(ctx context.Context, eml string) (User, error)

	// UpdateUser should update user's data in the underlying
	// data store.
	UpdateUser(ctx context.Context, usr User) error

	// DeleteUserByID should delete a user from the underlying
	// data store by their ID.
	DeleteUserByID(ctx context.Context, id xid.ID) error
}

DB is an interface which should be implemented by the user data store layer.

type DeleteCheck

type DeleteCheck func(ctx context.Context, usr User) error

DeleteCheck is function that should be used for custom account checks before user deletion (e.g. check whether at least one admin user exists or not).

type EmailSender

type EmailSender interface {
	// SendAccountActivation should send an email regarding account
	// activation with the token, embedded into a full URL, to the
	// specified email address.
	SendAccountActivation(ctx context.Context, eml, tok string)

	// SendEmailVerification should send an email regarding new email
	// verification with the token, embedded into a full URL, to the
	// specified email address.
	SendEmailVerification(ctx context.Context, eml, tok string)

	// SendEmailChanged should send an email to the old email
	// address (first parameter) about a new email address
	// being set (second parameter).
	SendEmailChanged(ctx context.Context, oEml, nEml string)

	// SendAccountRecovery should send an email regarding account
	// recovery with the token, embedded into a full URL, to the
	// specified email address.
	SendAccountRecovery(ctx context.Context, eml, tok string)

	// SendAccountDeleted should send an email regarding
	// successful account deletion to the specified email address.
	SendAccountDeleted(ctx context.Context, eml string)

	// SendPasswordChanged should send an email notifying about
	// a successful password change to the specified email address.
	// Last parameter specifies whether the password was changed during
	// the recovery process or not.
	SendPasswordChanged(ctx context.Context, eml string, recov bool)
}

EmailSender is an interface which should be implemented by email sending service.

type Handler

type Handler struct {
	// contains filtered or unexported fields
}

Handler holds dependencies required for user management.

func NewHandler

func NewHandler(log zerolog.Logger, db DB, es EmailSender, sm *sessionup.Manager, ss ...setter) *Handler

NewHandler creates a new handler instance with the options provided.

func (*Handler) BasicRouter

func (h *Handler) BasicRouter(open bool) chi.Router

BasicRouter returns a chi router instance with basic user routes. Bool parameter determines whether registration is allowed or not (useful for applications where users are invited rather than allowed to register themselves).

func (*Handler) CancelRecovery

func (h *Handler) CancelRecovery(w http.ResponseWriter, r *http.Request)

CancelRecovery checks whether the token in the URL is valid and stops active verification token from further processing.

func (*Handler) CancelVerification

func (h *Handler) CancelVerification(w http.ResponseWriter, r *http.Request)

CancelVerification checks whether the token in the URL is valid and stops active verification token from further processing.

func (*Handler) Defaults

func (h *Handler) Defaults()

Defaults sets all optional handler's values to sane defaults.

func (*Handler) Delete

func (h *Handler) Delete(w http.ResponseWriter, r *http.Request)

Delete handles user's data removal from the data store. On successful deletion, an email will be sent.

func (*Handler) Fetch

func (h *Handler) Fetch(w http.ResponseWriter, r *http.Request)

Fetch handles user's data retrieval.

func (*Handler) FetchByToken

func (h *Handler) FetchByToken(r *http.Request) (User, string, error)

FetchByToken extracts the token from request's URL, retrieves a user by ID embedded in the token and returns user's account instance, raw token and optionally an error.

func (*Handler) FetchSessions

func (h *Handler) FetchSessions(w http.ResponseWriter, r *http.Request)

FetchSessions retrieves all sessions of the same user.

func (*Handler) InitRecovery

func (h *Handler) InitRecovery(w http.ResponseWriter, r *http.Request)

InitRecovery initializes recovery token for the user associated with the provided email address and sends to the same address. On successful execution, a recovery email will be sent to the email provided.

func (*Handler) LogIn

func (h *Handler) LogIn(w http.ResponseWriter, r *http.Request)

LogIn handles user's credentials checking and new session creation. On successful execution, a session will be created.

func (*Handler) LogOut

func (h *Handler) LogOut(w http.ResponseWriter, r *http.Request)

LogOut handles user's active session revokation.

func (*Handler) PingRecovery

func (h *Handler) PingRecovery(w http.ResponseWriter, r *http.Request)

PingRecovery only checks whether the token in the URL is valid or not; no writable modifications are being done.

func (*Handler) Recover

func (h *Handler) Recover(w http.ResponseWriter, r *http.Request)

Recover checks the token in the URL and applies the provided password to the user account data structure. On successful execution, an email will be sent notifying about password change.

func (*Handler) Register

func (h *Handler) Register(w http.ResponseWriter, r *http.Request)

Register handles new user's creation and insertion into the data store. On successful execution, a session will be created and account activation email will sent.

func (*Handler) ResendVerification

func (h *Handler) ResendVerification(w http.ResponseWriter, r *http.Request)

ResendVerification attempts to send and generate the verification token once more. On successful execution, either account activation or new email verification will be sent.

func (*Handler) RevokeOtherSessions

func (h *Handler) RevokeOtherSessions(w http.ResponseWriter, r *http.Request)

RevokeOtherSessions revokes all sessions of the same user besides the current one.

func (*Handler) RevokeSession

func (h *Handler) RevokeSession(w http.ResponseWriter, r *http.Request)

RevokeSession revokes one specific session of the user with the active session in the request's context.

func (*Handler) Router

func (h *Handler) Router(open bool) chi.Router

Router returns a chi router instance with all core user routes. Bool parameter determines whether registration is allowed or not (useful for applications where users are invited rather than allowed to register themselves).

func (*Handler) ServeHTTP

func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP handles all core user routes. Registration is allowed (use Router method to override this).

func (*Handler) Update

func (h *Handler) Update(w http.ResponseWriter, r *http.Request)

Update handles user's data update in the data store. On email address change, a verification email will be sent to the new address. On password change, all other sessions will be destroyed and email sent.

func (*Handler) Verify

func (h *Handler) Verify(w http.ResponseWriter, r *http.Request)

Verify checks whether the token in the URL is valid and activates either user's account or their new email address. If new email was changed and verified, an email will be sent to the old address about the change.

type Inputer

type Inputer interface {
	// ExposeCore should return user's core input fields.
	ExposeCore() CoreInput
}

Inputer is an interface which should be implemented by every user input data type.

func DefaultParser

func DefaultParser(r *http.Request) (Inputer, error)

DefaultParser marshals incoming request's body into a core input data structure.

type LoginCheck

type LoginCheck func(ctx context.Context, usr User) error

LoginCheck is a function that should be used for custom user data checks before authentication. Used before non-registration type authentication (e.g. login).

func DefaultLoginCheck

func DefaultLoginCheck(open bool) LoginCheck

DefaultLoginCheck checks whether the user has to be activated before authentication or not.

type Parser

type Parser func(r *http.Request) (Inputer, error)

Parser is a function that should be used for custom input parsing. Used only during user update process and registration.

type Stats

type Stats interface {
	// ExposeCore should return users' core statistics.
	ExposeCore() CoreStats
}

Stats is an interface which should be implemented by every user statistics data type.

type Summary

type Summary interface {
	// ExposeCore should return user's core fields' modification status.
	ExposeCore() CoreSummary
}

Summary is an interface which should be implemented by every user data type describing modifications during updates.

type Token

type Token struct {
	// ExpiresAt specifies the exact time when the token becomes invalid.
	ExpiresAt null.Time `json:"-" db:"expires_at"`

	// NextAt specifies the exact time when the next token will be allowed
	// to be generated.
	NextAt null.Time `json:"-" db:"next_at"`

	// Hash is the hashed token value version. Treat it as a temporary
	// password.
	Hash []byte `json:"-" db:"hash"`
}

Token is a temporary password-type data structure used for account verification and recovery.

func (*Token) Check

func (t *Token) Check(v string) error

Check determines whether the provided token is correct and non-expired or not.

func (*Token) Clear

func (t *Token) Clear()

Clear resets all token data.

func (*Token) IsEmpty

func (t *Token) IsEmpty() bool

IsEmpty checks whether the token is active or not.

type TokenLifetime

type TokenLifetime struct {
	// Interval is used for token expiration time calculation.
	Interval time.Duration

	// Cooldown is used for token next allowed generation time calculation.
	Cooldown time.Duration
}

TokenLifetime holds data related to token expiration and next generation times.

type User

type User interface {
	// ApplyInput should set values from provided data structure.
	// If certain input fields are empty, their destination fields
	// in the underlying user's structure should not be modified.
	ApplyInput(i Inputer) (Summary, error)

	// ExposeCore should return user's core fields.
	ExposeCore() *Core
}

User is an interface every user data type should implement.

func DefaultCreator

func DefaultCreator(_ context.Context, inp Inputer) (User, error)

DefaultCreator creates a new user with only core data fields from the provided input.

Directories

Path Synopsis
Package postgres provides functionality for interaction with postgres database.
Package postgres provides functionality for interaction with postgres database.

Jump to

Keyboard shortcuts

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