1
0
mirror of https://github.com/volatiletech/authboss.git synced 2025-09-16 09:06:20 +02:00

Rewrite docs to 80 cols

- Fix #183
This commit is contained in:
Aaron L
2018-09-15 15:39:26 -07:00
parent 2eeaf342f9
commit 8213e87e83
23 changed files with 199 additions and 150 deletions

View File

@@ -339,7 +339,8 @@ func TestAuthPostUserNotFound(t *testing.T) {
resp := httptest.NewRecorder()
w := harness.ab.NewResponse(resp)
// This event is really the only thing that separates "user not found" from "bad password"
// This event is really the only thing that separates "user not found"
// from "bad password"
var afterCalled bool
harness.ab.Events.After(authboss.EventAuthFail, func(w http.ResponseWriter, r *http.Request, handled bool) (bool, error) {
afterCalled = true

View File

@@ -53,12 +53,14 @@ func (a *Authboss) Init(modulesToLoad ...string) error {
}
// UpdatePassword updates the password field of a user using the same semantics
// that register/auth do to create and verify passwords. It saves this using the storer.
// that register/auth do to create and verify passwords. It saves this using
// the storer.
//
// In addition to that, it also invalidates any remember me tokens, if the storer supports
// that kind of operation.
// In addition to that, it also invalidates any remember me tokens, if the
// storer supports that kind of operation.
//
// If it's also desirable to log the user out, use: authboss.DelKnown(Session|Cookie)
// If it's also desirable to log the user out, use:
// authboss.DelKnown(Session|Cookie)
func (a *Authboss) UpdatePassword(ctx context.Context, user AuthableUser, newPassword string) error {
pass, err := bcrypt.GenerateFromPassword([]byte(newPassword), a.Config.Modules.BCryptCost)
if err != nil {

View File

@@ -13,13 +13,15 @@ const (
// the remember module. This serves as a way to force full authentication
// by denying half-authed users acccess to sensitive areas.
SessionHalfAuthKey = "halfauth"
// SessionLastAction is the session key to retrieve the last action of a user.
// SessionLastAction is the session key to retrieve the
// last action of a user.
SessionLastAction = "last_action"
// Session2FA is set when a user has been authenticated with a second factor
Session2FA = "twofactor"
// SessionOAuth2State is the xsrf protection key for oauth.
SessionOAuth2State = "oauth2_state"
// SessionOAuth2Params is the additional settings for oauth like redirection/remember.
// SessionOAuth2Params is the additional settings for oauth
// like redirection/remember.
SessionOAuth2Params = "oauth2_params"
// CookieRemember is used for cookies and form input names.
@@ -94,8 +96,9 @@ type ClientStateResponseWriter struct {
sessionStateEvents []ClientStateEvent
}
// LoadClientStateMiddleware wraps all requests with the ClientStateResponseWriter
// as well as loading the current client state into the context for use.
// LoadClientStateMiddleware wraps all requests with the
// ClientStateResponseWriter as well as loading the current client
// state into the context for use.
func (a *Authboss) LoadClientStateMiddleware(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
writer := a.NewResponse(w)
@@ -121,8 +124,8 @@ func (a *Authboss) NewResponse(w http.ResponseWriter) *ClientStateResponseWriter
}
}
// LoadClientState loads the state from sessions and cookies into the ResponseWriter
// for later use.
// LoadClientState loads the state from sessions and cookies
// into the ResponseWriter for later use.
func (a *Authboss) LoadClientState(w http.ResponseWriter, r *http.Request) (*http.Request, error) {
if a.Storage.SessionState != nil {
state, err := a.Storage.SessionState.ReadState(r)

View File

@@ -14,16 +14,18 @@ type Config struct {
Mount string
// NotAuthorized is the default URL to kick users back to when
// they attempt an action that requires them to be logged in and they're not auth'd
// they attempt an action that requires them to be logged in and
// they're not auth'd
NotAuthorized string
// AuthLoginOK is the redirect path after a successful authentication.
AuthLoginOK string
// ConfirmOK once a user has confirmed their account, where should they go
// ConfirmOK once a user has confirmed their account
// this says where they should go
ConfirmOK string
// ConfirmNotOK is used by the middleware, when a user is still supposed to
// confirm their account, this is where they should be redirected to.
// ConfirmNotOK is used by the middleware, when a user is still supposed
// to confirm their account, this is where they should be redirected to.
ConfirmNotOK string
// LockNotOK is a path to go to when the user fails
@@ -34,7 +36,8 @@ type Config struct {
// OAuth2LoginOK is the redirect path after a successful oauth2 login
OAuth2LoginOK string
// OAuth2LoginNotOK is the redirect path after an unsuccessful oauth2 login
// OAuth2LoginNotOK is the redirect path after
// an unsuccessful oauth2 login
OAuth2LoginNotOK string
// RecoverOK is the redirect path after a successful recovery of a password.
@@ -43,7 +46,9 @@ type Config struct {
// RegisterOK is the redirect path after a successful registration.
RegisterOK string
// RootURL is the scheme+host+port of the web application (eg https://www.happiness.com:8080) for url generation. No trailing slash.
// RootURL is the scheme+host+port of the web application
// (eg https://www.happiness.com:8080) for url generation.
// No trailing slash.
RootURL string
}
@@ -51,14 +56,14 @@ type Config struct {
// BCryptCost is the cost of the bcrypt password hashing function.
BCryptCost int
// ConfirmMethod controls which http method confirm expects. This is because
// typically this is a GET request since it's a link from an e-mail, but in
// api-like cases it needs to be able to be a post since there's data that
// must be sent to it.
// ConfirmMethod controls which http method confirm expects.
// This is because typically this is a GET request since it's a link
// from an e-mail, but in api-like cases it needs to be able to be a
// post since there's data that must be sent to it.
ConfirmMethod string
// ExpireAfter controls the time an account is idle before being logged out
// by the ExpireMiddleware.
// ExpireAfter controls the time an account is idle before being
// logged out by the ExpireMiddleware.
ExpireAfter time.Duration
// LockAfter this many tries.
@@ -68,41 +73,48 @@ type Config struct {
// LockDuration is how long an account is locked for.
LockDuration time.Duration
// LogoutMethod is the method the logout route should use (default should be DELETE)
// LogoutMethod is the method the logout route should use
// (default should be DELETE)
LogoutMethod string
// RegisterPreserveFields are fields used with registration that are to be rendered when
// post fails in a normal way (for example validation errors), they will be passed
// back in the data of the response under the key DataPreserve which will be a map[string]string.
// RegisterPreserveFields are fields used with registration that are
// to be rendered when post fails in a normal way
// (for example validation errors), they will be passed back in the
// data of the response under the key DataPreserve which
// will be a map[string]string.
//
// All fields that are to be preserved must be able to be returned by the ArbitraryValuer.GetValues()
// All fields that are to be preserved must be able to be returned by
// the ArbitraryValuer.GetValues()
//
// This means in order to have a field named "address" you would need to have that returned by
// the ArbitraryValuer.GetValues() method and then it would be available to be whitelisted by this
// This means in order to have a field named "address" you would need
// to have that returned by the ArbitraryValuer.GetValues() method and
// then it would be available to be whitelisted by this
// configuration variable.
RegisterPreserveFields []string
// RecoverTokenDuration controls how long a token sent via email for password
// recovery is valid for.
// RecoverTokenDuration controls how long a token sent via
// email for password recovery is valid for.
RecoverTokenDuration time.Duration
// RecoverLoginAfterRecovery says for the recovery module after a user has successfully
// recovered the password, are they simply logged in, or are they redirected to
// the login page with an "updated password" message.
// RecoverLoginAfterRecovery says for the recovery module after a
// user has successfully recovered the password, are they simply
// logged in, or are they redirected to the login page with an
// "updated password" message.
RecoverLoginAfterRecovery bool
// OAuth2Providers lists all providers that can be used. See
// OAuthProvider documentation for more details.
OAuth2Providers map[string]OAuth2Provider
// TOTP2FAIssuer is the issuer that appears in the url when scanning a qr code
// for google authenticator.
// TOTP2FAIssuer is the issuer that appears in the url when scanning
// a qr code for google authenticator.
TOTP2FAIssuer string
// RoutesRedirectOnUnauthed controls whether or not a user is redirected or given
// a 404 when they are unauthenticated and attempting to access a route that's
// login-protected inside Authboss itself. The otp/twofactor modules all use
// authboss.Middleware to protect their routes and this is the
// redirectToLogin parameter in that middleware that they pass through.
// RoutesRedirectOnUnauthed controls whether or not a user is redirected
// or given a 404 when they are unauthenticated and attempting to access
// a route that's login-protected inside Authboss itself.
// The otp/twofactor modules all use authboss.Middleware to protect
// their routes and this is the redirectToLogin parameter in that
// middleware that they pass through.
RoutesRedirectOnUnauthed bool
}
@@ -110,8 +122,8 @@ type Config struct {
// RootURL is a full path to an application that is hosting a front-end
// Typically using a combination of Paths.RootURL and Paths.Mount
// MailRoot will be assembled if not set.
// Typically looks something like: https://our-front-end.com/authenication
// No trailing slash
// Typically looks like: https://our-front-end.com/authenication
// No trailing slash.
RootURL string
// From is the email address authboss e-mails come from.
@@ -124,12 +136,13 @@ type Config struct {
}
Storage struct {
// Storer is the interface through which Authboss accesses the web apps database
// for user operations.
// Storer is the interface through which Authboss accesses the web apps
// database for user operations.
Server ServerStorer
// CookieState must be defined to provide an interface capapable of
// storing cookies for the given response, and reading them from the request.
// storing cookies for the given response, and reading them from the
// request.
CookieState ClientStateReadWriter
// SessionState must be defined to provide an interface capable of
// storing session-only values for the given response, and reading them
@@ -150,12 +163,12 @@ type Config struct {
// http request.
Responder HTTPResponder
// Redirector can redirect a response, similar to Responder but responsible
// only for redirection.
// Redirector can redirect a response, similar to Responder but
// responsible only for redirection.
Redirector HTTPRedirector
// BodyReader reads validatable data from the body of a request to be able
// to get data from the user's client.
// BodyReader reads validatable data from the body of a request to
// be able to get data from the user's client.
BodyReader BodyReader
// ViewRenderer loads the templates for the application.

View File

@@ -96,8 +96,8 @@ func (c *Confirm) PreventAuth(w http.ResponseWriter, r *http.Request, handled bo
return true, c.Authboss.Config.Core.Redirector.Redirect(w, r, ro)
}
// StartConfirmationWeb hijacks a request and forces a user to be confirmed first
// it's assumed that the current user is loaded into the request context.
// StartConfirmationWeb hijacks a request and forces a user to be confirmed
// first it's assumed that the current user is loaded into the request context.
func (c *Confirm) StartConfirmationWeb(w http.ResponseWriter, r *http.Request, handled bool) (bool, error) {
user, err := c.Authboss.CurrentUser(r)
if err != nil {
@@ -117,8 +117,8 @@ func (c *Confirm) StartConfirmationWeb(w http.ResponseWriter, r *http.Request, h
return true, c.Authboss.Config.Core.Redirector.Redirect(w, r, ro)
}
// StartConfirmation begins confirmation on a user by setting them to require confirmation
// via a created token, and optionally sending them an e-mail.
// StartConfirmation begins confirmation on a user by setting them to require
// confirmation via a created token, and optionally sending them an e-mail.
func (c *Confirm) StartConfirmation(ctx context.Context, user authboss.ConfirmableUser, sendEmail bool) error {
logger := c.Authboss.Logger(ctx)
@@ -260,12 +260,13 @@ func (c *Confirm) invalidToken(w http.ResponseWriter, r *http.Request) error {
return c.Authboss.Config.Core.Redirector.Redirect(w, r, ro)
}
// Middleware ensures that a user is confirmed, or else it will intercept the request
// and send them to the confirm page, this will load the user if he's not been loaded
// yet from the session.
// Middleware ensures that a user is confirmed, or else it will intercept the
// request and send them to the confirm page, this will load the user if he's
// not been loaded yet from the session.
//
// Panics if the user was not able to be loaded in order to allow a panic handler to show
// a nice error page, also panics if it failed to redirect for whatever reason.
// Panics if the user was not able to be loaded in order to allow a panic
// handler to show a nice error page, also panics if it failed to redirect
// for whatever reason.
func Middleware(ab *authboss.Authboss) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
@@ -291,9 +292,11 @@ func Middleware(ab *authboss.Authboss) func(http.Handler) http.Handler {
}
}
// GenerateConfirmCreds generates pieces needed for user confirmy
// selector: hash of the first half of a 64 byte value (to be stored in the database and used in SELECT query)
// verifier: hash of the second half of a 64 byte value (to be stored in database but never used in SELECT query)
// GenerateConfirmCreds generates pieces needed for user confirm
// selector: hash of the first half of a 64 byte value
// (to be stored in the database and used in SELECT query)
// verifier: hash of the second half of a 64 byte value
// (to be stored in database but never used in SELECT query)
// token: the user-facing base64 encoded selector+verifier
func GenerateConfirmCreds() (selector, verifier, token string, err error) {
rawToken := make([]byte, confirmTokenSize)

View File

@@ -17,7 +17,8 @@ func NewResponder(renderer authboss.Renderer) *Responder {
}
// Respond to an HTTP request. It's main job is to merge data that comes in from
// various middlewares via the context with the data sent by the controller and render that.
// various middlewares via the context with the data sent by the controller and
// render that.
func (r *Responder) Respond(w http.ResponseWriter, req *http.Request, code int, page string, data authboss.HTMLData) error {
ctxData := req.Context().Value(authboss.CTXKeyData)
if ctxData != nil {

View File

@@ -17,7 +17,8 @@ import (
// NewSMTPMailer creates an SMTP Mailer to send emails with.
// An example usage might be something like:
//
// NewSMTPMailer("smtp.gmail.com", smtp.PlainAuth("", "admin@yoursite.com", "password", "smtp.gmail.com"))
// NewSMTPMailer("smtp.gmail.com",
// smtp.PlainAuth("", "admin@yoursite.com", "password", "smtp.gmail.com"))
func NewSMTPMailer(server string, auth smtp.Auth) *SMTPMailer {
if len(server) == 0 {
panic("SMTP Mailer must be created with a server string.")

View File

@@ -32,8 +32,8 @@ const (
// keyed by the field name, and the value is the field value.
DataPreserve = "preserve"
// DataModules contains a map[string]bool of which modules are loaded
// The bool is largely extraneous and can be ignored, if the module is loaded
// it will be present in the map, if not it will be missing.
// The bool is largely extraneous and can be ignored, if the module is
// loaded it will be present in the map, if not it will be missing.
DataModules = "modules"
)
@@ -41,7 +41,8 @@ const (
type HTMLData map[string]interface{}
// NewHTMLData creates HTMLData from key-value pairs. The input is a key-value
// slice, where odd elements are keys, and the following even element is their value.
// slice, where odd elements are keys, and the following even element
// is their value.
func NewHTMLData(data ...interface{}) HTMLData {
if len(data)%2 != 0 {
panic("it should be a key value list of arguments.")
@@ -71,7 +72,8 @@ func (h HTMLData) Merge(other HTMLData) HTMLData {
}
// MergeKV adds extra key-values to the HTMLData. The input is a key-value
// slice, where odd elements are keys, and the following even element is their value.
// slice, where odd elements are keys, and the following even element
// is their value.
func (h HTMLData) MergeKV(data ...interface{}) HTMLData {
if len(data)%2 != 0 {
panic("It should be a key value list of arguments.")

View File

@@ -266,7 +266,8 @@ func (s *ServerStorer) SaveOAuth2(ctx context.Context, user authboss.OAuth2User)
u := user.(*User)
pid := authboss.MakeOAuth2PID(u.OAuth2Provider, u.OAuth2UID)
// Since we don't have to differentiate between insert/update in a map, we just overwrite
// Since we don't have to differentiate between
// insert/update in a map, we just overwrite
s.Users[pid] = u
return nil
}
@@ -329,7 +330,8 @@ func (s *ServerStorer) UseRememberToken(ctx context.Context, givenKey, token str
return authboss.ErrTokenNotFound
}
// FailStorer is used for testing module initialize functions that recover more than the base storer
// FailStorer is used for testing module initialize functions that
// recover more than the base storer
type FailStorer struct {
User
}

View File

@@ -148,9 +148,10 @@ func (l *Lock) Unlock(ctx context.Context, key string) error {
return l.Authboss.Config.Storage.Server.Save(ctx, lu)
}
// Middleware ensures that a user is not locked, or else it will intercept the request
// and send them to the configured LockNotOK page, this will load the user if he's not been loaded
// yet from the session. And panics if it cannot load the user.
// Middleware ensures that a user is not locked, or else it will intercept
// the request and send them to the configured LockNotOK page, this will load
// the user if he's not been loaded yet from the session. And panics if it
// cannot load the user.
func Middleware(ab *authboss.Authboss) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

View File

@@ -109,7 +109,8 @@ func TestLogoutLogout(t *testing.T) {
resp := httptest.NewRecorder()
w := h.ab.NewResponse(resp)
// This enables the logging portion, which is debatable-y not useful in a log out method
// This enables the logging portion
// which is debatable-y not useful in a log out method
user := &mocks.User{Email: "test@test.com"}
r = r.WithContext(context.WithValue(r.Context(), authboss.CTXKeyUser, user))

View File

@@ -51,13 +51,13 @@ func (a *Authboss) IsLoaded(mod string) bool {
}
// loadModule loads a particular module. It uses reflection to create a new
// instance of the module type. The original value is copied, but not deep copied
// so care should be taken to make sure most initialization happens inside the Initialize()
// method of the module.
// instance of the module type. The original value is copied, but not deep
// copied so care should be taken to make sure most initialization happens
// inside the Initialize() method of the module.
//
// This method exists so many copies of authboss can be loaded and initialized at the same time
// if we didn't use this, then the registeredModules instances of the modules would end up used
// by the first instance of authboss.
// This method exists so many copies of authboss can be loaded and initialized
// at the same time if we didn't use this, then the registeredModules
// instances of the modules would end up used by the first instance of authboss.
func (a *Authboss) loadModule(name string) error {
module, ok := registeredModules[name]
if !ok {
@@ -87,15 +87,15 @@ func (a *Authboss) loadModule(name string) error {
// ModuleListMiddleware puts a map in the data that can be used
// to provide the renderer with information about which pieces of the
// views to show. The bool is extraneous, as presence in the map is the indication
// of wether or not the module is loaded.
// views to show. The bool is extraneous, as presence in the map is
// the indication of wether or not the module is loaded.
// Data looks like:
// map[modulename] = true
//
// oauth2 providers are also listed here using the syntax:
// oauth2.google for an example. Be careful since this doesn't actually mean
// that the oauth2 module has been loaded so you should do a conditional that checks
// for both.
// that the oauth2 module has been loaded so you should do a conditional
// that checks for both.
func ModuleListMiddleware(ab *Authboss) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

View File

@@ -5,28 +5,31 @@
// The general flow looks like this:
// 1. User goes to Start handler and has his session packed with goodies
// then redirects to the OAuth service.
// 2. OAuth service returns to OAuthCallback which extracts state and parameters
// and generally checks that everything is ok. It uses the token received to
// get an access token from the oauth2 library
// 3. Calls the OAuth2Provider.FindUserDetails which should return the user's details
// in a generic form.
// 4. Passes the user details into the OAuth2ServerStorer.NewFromOAuth2 in order
// to create a user object we can work with.
// 2. OAuth service returns to OAuthCallback which extracts state and
// parameters and generally checks that everything is ok. It uses the
// token received to get an access token from the oauth2 library
// 3. Calls the OAuth2Provider.FindUserDetails which should return the user's
// details in a generic form.
// 4. Passes the user details into the OAuth2ServerStorer.NewFromOAuth2 in
// order to create a user object we can work with.
// 5. Saves the user in the database, logs them in, redirects.
//
// In order to do this there are a number of parts:
// 1. The configuration of a provider (handled by authboss.Config.Modules.OAuth2Providers)
// 2. The flow of redirection of client, parameter passing etc (handled by this package)
// 3. The HTTP call to the service once a token has been retrieved to get user details
// (handled by OAuth2Provider.FindUserDetails)
// 4. The creation of a user from the user details returned from the FindUserDetails
// (authboss.OAuth2ServerStorer)
// 1. The configuration of a provider
// (handled by authboss.Config.Modules.OAuth2Providers).
// 2. The flow of redirection of client, parameter passing etc
// (handled by this package)
// 3. The HTTP call to the service once a token has been retrieved to
// get user details (handled by OAuth2Provider.FindUserDetails)
// 4. The creation of a user from the user details returned from the
// FindUserDetails (authboss.OAuth2ServerStorer)
//
// Of these parts, the responsibility of the authboss library consumer is on 1, 3, and 4.
// Configuration of providers that should be used is totally up to the consumer. The FindUserDetails
// function is typically up to the user, but we have some basic ones included in this package too.
// The creation of users from the FindUserDetail's map[string]string return is handled as part
// of the implementation of the OAuth2ServerStorer.
// Of these parts, the responsibility of the authboss library consumer
// is on 1, 3, and 4. Configuration of providers that should be used is totally
// up to the consumer. The FindUserDetails function is typically up to the
// user, but we have some basic ones included in this package too.
// The creation of users from the FindUserDetail's map[string]string return
// is handled as part of the implementation of the OAuth2ServerStorer.
package oauth2
import (
@@ -73,7 +76,8 @@ func (o *OAuth2) Init(ab *authboss.Authboss) error {
o.Authboss = ab
// Do annoying sorting on keys so we can have predictible
// route registration (both for consistency inside the router but also for tests -_-)
// route registration (both for consistency inside the router but
// also for tests -_-)
var keys []string
for k := range o.Authboss.Config.Modules.OAuth2Providers {
keys = append(keys, k)

View File

@@ -30,7 +30,8 @@ type googleMeResponse struct {
// testing
var clientGet = (*http.Client).Get
// GoogleUserDetails can be used as a FindUserDetails function for an authboss.OAuth2Provider
// GoogleUserDetails can be used as a FindUserDetails function
// for an authboss.OAuth2Provider
func GoogleUserDetails(ctx context.Context, cfg oauth2.Config, token *oauth2.Token) (map[string]string, error) {
client := cfg.Client(ctx, token)
resp, err := clientGet(client, googleInfoEndpoint)
@@ -61,7 +62,8 @@ type facebookMeResponse struct {
Name string `json:"name"`
}
// FacebookUserDetails can be used as a FindUserDetails function for an authboss.OAuth2Provider
// FacebookUserDetails can be used as a FindUserDetails function
// for an authboss.OAuth2Provider
func FacebookUserDetails(ctx context.Context, cfg oauth2.Config, token *oauth2.Token) (map[string]string, error) {
client := cfg.Client(ctx, token)
resp, err := clientGet(client, facebookInfoEndpoint)

View File

@@ -12,8 +12,8 @@ import (
)
func init() {
// This has an extra parameter that the Google client wouldn't normally get, but it'll safely be
// ignored.
// This has an extra parameter that the Google client wouldn't normally
// get, but it'll safely be ignored.
clientGet = func(_ *http.Client, url string) (*http.Response, error) {
return &http.Response{
Body: ioutil.NopCloser(strings.NewReader(`{"id":"id", "email":"email", "name": "name"}`)),

View File

@@ -359,7 +359,8 @@ func TestAuthPostUserNotFound(t *testing.T) {
resp := httptest.NewRecorder()
w := harness.ab.NewResponse(resp)
// This event is really the only thing that separates "user not found" from "bad password"
// This event is really the only thing that separates
// "user not found" from "bad password"
var afterCalled bool
harness.ab.Events.After(authboss.EventAuthFail, func(w http.ResponseWriter, r *http.Request, handled bool) (bool, error) {
afterCalled = true

View File

@@ -20,7 +20,8 @@ type User interface {
// GetRecoveryCodes retrieves a CSV string of bcrypt'd recovery codes
GetRecoveryCodes() string
// PutRecoveryCodes uses a single string to store many bcrypt'd recovery codes
// PutRecoveryCodes uses a single string to store many
// bcrypt'd recovery codes
PutRecoveryCodes(codes string)
}
@@ -147,8 +148,8 @@ func BCryptRecoveryCodes(codes []string) ([]string, error) {
return cryptedCodes, nil
}
// UseRecoveryCode deletes the code that was used from the string slice and returns it
// the bool is true if a code was used
// UseRecoveryCode deletes the code that was used from the string slice and
// returns it, the bool is true if a code was used
func UseRecoveryCode(codes []string, inputCode string) ([]string, bool) {
input := []byte(inputCode)
use := -1

View File

@@ -155,8 +155,8 @@ func (r *Recover) SendRecoverEmail(ctx context.Context, to, encodedToken string)
}
}
// EndGet shows a password recovery form, and it should have the token that the user
// brought in the query parameters in it on submission.
// EndGet shows a password recovery form, and it should have the token that
// the user brought in the query parameters in it on submission.
func (r *Recover) EndGet(w http.ResponseWriter, req *http.Request) error {
validatable, err := r.Authboss.Core.BodyReader.Read(PageRecoverMiddle, req)
if err != nil {
@@ -282,8 +282,10 @@ func (r *Recover) mailURL(token string) string {
}
// GenerateRecoverCreds generates pieces needed for user recovery
// selector: hash of the first half of a 64 byte value (to be stored in the database and used in SELECT query)
// verifier: hash of the second half of a 64 byte value (to be stored in database but never used in SELECT query)
// selector: hash of the first half of a 64 byte value
// (to be stored in the database and used in SELECT query)
// verifier: hash of the second half of a 64 byte value
// (to be stored in database but never used in SELECT query)
// token: the user-facing base64 encoded selector+verifier
func GenerateRecoverCreds() (selector, verifier, token string, err error) {
rawToken := make([]byte, recoverTokenSize)

View File

@@ -128,8 +128,8 @@ func (r *Register) Post(w http.ResponseWriter, req *http.Request) error {
return nil
}
// Log the user in, but only if the response wasn't handled previously by a module
// like confirm.
// Log the user in, but only if the response wasn't handled previously
// by a module like confirm.
authboss.PutSession(w, authboss.SessionKey, pid)
logger.Infof("registered and logged in user %s", pid)
@@ -141,7 +141,8 @@ func (r *Register) Post(w http.ResponseWriter, req *http.Request) error {
return r.Config.Core.Redirector.Redirect(w, req, ro)
}
// hasString checks to see if a sorted (ascending) array of strings contains a string
// hasString checks to see if a sorted (ascending) array of
// strings contains a string
func hasString(arr []string, s string) bool {
index := sort.SearchStrings(arr, s)
if index < 0 || index >= len(arr) {

View File

@@ -196,7 +196,8 @@ func TestRegisterPostValidationFailure(t *testing.T) {
h := testSetup()
// Ensure the below is sorted, the sort normally happens in Init() that we don't call
// Ensure the below is sorted, the sort normally happens in Init()
// that we don't call
h.ab.Modules.RegisterPreserveFields = []string{"another", "email"}
h.bodyReader.Return = mocks.ArbValues{
Values: map[string]string{
@@ -249,7 +250,8 @@ func TestRegisterPostUserExists(t *testing.T) {
h := testSetup()
// Ensure the below is sorted, the sort normally happens in Init() that we don't call
// Ensure the below is sorted, the sort normally happens in Init()
// that we don't call
h.ab.Modules.RegisterPreserveFields = []string{"another", "email"}
h.storer.Users["test@test.com"] = &mocks.User{}
h.bodyReader.Return = mocks.ArbValues{

View File

@@ -20,15 +20,15 @@ const (
// - XSRF handling (template data)
// - Assembling template data from various sources
//
// Authboss controller methods (like the one called in response to POST /auth/login)
// will call this method to write a response to the user.
// Authboss controller methods (like the one called in response to
// POST /auth/login) will call this method to write a response to the user.
type HTTPResponder interface {
Respond(w http.ResponseWriter, r *http.Request, code int, templateName string, data HTMLData) error
}
// HTTPRedirector redirects http requests to a different url (must handle both json and html)
// When an authboss controller wants to redirect a user to a different path, it will use
// this interface.
// HTTPRedirector redirects http requests to a different url (must handle
// both json and html) When an authboss controller wants to redirect a user to
// a different path, it will use this interface.
type HTTPRedirector interface {
Redirect(w http.ResponseWriter, r *http.Request, ro RedirectOptions) error
}
@@ -46,8 +46,8 @@ type RedirectOptions struct {
// When a request should redirect a user somewhere on completion, these
// should be set. RedirectURL tells it where to go. And optionally set
// FollowRedirParam to override the RedirectURL if the form parameter defined
// by FormValueRedirect is passed in the request.
// FollowRedirParam to override the RedirectURL if the form parameter
// defined by FormValueRedirect is passed in the request.
//
// Redirecting works differently whether it's an API request or not.
// If it's an API request, then it will leave the URL in a "redirect"
@@ -63,7 +63,8 @@ type EmailResponseOptions struct {
TextTemplate string
}
// Email renders the e-mail templates for the given email and sends it using the mailer.
// Email renders the e-mail templates for the given email and
// sends it using the mailer.
func (a *Authboss) Email(ctx context.Context, email Email, ro EmailResponseOptions) error {
if len(ro.HTMLTemplate) != 0 {
htmlBody, _, err := a.Core.MailRenderer.Render(ctx, ro.HTMLTemplate, ro.Data)

View File

@@ -14,12 +14,13 @@ import (
)
var (
// ErrUserFound should be returned from Create (see ConfirmUser) when the primaryID
// of the record is found.
// ErrUserFound should be returned from Create (see ConfirmUser)
// when the primaryID of the record is found.
ErrUserFound = errors.New("user found")
// ErrUserNotFound should be returned from Get when the record is not found.
ErrUserNotFound = errors.New("user not found")
// ErrTokenNotFound should be returned from UseToken when the record is not found.
// ErrTokenNotFound should be returned from UseToken when the
// record is not found.
ErrTokenNotFound = errors.New("token not found")
)
@@ -56,23 +57,24 @@ type OAuth2ServerStorer interface {
// of details returned from OAuth2Provider.FindUserDetails
// A more in-depth explanation is that once we've got an access token
// for the service in question (say a service that rhymes with book)
// the FindUserDetails function does an http request to a known endpoint that
// provides details about the user, those details are captured in a generic
// way as map[string]string and passed into this function to be turned
// into a real user.
// the FindUserDetails function does an http request to a known endpoint
// that provides details about the user, those details are captured in a
// generic way as map[string]string and passed into this function to be
// turned into a real user.
//
// It's possible that the user exists in the database already, and so
// an attempt should be made to look that user up using the details.
// Any details that have changed should be updated. Do not save the user
// since that will be done by a later call to OAuth2ServerStorer.SaveOAuth2()
// since that will be done later by OAuth2ServerStorer.SaveOAuth2()
NewFromOAuth2(ctx context.Context, provider string, details map[string]string) (OAuth2User, error)
// SaveOAuth2 has different semantics from the typical ServerStorer.Save, in this case
// we want to insert a user if they do not exist. The difference must be made clear because
// in the non-oauth2 case, we know exactly when we want to Create vs Update. However
// since we're simply trying to persist a user that may have been in our database, but if not
// should already be (since you can think of the operation as a caching of what's on the oauth2 provider's
// servers).
// SaveOAuth2 has different semantics from the typical ServerStorer.Save,
// in this case we want to insert a user if they do not exist.
// The difference must be made clear because in the non-oauth2 case,
// we know exactly when we want to Create vs Update. However since we're
// simply trying to persist a user that may have been in our database,
// but if not should already be (since you can think of the operation as
// a caching of what's on the oauth2 provider's servers).
SaveOAuth2(ctx context.Context, user OAuth2User) error
}
@@ -117,7 +119,8 @@ func EnsureCanCreate(storer ServerStorer) CreatingServerStorer {
return s
}
// EnsureCanConfirm makes sure the server storer supports confirm-lookup operations
// EnsureCanConfirm makes sure the server storer supports
// confirm-lookup operations
func EnsureCanConfirm(storer ServerStorer) ConfirmingServerStorer {
s, ok := storer.(ConfirmingServerStorer)
if !ok {
@@ -127,7 +130,8 @@ func EnsureCanConfirm(storer ServerStorer) ConfirmingServerStorer {
return s
}
// EnsureCanRecover makes sure the server storer supports confirm-lookup operations
// EnsureCanRecover makes sure the server storer supports
// confirm-lookup operations
func EnsureCanRecover(storer ServerStorer) RecoveringServerStorer {
s, ok := storer.(RecoveringServerStorer)
if !ok {
@@ -147,7 +151,8 @@ func EnsureCanRemember(storer ServerStorer) RememberingServerStorer {
return s
}
// EnsureCanOAuth2 makes sure the server storer supports oauth2 creation and lookup
// EnsureCanOAuth2 makes sure the server storer supports
// oauth2 creation and lookup
func EnsureCanOAuth2(storer ServerStorer) OAuth2ServerStorer {
s, ok := storer.(OAuth2ServerStorer)
if !ok {

View File

@@ -9,8 +9,8 @@ const (
ConfirmPrefix = "confirm_"
)
// Validator takes a form name and a set of inputs and returns any validation errors
// for the inputs.
// Validator takes a form name and a set of inputs and returns any
// validation errors for the inputs.
type Validator interface {
// Validate makes the type validate itself and return
// a list of validation errors.
@@ -26,8 +26,8 @@ type FieldError interface {
Err() error
}
// ErrorMap is a shortcut to change []error into ErrorList and call Map on it since
// this is a common operation.
// ErrorMap is a shortcut to change []error into ErrorList and call Map on it
// since this is a common operation.
func ErrorMap(e []error) map[string][]string {
return ErrorList(e).Map()
}