Documentation ¶
Overview ¶
Package webauth provides support for web apps that use form authentication.
Index ¶
- Constants
- Variables
- func CookieValue(r *http.Request, name string) (string, error)
- func GenerateRandomString(n int) (string, error)
- func Hash(s string) string
- func IsEmpty(strs ...string) bool
- func LoginCookie(value string, expires time.Time, remember bool) *http.Cookie
- type AuthApp
- func (app *AuthApp) ConfirmHandlerGet(w http.ResponseWriter, r *http.Request)
- func (app *AuthApp) ConfirmHandlerPost(w http.ResponseWriter, r *http.Request)
- func (app *AuthApp) ConfirmRequestHandlerGet(w http.ResponseWriter, r *http.Request)
- func (app *AuthApp) ConfirmRequestHandlerPost(w http.ResponseWriter, r *http.Request)
- func (app *AuthApp) ConfirmRequestSentHandlerGet(w http.ResponseWriter, r *http.Request)
- func (app *AuthApp) ConfirmedHandlerGet(w http.ResponseWriter, r *http.Request)
- func (app *AuthApp) CreateLoginToken(username string) (Token, error)
- func (app *AuthApp) EventsCSVHandler(w http.ResponseWriter, r *http.Request)
- func (app *AuthApp) EventsHandler(w http.ResponseWriter, r *http.Request)
- func (app *AuthApp) ForgotHandler(w http.ResponseWriter, r *http.Request)
- func (app *AuthApp) LoginGetHandler(w http.ResponseWriter, r *http.Request)
- func (app *AuthApp) LoginPostHandler(w http.ResponseWriter, r *http.Request)
- func (app *AuthApp) LoginUser(username, password string) (Token, error)
- func (app *AuthApp) LogoutHandler(w http.ResponseWriter, r *http.Request)
- func (app *AuthApp) RegisterHandler(w http.ResponseWriter, r *http.Request)
- func (app *AuthApp) RenderPage(w http.ResponseWriter, logger *slog.Logger, templateName string, data PageData)
- func (app *AuthApp) ResetHandler(w http.ResponseWriter, r *http.Request)
- func (a *AuthApp) String() string
- func (app *AuthApp) UserGetHandler(w http.ResponseWriter, r *http.Request)
- func (app *AuthApp) UsersCSVHandler(w http.ResponseWriter, r *http.Request)
- func (app *AuthApp) UsersHandler(w http.ResponseWriter, r *http.Request)
- type AuthDB
- func (db *AuthDB) CheckPassword(username, password string) error
- func (db *AuthDB) ConfirmUser(username, ctoken string) error
- func (db *AuthDB) CreateConfirmEmailToken(username string) (Token, error)
- func (db *AuthDB) CreateToken(kind, username string, size int, duration string) (Token, error)
- func (db *AuthDB) EmailExists(email string) (bool, error)
- func (db *AuthDB) GetEvents() ([]Event, error)
- func (db *AuthDB) HashedPassword(username string) (string, error)
- func (db *AuthDB) LastLoginForUser(username string) (time.Time, string, error)
- func (db *AuthDB) RegisterUser(username, fullName, email, password string) error
- func (db *AuthDB) RemoveToken(kind, value string) error
- func (db *AuthDB) RowExists(qry string, args ...interface{}) (bool, error)
- func (db *AuthDB) UserExists(username string) (bool, error)
- func (db *AuthDB) UserForLoginToken(loginToken string) (User, error)
- func (db *AuthDB) UserForName(username string) (User, error)
- func (db *AuthDB) UserFromRequest(w http.ResponseWriter, r *http.Request) (User, error)
- func (db *AuthDB) UsernameForConfirmToken(tokenValue string) (string, error)
- func (db *AuthDB) UsernameForEmail(email string) (string, error)
- func (db *AuthDB) UsernameForResetToken(tokenValue string) (string, error)
- func (db *AuthDB) WriteEvent(name EventName, succeeded bool, username, message string) error
- type CommonData
- type Config
- type ConfigAuth
- type ConfigSQL
- type ConfirmData
- type ConfirmRequestPageData
- type ConfirmRequestSentData
- type ConfirmedData
- type Event
- type EventName
- type EventsPageData
- type ForgotPageData
- type LoginPageData
- type LogoutPageData
- type Option
- type PageData
- type RedactedConfig
- type RegisterPageData
- type ResetPageData
- type Token
- type User
- type UserPageData
- type UsersPageData
Constants ¶
const ( MsgMissingConfirmToken = "Please provide a token." MsgInvalidConfirmToken = "Token is invalid. Request a new token." MsgExpiredConfirmToken = "Token is expired. Request a new token." )
const ( ConfirmTokenSize = 12 // Size of the confirm token ConfirmTokenExpires = "5m" // Token expiry time )
Constants for error and informational messages displayed to the user.
const ( MsgMissingEmail = "Please provide your email." MsgMissingAction = "Please provide an action." MsgInvalidAction = "Please provide a valid action." TemplateForgot = "forgot.html" TemplateForgotSent = "forgot_sent.html" ResetTokenSize = 12 // Size of the password reset token; TODO: move to config ResetTokenExpires = "5m" // Token expiry time; TODO: move to config )
Constants for error and informational messages displayed to the user.
const ( MsgMissingUsernameAndPassword = "Missing username and password." MsgMissingUsername = "Missing username." MsgMissingPassword = "Missing password." MsgLoginFailed = "Login failed." )
const ( MsgMissingRequired = "Please provide required values" MsgUsernameExists = "Username already exists." MsgEmailExists = "Email already registered." MsgPasswordsDifferent = "Passwords do not match." MsgRegisterFailed = "Unable to register user." )
const ConfirmRequestSentTmpl = "confirm_request_sent.html"
const ConfirmTmpl = "confirm.html"
const ConfirmedTmpl = "confirmed.html"
const LoginPageName = "login.html"
LoginPageName is the name of the login HTML template.
const LoginTokenCookieName = "login"
const LoginTokenKind = "login"
const LoginTokenSize = 32
Variables ¶
var ( ErrConfigRead = errors.New("failed to read config file") ErrConfigParse = errors.New("failed to parse config file") )
var ( ErrInitDBOpen = errors.New("db open failed") ErrInitDBPing = errors.New("db ping failed") )
var ( ErrRowExistsDBNil = errors.New("RowExists: db is nil") ErrRowExistsQueryFailed = errors.New("RowExists: query failed") )
var ( ErrWriteEventDBNil = errors.New("WriteEvent: db is nil") ErrWriteEventFailed = errors.New("WriteEvent: db write failed") )
var ( ErrGetEventsDBNil = errors.New("GetEvents: db is nil") ErrGetEventsQuery = errors.New("GetEvents: query failed") ErrGetEventsScan = errors.New("GetEvents: scan failed") ErrGetEventsRows = errors.New("GetEvents: rows.Err()") )
var ( ErrInvalidDB = errors.New("invalid db") ErrUserLoginTokenNotFound = errors.New("user login token not found") ErrUserNotFound = errors.New("user not found") ErrUserLoginTokenExpired = errors.New("user login expired") ErrResetPasswordTokenExpired = errors.New("reset password token expired") ErrConfirmTokenExpired = errors.New("confirm token expired") ErrUserGetLastLoginFailed = errors.New("failed to get user last login") ErrMissingConfirmToken = errors.New("empty confirm token") )
Define command error values.
var ErrInvalidConfig = errors.New("invalid config")
var ErrInvalidLength = errors.New("invalid length")
var ErrInvalidPassword = errors.New("invalid password")
var ErrRequestNil = errors.New("request is nil")
var ErrTokenNotFound = errors.New("token not found")
Functions ¶
func CookieValue ¶
CookieValue returns the named cookie value provided in the request or an empty string if not found.
func GenerateRandomString ¶
GenerateRandomString returns a URL safe base64 encoded string of n random bytes.
func Hash ¶
Hash returns a hex encoded sha256 Hash of the given string. TODO: should this be a salted Hash to be more secure?
Types ¶
type AuthApp ¶
type AuthApp struct { *webapp.WebApp // Embedded WebApp DB *AuthDB // DB is the database connection. Cfg Config }
AuthApp extends the WebApp to support authentication.
func NewApp ¶
NewApp creates a new AuthApp with the given options and returns it. These options can be either AuthApp or WebApp Options.
func (*AuthApp) ConfirmHandlerGet ¶
func (app *AuthApp) ConfirmHandlerGet(w http.ResponseWriter, r *http.Request)
ConfirmHandlerGet processes GET requests for the email confirmation page.
This function retrieves the 'ctoken' (confirmation token) from the query parameters of the request URL. If a 'ctoken' is present, it is displayed to the user on the confirmation page. Users may also manually enter a 'ctoken'.
Submission of the token is via a POST request, which is handled by ConfirmHandlerPost, which completes the email confirmation process.
func (*AuthApp) ConfirmHandlerPost ¶
func (app *AuthApp) ConfirmHandlerPost(w http.ResponseWriter, r *http.Request)
ConfirmHandlerPost processes POST requests for user email confirmation.
It extracts the 'ctoken' (confirmation token) from the form data to verify and confirm the associated user. If the token is valid, the user's status is updated to confirmed.
func (*AuthApp) ConfirmRequestHandlerGet ¶
func (app *AuthApp) ConfirmRequestHandlerGet(w http.ResponseWriter, r *http.Request)
ConfirmRequestHandlerGet processes GET requests for the confirmation request page. It allows a user to enter their email to request a confirmation token. Submission of the request with an email is via a POST request, which is handled by ConfirmRequestHandlerPost.
func (*AuthApp) ConfirmRequestHandlerPost ¶
func (app *AuthApp) ConfirmRequestHandlerPost(w http.ResponseWriter, r *http.Request)
ConfirmRequestHandlerPost processes POST rquests that emails a user a confirmation token. It extracts the 'email" from the form data to create the token and then email to the user.
func (*AuthApp) ConfirmRequestSentHandlerGet ¶
func (app *AuthApp) ConfirmRequestSentHandlerGet(w http.ResponseWriter, r *http.Request)
ConfirmRequestSentHandlerGet handles GET requests for confirm request sent success page.
func (*AuthApp) ConfirmedHandlerGet ¶
func (app *AuthApp) ConfirmedHandlerGet(w http.ResponseWriter, r *http.Request)
ConfirmedHandlerGet handles GET requests for the email confirmation success page.
func (*AuthApp) CreateLoginToken ¶
CreateLoginToken creates a login token for username.
func (*AuthApp) EventsCSVHandler ¶
func (app *AuthApp) EventsCSVHandler(w http.ResponseWriter, r *http.Request)
EventsCSVHandler provides list of events as a CSV file.
func (*AuthApp) EventsHandler ¶
func (app *AuthApp) EventsHandler(w http.ResponseWriter, r *http.Request)
EventsHandler displays a list of events.
func (*AuthApp) ForgotHandler ¶
func (app *AuthApp) ForgotHandler(w http.ResponseWriter, r *http.Request)
ForgotHandler handles HTTP requests for forgot user or password.
func (*AuthApp) LoginGetHandler ¶
func (app *AuthApp) LoginGetHandler(w http.ResponseWriter, r *http.Request)
LoginGetHandler handles login GET requests.
func (*AuthApp) LoginPostHandler ¶
func (app *AuthApp) LoginPostHandler(w http.ResponseWriter, r *http.Request)
LoginPostHandler handles login POST requests.
func (*AuthApp) LoginUser ¶
LoginUser returns a login token if the username and password are correct.
func (*AuthApp) LogoutHandler ¶
func (app *AuthApp) LogoutHandler(w http.ResponseWriter, r *http.Request)
LogoutHandler handles /logout requests.
func (*AuthApp) RegisterHandler ¶
func (app *AuthApp) RegisterHandler(w http.ResponseWriter, r *http.Request)
RegisterHandler handles requests to register a user.
func (*AuthApp) RenderPage ¶
func (app *AuthApp) RenderPage(w http.ResponseWriter, logger *slog.Logger, templateName string, data PageData)
RenderPage renders a web page using the specified template and data.
If the page cannot be rendered, http.StatusInternalServerError is set and the caller should ensure no further writes are done to w.
func (*AuthApp) ResetHandler ¶
func (app *AuthApp) ResetHandler(w http.ResponseWriter, r *http.Request)
ResetHandler handles /reset requests.
func (*AuthApp) UserGetHandler ¶
func (app *AuthApp) UserGetHandler(w http.ResponseWriter, r *http.Request)
UserGetHandler shows user information.
func (*AuthApp) UsersCSVHandler ¶
func (app *AuthApp) UsersCSVHandler(w http.ResponseWriter, r *http.Request)
UsersCSVHandler provides list of the current users as a CSV file.
func (*AuthApp) UsersHandler ¶
func (app *AuthApp) UsersHandler(w http.ResponseWriter, r *http.Request)
UsersHandler shows a list of the current users.
type AuthDB ¶
func (*AuthDB) CheckPassword ¶
CheckPassword validates the password for a user.
func (*AuthDB) ConfirmUser ¶
ConfirmUser updates database to indicate user confirmed their email.
func (*AuthDB) CreateConfirmEmailToken ¶
CreateConfirmEmailToken generates a new token to confirm a user's email.
func (*AuthDB) CreateToken ¶
CreateToken creates and saves a token for user of size that expires in duration.
func (*AuthDB) EmailExists ¶
EmailExists returns true if the given email already exists.
func (*AuthDB) HashedPassword ¶
HashedPassword retrieves the hashed password for a given username.
func (*AuthDB) LastLoginForUser ¶
LastLoginForUser retrieves the last login time and result for a given username. It returns zero values in case of no previous login.
func (*AuthDB) RegisterUser ¶
RegisterUser registers a user with the given values. Returns nil on success or an error on failure.
func (*AuthDB) RemoveToken ¶
RemoveToken removes the token with kind and value.
func (*AuthDB) RowExists ¶
RowExists checks if the given SQL query returns at least one row. The query should be in the form "SELECT 1 FROM ... WHERE ... LIMIT 1".
func (*AuthDB) UserExists ¶
UserExists returns true if the given username already exists in db.
func (*AuthDB) UserForLoginToken ¶
UserForLoginToken returns a user for the given loginToken.
func (*AuthDB) UserForName ¶
UserForName returns a user for the given username.
func (*AuthDB) UserFromRequest ¶
UserFromRequest returns the user for the login token cookie in the request. If the login token is invalid or expired, the cookie is removed and an empty user returned.
func (*AuthDB) UsernameForConfirmToken ¶
UsernameForConfirmToken returns the username for a given confirm token.
If token is not found, ErrUserNotFound is returned.
If token is expired, ErrConfirmTokenExpired is returned and token is removed.
If a SQL error occurs, it will be returned, except ErrNoRows.
func (*AuthDB) UsernameForEmail ¶
UsernameForEmail looks up a username based on their email address.
If not found, ErrUserNotFound is returned.
If a SQL error occurs, other than ErrNoRows, it is returned.
func (*AuthDB) UsernameForResetToken ¶
UsernameForResetToken returns the username for a given reset token.
type CommonData ¶
type CommonData struct {
Title string
}
CommonData holds common fields for page data.
func (*CommonData) SetDefaultTitle ¶
func (c *CommonData) SetDefaultTitle(appName string)
SetDefaultTitle ensures that the Title of CommonPageData is not empty. If Title is empty, this method sets it to the value of appName.
type Config ¶
type Config struct { webapp.Config // Inherit webapp.Config Auth ConfigAuth // Auth app configuration. SQL ConfigSQL // SQL Database configuration. SMTP email.SMTPConfig // SMTP server configuration. EmailFrom string `required:"true"` // From address for emails. }
Config represents the overall application configuration.
func LoadConfigFromJSON ¶
LoadConfigFromJSON loads configuration settings from a JSON file.
func (*Config) MarshalJSON ¶
MarshalJSON customizes JSON marshalling to redact sensitive Config data.
func (*Config) MissingFields ¶
MissingFields identifies which required fields are absent in Config. It returns a slice of missing fields. If an error occurs during the check, an empty slice and the error are returned.
type ConfigAuth ¶
type ConfigAuth struct { BaseURL string `required:"true"` // Base URL of the application. LoginExpires string `required:"true"` // Duration string for expiry. }
ConfigAuth holds settings specific to the auth app.
type ConfigSQL ¶
type ConfigSQL struct { DriverName string `required:"true"` // Database driver name. DataSourceName string `required:"true"` // Database connection string. }
ConfigSQL hold SQL database connection settings.
type ConfirmData ¶
type ConfirmData struct { CommonData Message string ConfirmToken string }
ConfirmData contains data to render the confirm template.
type ConfirmRequestPageData ¶
type ConfirmRequestPageData struct { CommonData Message string // An message to display to the user. }
ConfirmRequestPageData contains data to render the confirm request template.
type ConfirmRequestSentData ¶
type ConfirmRequestSentData struct { CommonData EmailFrom string // The email address that sends the confirm message. }
ConfirmRequestSentData contains data to render the confirm template.
type ConfirmedData ¶
type ConfirmedData struct {
CommonData
}
ConfirmedData contains data to render the confirm template.
type Event ¶
type Event struct { Name EventName // Name of the event. Succeeded bool // Indicates if the event was successful. Username string // Username associated with the event. Message string // Message or details about the event. Created time.Time // Timestamp of event, set by db when inserted. }
Event represents a system event, such as a user login or registration.
type EventName ¶
type EventName string
EventName represents possible event types within the system.
const ( EventLogin EventName = "login" EventLogout EventName = "logout" EventRegister EventName = "register" EventSaveToken EventName = "save_token" EventResetPass EventName = "reset_pass" EventConfirmed EventName = "confirmed" EventMaxName EventName = "1234567890" // Event defined as varchar(10). )
type EventsPageData ¶
type EventsPageData struct { CommonData User User Events []Event }
EventsPageData contains data passed to the HTML template.
type ForgotPageData ¶
type ForgotPageData struct { CommonData Message string // An informational or error message to display to the user. EmailFrom string // The email address from which the reset or reminder email will be sent. }
ForgotPageData contains data required to render the forgot templates.
type LoginPageData ¶
type LoginPageData struct { CommonData Message string }
LoginPageData contains data passed to the login HTML template.
type LogoutPageData ¶
type LogoutPageData struct { CommonData Message string }
LogoutPageData contains data passed to the HTML template.
type Option ¶
type Option func(*AuthApp)
Option is a function type used to apply configuration options to a AuthApp. This follows the Option pattern from https://commandcenter.blogspot.com/2014/01/self-referential-functions-and-design.html and elsewhere.
func WithConfig ¶
WithConfig returns an Option to set the Config for a AuthApp.
type PageData ¶
type PageData interface {
SetDefaultTitle(appName string)
}
PageData is an interface that all page data structs must implement.
type RedactedConfig ¶
type RedactedConfig Config
RedactedConfig provides a redacted copy of Config for secure logging.
type RegisterPageData ¶
type RegisterPageData struct { CommonData Message string }
RegisterPageData contains data passed to the HTML template.
type ResetPageData ¶
ResetPageData contains data passed to the HTML template.
type User ¶
type User struct { Username string FullName string Email string IsAdmin bool Confirmed bool Created time.Time LastLoginTime time.Time LastLoginResult string // TODO: implement as bool? }
User represents in the application.
var EmptyUser User // EmptyUser is a empty User used when returning a error.
type UserPageData ¶
UserPageData contains data passed to the HTML template.
Source Files ¶
- config.go
- confirm_handler.go
- confirm_request_handler.go
- confirm_request_sent_handler.go
- confirmed_handler.go
- db.go
- event.go
- events_handler.go
- forgot_handler.go
- login.go
- login_handler.go
- logout_handler.go
- page.go
- register_handler.go
- reset_handler.go
- token.go
- user.go
- user_handler.go
- users_handler.go
- utils.go
- webauth.go