Documentation
¶
Index ¶
- Constants
- Variables
- type Auth
- func (auth *Auth) AuthURL(pth string) string
- func (auth *Auth) GetCurrentUser(req *http.Request) interface{}
- func (auth *Auth) GetDB(request *http.Request) *gorm.DB
- func (auth *Auth) GetProvider(name string) Provider
- func (auth *Auth) GetProviders() (providers []Provider)
- func (auth *Auth) Login(w http.ResponseWriter, req *http.Request, claimer claims.ClaimerInterface) error
- func (auth *Auth) Logout(w http.ResponseWriter, req *http.Request)
- func (auth *Auth) NewServeMux() http.Handler
- func (auth *Auth) RegisterProvider(provider Provider)
- type Config
- type Context
- type DefaultSMSSender
- type Provider
- type Redirector
- type RedirectorInterface
- type SMSSender
- type Schema
- type SessionStorer
- func (sessionStorer *SessionStorer) Delete(w http.ResponseWriter, req *http.Request) error
- func (sessionStorer *SessionStorer) Flash(w http.ResponseWriter, req *http.Request, message session.Message) error
- func (sessionStorer *SessionStorer) Flashes(w http.ResponseWriter, req *http.Request) []session.Message
- func (sessionStorer *SessionStorer) Get(req *http.Request) (*claims.Claims, error)
- func (sessionStorer *SessionStorer) SignedToken(claims *claims.Claims) string
- func (sessionStorer *SessionStorer) Update(w http.ResponseWriter, req *http.Request, claims *claims.Claims) error
- func (sessionStorer *SessionStorer) ValidateClaims(tokenString string) (*claims.Claims, error)
- type SessionStorerInterface
- type UserStorer
- type UserStorerInterface
Constants ¶
const CurrentUser utils.ContextKey = "current_user"
CurrentUser context key to get current user from Request
Variables ¶
var ( // ErrAlreadyRegistered registered error ErrAlreadyRegistered = errors.New("Email already registered") // ErrPhoneRegistered registered error ErrPhoneRegistered = errors.New("Phone already registered") // ErrInvalidPassword invalid password error ErrInvalidPassword = errors.New("invalid password") // ErrInvalidAccount invalid account error ErrInvalidAccount = errors.New("invalid account") // ErrInvalidPhoneNumber invalid format phone number ErrInvalidPhoneNumber = errors.New("invalid format phone number") ErrUnauthorized = errors.New("Unauthorized") )
var ( // ConfirmationMailSubject confirmation mail's subject ConfirmationMailSubject = "Please confirm your account" // ConfirmedAccountFlashMessage confirmed your account message ConfirmedAccountFlashMessage = template.HTML("Confirmed your account!") // ConfirmFlashMessage confirm account flash message ConfirmFlashMessage = template.HTML("Please confirm your account") // ErrAlreadyConfirmed account already confirmed error ErrAlreadyConfirmed = errors.New("Your account already been confirmed") // ErrUnconfirmed unauthorized error ErrUnconfirmed = errors.New("You have to confirm your account before continuing") )
var DefaultAssetHandler = func(context *Context) { asset := strings.TrimPrefix(context.Request.URL.Path, context.Auth.URLPrefix) if context.Request.Header.Get("If-Modified-Since") == cacheSince { context.Writer.WriteHeader(http.StatusNotModified) return } context.Writer.Header().Set("Last-Modified", cacheSince) if content, err := context.Config.Render.Asset(path.Join("/auth", asset)); err == nil { etag := fmt.Sprintf("%x", md5.Sum(content)) if context.Request.Header.Get("If-None-Match") == etag { context.Writer.WriteHeader(http.StatusNotModified) return } if ctype := mime.TypeByExtension(filepath.Ext(asset)); ctype != "" { context.Writer.Header().Set("Content-Type", ctype) } context.Writer.Header().Set("Cache-control", "private, must-revalidate, max-age=300") context.Writer.Header().Set("ETag", etag) context.Writer.Write(content) } else { http.NotFound(context.Writer, context.Request) } }
DefaultAssetHandler render auth asset file
var DefaultConfirmHandler = func(context *Context) error { var ( authInfo auth_identity.Basic tx = context.Auth.GetDB(context.Request) token = context.Request.URL.Query().Get("token") ) claims, err := context.SessionStorer.ValidateClaims(token) if err == nil { if err = claims.Valid(); err == nil { authInfo.UID = claims.Id authIdentity := reflect.New(utils.ModelType(context.Auth.Config.AuthIdentityModel)).Interface() if tx.Where(map[string]interface{}{ "provider": authInfo.Provider, "uid": authInfo.UID, }).First(authIdentity).RecordNotFound() { err = ErrInvalidAccount } if err == nil { if authInfo.ConfirmedAt == nil { now := time.Now() authInfo.ConfirmedAt = &now if err = tx.Model(authIdentity).Where(map[string]interface{}{ "provider": authInfo.Provider, "uid": authInfo.UID, }).Update(authInfo).Error; err == nil { context.SessionStorer.Flash(context.Writer, context.Request, session.Message{Message: ConfirmedAccountFlashMessage, Type: "success"}) context.Auth.Redirector.Redirect(context.Writer, context.Request, "confirm") return nil } } err = ErrAlreadyConfirmed } } } return err }
DefaultConfirmHandler default confirm handler
var DefaultConfirmationMailer = func(email string, context *Context, claim *claims.Claims, currentUser interface{}) error { claim.Subject = "confirm" return context.Auth.Mailer.Send( mailer.Email{ TO: []mail.Address{{Address: email}}, From: &mail.Address{Address: "admin@example.org"}, Subject: ConfirmationMailSubject, }, mailer.Template{ Name: "auth/confirmation", Data: context, Request: context.Request, Writer: context.Writer, }.Funcs(template.FuncMap{ "current_user": func() interface{} { return currentUser }, "confirm_url": func() string { confirmURL := utils.GetAbsURL(context.Request) confirmURL.Path = path.Join(context.Auth.AuthURL("password/confirm")) qry := confirmURL.Query() qry.Set("token", context.SessionStorer.SignedToken(claim)) confirmURL.RawQuery = qry.Encode() return confirmURL.String() }, })) }
DefaultConfirmationMailer default confirm mailer
var DefaultLoginHandler = func(context *Context, authorize func(*Context) (*claims.Claims, error)) { var ( req = context.Request w = context.Writer claims, err = authorize(context) ) if err == nil && claims != nil { context.SessionStorer.Flash(w, req, session.Message{Message: "logged"}) respondAfterLogged(claims, context) return } context.SessionStorer.Flash(w, req, session.Message{Message: template.HTML(err.Error()), Type: "error"}) responder.With("html", func() { context.Auth.Config.Render.Execute("auth/login", context, req, w) }).With([]string{"json"}, func() { }).Respond(context.Request) }
DefaultLoginHandler default login behaviour
var DefaultLogoutHandler = func(context *Context) {
context.SessionStorer.Delete(context.Writer, context.Request)
context.Auth.Redirector.Redirect(context.Writer, context.Request, "logout")
}
DefaultLogoutHandler default logout behaviour
var DefaultRegisterHandler = func(context *Context, register func(*Context) (*claims.Claims, error)) { var ( req = context.Request w = context.Writer claims, err = register(context) ) if err == nil && claims != nil { respondAfterLogged(claims, context) return } context.SessionStorer.Flash(w, req, session.Message{Message: template.HTML(err.Error()), Type: "error"}) responder.With("html", func() { context.Auth.Config.Render.Execute("auth/register", context, req, w) }).With([]string{"json"}, func() { }).Respond(context.Request) }
DefaultRegisterHandler default register b ehaviour
var DefaultWelcomeMailer = func(email string, context *Context, claim *claims.Claims, currentUser interface{}) error { claim.Subject = "confirm" return context.Auth.Mailer.Send( mailer.Email{ TO: []mail.Address{{Address: email}}, From: &mail.Address{Address: "admin@example.org"}, Subject: "Welcome To Our Store", }, mailer.Template{ Name: "auth/confirmation", Data: context, Request: context.Request, Writer: context.Writer, }.Funcs(template.FuncMap{ "current_user": func() interface{} { return currentUser }, "confirm_url": func() string { confirmURL := utils.GetAbsURL(context.Request) confirmURL.Path = path.Join(context.Auth.AuthURL("password/confirm")) qry := confirmURL.Query() qry.Set("token", context.SessionStorer.SignedToken(claim)) confirmURL.RawQuery = qry.Encode() return confirmURL.String() }, })) }
DefaultWelcomeMailer default mailer for welcome message
Functions ¶
This section is empty.
Types ¶
type Auth ¶
type Auth struct {
*Config
// Embed SessionStorer to match Authority's AuthInterface
SessionStorerInterface
// contains filtered or unexported fields
}
Auth auth struct
func (*Auth) GetCurrentUser ¶
GetCurrentUser get current user from request
func (*Auth) GetProvider ¶
GetProvider get provider with name
func (*Auth) GetProviders ¶
GetProviders return registered providers
func (*Auth) Login ¶
func (auth *Auth) Login(w http.ResponseWriter, req *http.Request, claimer claims.ClaimerInterface) error
Login sign user in
func (*Auth) Logout ¶
func (auth *Auth) Logout(w http.ResponseWriter, req *http.Request)
Logout sign current user out
func (*Auth) NewServeMux ¶
NewServeMux generate http.Handler for auth
func (*Auth) RegisterProvider ¶
RegisterProvider register auth provider
type Config ¶
type Config struct {
// Default Database, which will be used in Auth when do CRUD, you can change a request's DB isntance by setting request Context's value, refer https://github.com/fahmibaswara/auth/blob/master/utils.go#L32
DB *gorm.DB
// AuthIdentityModel a model used to save auth info, like email/password, OAuth token, linked user's ID, https://github.com/fahmibaswara/auth/blob/master/auth_identity/auth_identity.go is the default implemention
AuthIdentityModel interface{}
// UserModel should be point of user struct's instance, it could be nil, then Auth will assume there is no user linked to auth info, and will return current auth info when get current user
UserModel interface{}
// Mount Auth into router with URLPrefix's value as prefix, default value is `/auth`.
URLPrefix string
// ViewPaths prepend views paths for auth
ViewPaths []string
// Auth is using [Render](https://github.com/qor/render) to render pages, you could configure it with your project's Render if you have advanced usage like [BindataFS](https://github.com/qor/bindatafs)
Render *render.Render
// Auth is using [Mailer](https://github.com/qor/mailer) to send email, by default, it will print email into console, you need to configure it to send real one
Mailer *mailer.Mailer
Confirmable bool
ConfirmMailer func(email string, context *Context, claims *claims.Claims, currentUser interface{}) error
ConfirmHandler func(*Context) error
WelcomeMailer func(email string, context *Context, claims *claims.Claims, currentUser interface{}) error
// SMS Sender, by default, it will print email into console, you need to configure it to send real one
SMSSender SMSSender
// UserToken a model used to save token that generated for authentication via Phone, https://github.com/fahmibaswara/auth/blob/master/auth_identity/auth_token.go is the default implemention
UserTokenModel interface{}
// UserStorer is an interface that defined how to get/save user, Auth provides a default one based on AuthIdentityModel, UserModel's definition
UserStorer UserStorerInterface
// SessionStorer is an interface that defined how to encode/validate/save/destroy session data and flash messages between requests, Auth provides a default method do the job, to use the default value, don't forgot to mount SessionManager's middleware into your router to save session data correctly. refer [session](https://github.com/qor/session) for more details
SessionStorer SessionStorerInterface
// Redirector redirect user to a new page after registered, logged, confirmed...
Redirector RedirectorInterface
// LoginHandler defined behaviour when request `{Auth Prefix}/login`, default behaviour defined in http://godoc.org/github.com/fahmibaswara/auth#pkg-variables
LoginHandler func(*Context, func(*Context) (*claims.Claims, error))
// RegisterHandler defined behaviour when request `{Auth Prefix}/register`, default behaviour defined in http://godoc.org/github.com/fahmibaswara/auth#pkg-variables
RegisterHandler func(*Context, func(*Context) (*claims.Claims, error))
// LogoutHandler defined behaviour when request `{Auth Prefix}/logout`, default behaviour defined in http://godoc.org/github.com/fahmibaswara/auth#pkg-variables
LogoutHandler func(*Context)
}
Config auth config
type Context ¶
type Context struct {
*Auth
Claims *claims.Claims
Provider Provider
Request *http.Request
Writer http.ResponseWriter
}
Context context
type Provider ¶
type Provider interface {
GetName() string
ConfigAuth(*Auth)
Login(*Context)
Logout(*Context)
Register(*Context)
Callback(*Context)
ServeHTTP(*Context)
}
Provider define Provider interface
type Redirector ¶
type Redirector struct {
*redirect_back.RedirectBack
}
Redirector default redirector
func (Redirector) Redirect ¶
func (redirector Redirector) Redirect(w http.ResponseWriter, req *http.Request, action string)
Redirect redirect back after action
type RedirectorInterface ¶
type RedirectorInterface interface {
// Redirect redirect after action
Redirect(w http.ResponseWriter, req *http.Request, action string)
}
RedirectorInterface redirector interface
type Schema ¶
type Schema struct {
Provider string
UID string
Role string
IsApproved string
Name string
Email string
FirstName string
LastName string
Location string
Image string
Phone string
URL string
RawInfo interface{}
}
Schema auth schema
type SessionStorer ¶
type SessionStorer struct {
SessionName string
SigningMethod jwt.SigningMethod
SignedString string
SessionManager session.ManagerInterface
}
SessionStorer default session storer
func (*SessionStorer) Delete ¶
func (sessionStorer *SessionStorer) Delete(w http.ResponseWriter, req *http.Request) error
Delete delete claims from session manager
func (*SessionStorer) Flash ¶
func (sessionStorer *SessionStorer) Flash(w http.ResponseWriter, req *http.Request, message session.Message) error
Flash add flash message to session data
func (*SessionStorer) Flashes ¶
func (sessionStorer *SessionStorer) Flashes(w http.ResponseWriter, req *http.Request) []session.Message
Flashes returns a slice of flash messages from session data
func (*SessionStorer) SignedToken ¶
func (sessionStorer *SessionStorer) SignedToken(claims *claims.Claims) string
SignedToken generate signed token with Claims
func (*SessionStorer) Update ¶
func (sessionStorer *SessionStorer) Update(w http.ResponseWriter, req *http.Request, claims *claims.Claims) error
Update update claims with session manager
func (*SessionStorer) ValidateClaims ¶
func (sessionStorer *SessionStorer) ValidateClaims(tokenString string) (*claims.Claims, error)
ValidateClaims validate auth token
type SessionStorerInterface ¶
type SessionStorerInterface interface {
// Get get claims from request
Get(req *http.Request) (*claims.Claims, error)
// Update update claims with session manager
Update(w http.ResponseWriter, req *http.Request, claims *claims.Claims) error
// Delete delete session
Delete(w http.ResponseWriter, req *http.Request) error
// Flash add flash message to session data
Flash(w http.ResponseWriter, req *http.Request, message session.Message) error
// Flashes returns a slice of flash messages from session data
Flashes(w http.ResponseWriter, req *http.Request) []session.Message
// SignedToken generate signed token with Claims
SignedToken(claims *claims.Claims) string
// ValidateClaims validate auth token
ValidateClaims(tokenString string) (*claims.Claims, error)
}
SessionStorerInterface session storer interface for Auth
type UserStorer ¶
type UserStorer struct {
// contains filtered or unexported fields
}
UserStorer default user storer