password

package
v0.0.0-...-2535ed7 Latest Latest
Warning

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

Go to latest
Published: Sep 28, 2020 License: MIT Imports: 30 Imported by: 2

Documentation

Index

Constants

View Source
const (
	ErrAdminUserNotFound          err = "admin_user_not_found"
	ErrCurrentPasswordNotNatch    err = "current_password_not_match"
	ErrInvalidResetPasswordToken  err = "invalid_reset_token"
	ErrLoadAdminUserFailed        err = "load_admin_user_failed"
	ErrPasswordsNotMatch          err = "passwords_not_match"
	ErrPasswordTooWeak            err = "password_too_weak"
	ErrStrengthTestFailed         err = "strength_test_failed"
	ErrUserIdentityCreationFailed err = "user_identity_creation_failed"
)
View Source
const (
	Name          = "password"
	FieldLogin    = "login"
	FieldPassword = "password"
)
View Source
const DefaultStrengthLevel = 2

Variables

View Source
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")
)
View Source
var (
	PREFIX     = path_helpers.GetCalledDir()
	I18N_GROUP = i18nmod.PkgToGroup(PREFIX)
)
View Source
var (
	// ResetPasswordMailSubject reset password mail's subject
	ResetPasswordMailSubject = I18N_GROUP + ".reset_your_password"

	// SendChangePasswordMailFlashMessage send change password mail flash message
	SendChangePasswordMailFlashMessage = I18N_GROUP + ".change_password_mail_body"

	// ChangedPasswordFlashMessage changed password success flash message
	ChangedPasswordFlashMessage = I18N_GROUP + ".your_password_changed"
)
View Source
var DefaultAuthorizeHandler = func(ctx *auth.LoginContext) (Claims *claims.Claims, err error) {
	var (
		authInfo    auth_identity.Basic
		identity    auth_identity.AuthIdentityInterface
		db          = ctx.DB()
		provider, _ = ctx.Provider.(*Provider)
		uid         = ctx.UID
		password    = ctx.LoginData[FieldPassword].(string)
	)

	if uid == "" {
		if uid, err = ctx.Auth.FindUID(ctx.Context, ctx.LoginData[FieldLogin].(string)); err != nil {
			return
		} else if uid == "" {
			return nil, auth.ErrUidBlank
		}
	}

	if identity, err = helpers.GetIdentity(ctx.Auth.AuthIdentityModel, ctx.Provider.GetName(), db, uid); err != nil {
		return
	}

	authInfo = *identity.GetAuthBasic()

	if provider.Config.Confirmable && authInfo.ConfirmedAt == nil {
		currentUser, _ := ctx.Auth.UserStorer.Get(authInfo.ToClaims(), ctx.Context)
		provider.Config.ConfirmMailer(authInfo.UID, ctx.Context, authInfo.ToClaims(), currentUser)

		return nil, ErrUnconfirmed
	}

	for _, f := range ctx.InfoCallbacks {
		if err = f(ctx, &authInfo); err != nil {
			return
		}
	}

	if err = provider.Encryptor.Compare(string(authInfo.EncryptedPassword), password); err == nil {
		return authInfo.ToClaims(), nil
	}

	return nil, ErrPasswordsNotMatch
}

DefaultAuthorizeHandler default authorize handler

View Source
var DefaultConfirmHandler = func(ctx *auth.Context) error {
	var (
		authInfo    auth_identity.Basic
		provider, _ = ctx.Provider.(*Provider)
		db          = ctx.DB()
		paths       = strings.Split(ctx.Request.URL.Path, "/")
		token       = paths[len(paths)-1]
	)

	claims, err := ctx.SessionStorer.ValidateClaims(token)

	if err == nil {
		if err = claims.Valid(); err == nil {
			authInfo.Provider = provider.GetName()
			authInfo.UID = claims.Id
			authIdentity := reflect.New(utils.ModelType(ctx.Auth.Config.AuthIdentityModel)).Interface()

			if db.Where(authInfo).First(authIdentity).RecordNotFound() {
				err = auth.ErrInvalidAccount
			}

			if err == nil {
				if authInfo.ConfirmedAt == nil {
					now := time.Now()
					authInfo.ConfirmedAt = &now
					if err = db.Model(authIdentity).Update(authInfo).Error; err == nil {
						ctx.SessionStorer.Flash(ctx.SessionManager(), session.Message{Message: ConfirmedAccountFlashMessage, Type: "success"})
						ctx.Auth.Redirector.Redirect(ctx.Writer, ctx.Request, "confirm")
						return nil
					}
				}
				err = ErrAlreadyConfirmed
			}
		}
	}

	return err
}

DefaultConfirmHandler default confirm handler

View Source
var DefaultConfirmationMailer = func(email string, ctx *auth.Context, claims *claims.Claims, currentUser interface{}) error {
	claims.Subject = "confirm"
	Mailer := mailer.FromSite(ctx.Site)
	return Mailer.Send(
		&mailer.Email{
			Context: context.Background(),
			TO:      []mail.Address{{Address: email}},
			Subject: ConfirmationMailSubject,
		}, mailer.Template{
			Name:    "auth/confirmation",
			Data:    ctx,
			Context: ctx.Context,
		}.Funcs(template.FuncMap{
			"current_user": func() interface{} {
				return currentUser
			},
			"confirm_url": func() string {
				confirmURL := utils.GetAbsURL(ctx.Request)
				token, err := ctx.SessionStorer.SignedToken(claims)
				if err != nil {
					return "{TOKEN ERROR=" + err.Error() + "}"
				}
				confirmURL.Path = path.Join(ctx.Auth.AuthPath("password/confirm"), token)
				return confirmURL.String()
			},
		}))
}

DefaultConfirmationMailer default confirm mailer

View Source
var DefaultRecoverPasswordHandler = func(ctx *auth.Context) (err error) {
	_ = ctx.Request.ParseForm()

	var (
		authInfo    *auth_identity.Basic
		identity    auth_identity.AuthIdentityInterface
		identifier  = ctx.Request.Form.Get("email")
		provider, _ = ctx.Provider.(*Provider)
		uid         string
	)

	if uid, err = ctx.Auth.FindUID(ctx, identifier); err != nil {
		return
	}

	if identity, err = helpers.GetIdentity(ctx.Auth.AuthIdentityModel, provider.GetName(), ctx.DB(), uid); err != nil {
		return
	}

	authInfo = identity.GetAuthBasic()
	authInfo.Provider = provider.GetName()

	currentUser, err := ctx.Auth.UserStorer.Get(authInfo.ToClaims(), ctx)

	if err != nil {
		return err
	}

	Claims := authInfo.ToClaims()
	Claims.ExpiresAt = time.Now().Add(time.Minute * 30).Unix()
	if err = provider.ResetPasswordMailer(ctx, Claims, currentUser); err == nil {
		_ = ctx.SessionStorer.Flash(ctx.SessionManager(), session.Message{Message: ctx.T(SendChangePasswordMailFlashMessage), Type: "success"})
		ctx.Auth.Redirector.Redirect(ctx.Writer, ctx.Request, "send_recover_password_mail")
	}
	return err
}

DefaultRecoverPasswordHandler default reset password handler

View Source
var DefaultRegisterHandler = func(context *auth.Context) (Claims *claims.Claims, err error) {
	var (
		currentUser interface{}
		schema      auth.Schema
		authInfo    auth_identity.Basic
		req         = context.Request
		db          = context.DB()
		provider, _ = context.Provider.(*Provider)
	)

	if err = req.ParseForm(); err != nil {
		return
	}

	if req.Form.Get("login") == "" {
		return nil, auth.ErrInvalidAccount
	}

	if req.Form.Get("password") == "" {
		return nil, auth.ErrInvalidPassword
	}

	authInfo.Provider = provider.GetName()
	authInfo.UID = strings.TrimSpace(req.Form.Get("login"))

	if !db.Model(context.Auth.AuthIdentityModel).Where(authInfo).Scan(&authInfo).RecordNotFound() {
		return nil, auth.ErrInvalidAccount
	}

	var ep string
	if ep, err = provider.Encryptor.Digest(strings.TrimSpace(req.Form.Get("password"))); err == nil {
		authInfo.EncryptedPassword = aorm.ProtectedString(ep)
		schema.Provider = authInfo.Provider
		schema.UID = authInfo.UID
		schema.Email = authInfo.UID
		schema.RawInfo = req
		var userId aorm.ID
		currentUser, userId, err = context.Auth.UserStorer.Save(&schema, context)
		authInfo.UserID = userId.String()
		if err != nil {
			return nil, err
		}

		authIdentity := reflect.New(utils.ModelType(context.Auth.Config.AuthIdentityModel)).Interface()
		if err = db.Where(authInfo).FirstOrCreate(authIdentity).Error; err == nil {
			if provider.Config.Confirmable {
				context.SessionStorer.Flash(context.SessionManager(), session.Message{Message: ConfirmFlashMessage, Type: "success"})
				err = provider.Config.ConfirmMailer(schema.Email, context, authInfo.ToClaims(), currentUser)
			}

			return authInfo.ToClaims(), err
		}
	}

	return
}

DefaultRegisterHandler default register handler

View Source
var DefaultResetPasswordHandler = func(ctx *auth.Context, updatedMailer UpdatedPasswordNotifier) (Claims *claims.Claims, err error) {
	_ = ctx.Request.ParseForm()
	pu := &PasswordUpdater{
		CurrentPasswordDisabled: true,
		NotifyMailer:            updatedMailer,
	}
	return pu.Context(ctx)
}

DefaultResetPasswordHandler default reset password handler

View Source
var DefaultResetPasswordMailer = func(ctx *auth.Context, claims *claims.Claims, currentUser auth.User, email ...string) error {
	claims.Subject = "reset_password"
	expireAt := time.Unix(claims.ExpiresAt, 0)
	if location := currentUser.Schema().Location; location != "" {
		expireAt = expireAt.In(tzdb.LocationCity(location).Location())
	}
	if len(email) == 0 || email[0] == "" {
		email = []string{currentUser.Schema().Email}
	}
	Mailer := mailer.FromSite(ctx.Site)
	return Mailer.Send(
		&mailer.Email{
			Context: ctx,
			Lang:    ctx.GetI18nContext().Locales(),
			TO:      []mail.Address{{Address: email[0]}},
			Subject: ctx.Ts(ResetPasswordMailSubject),
		}, mailer.Template{
			Name:    "auth/password/reset_password",
			Data:    ctx,
			Context: ctx.Context,
		}.Funcs(template.FuncMap{
			"current_user": func() interface{} {
				return currentUser
			},
			"expire_at": func() time.Time {
				return expireAt
			},
			"reset_password_url": func() string {
				token, err := ctx.SessionStorer.SignedToken(claims)
				if err != nil {
					return "{TOKEN ERROR=" + err.Error() + "}"
				}
				url := ctx.AuthURL("password/edit", token)
				return url
			},
		}),
	)
}

DefaultResetPasswordMailer default reset password mailer

View Source
var DefaultUpdatedPasswordNotifier = func(TO []mail.Address, context *auth.Context, user auth.User, passwd string) error {
	Mailer := mailer.FromSite(context.Site)
	if Mailer == nil {
		log.Warningf("No mailer for %q. Password for user %q#%s is %q", context.Site.Name(), user.Schema().Name, aorm.IdOf(user), passwd)
		return nil
	}
	if you := user.Schema().MailAddress(); you != nil {
		subject := context.Ts(ChangedPasswordFlashMessage)
		if err := Mailer.Send(
			&mailer.Email{
				Context: context,
				Lang:    append(user.Schema().Lang, context.GetI18nContext().Locales()...),
				TO:      []mail.Address{*you},
				Subject: subject,
			}, mailer.Template{
				Name:    "auth/password/you_password_updated",
				Data:    context,
				Context: context.Context,
			}.Funcs(template.FuncMap{
				"you": func() *mail.Address {
					return you
				},
				"user": func() interface{} {
					return user
				},
				"login_url": func() string {
					return context.AuthURL("login")
				},
				"user_info": func() *auth.Schema {
					return user.Schema()
				},
				"has_password": func() bool {
					return passwd != ""
				},
				"password": func() string {
					return passwd
				},
			}),
		); err != nil {
			return err
		}
	}
	return Mailer.Send(
		&mailer.Email{
			Context: context,
			Lang:    context.GetI18nContext().Locales(),
			TO:      TO,
			Subject: context.Ts(ResetPasswordMailSubject),
		}, mailer.Template{
			Name:    "auth/password/updated_password",
			Data:    context,
			Context: context.Context,
		}.Funcs(template.FuncMap{
			"user": func() interface{} {
				return user
			},
			"login_url": func() string {
				return context.AuthURL("login")
			},
			"user_info": func() *auth.Schema {
				return user.Schema()
			},
			"has_password": func() bool {
				return passwd != ""
			},
			"password": func() string {
				return passwd
			},
		}),
	)
}

DefaultUpdatePasswordMailer default update password mailer

Functions

func NewPasswordToken

func NewPasswordToken(ctx *auth.Context, email string) (string, error)

Types

type Config

type Config struct {
	Confirmable    bool
	ConfirmMailer  func(email string, context *auth.Context, claims *claims.Claims, currentUser interface{}) error
	ConfirmHandler func(*auth.Context) error

	ResetPasswordMailer    func(context *auth.Context, claims *claims.Claims, currentUser auth.User, email ...string) error
	ResetPasswordHandler   func(*auth.Context, UpdatedPasswordNotifier) (Claims *claims.Claims, err error)
	RecoverPasswordHandler func(*auth.Context) error

	Encryptor        encryptor.Interface
	AuthorizeHandler func(*auth.LoginContext) (*claims.Claims, error)
	RegisterHandler  func(*auth.Context) (*claims.Claims, error)

	UpdatedPasswordNotifier UpdatedPasswordNotifier
}

Config password config

type PasswordUpdater

type PasswordUpdater struct {
	UID                         string
	Token                       string
	NewPassword                 string
	PasswordConfirm             string
	CurrentPassword             string
	CurrentPasswordDisabled     bool
	StrengthDisabled            bool
	StrengthLevel               int
	Createable                  bool
	Confirmed                   bool
	UserID                      string
	IsAdmin                     bool
	AdminUserUID                string
	AuthIdentityModel           interface{}
	Provider                    *Provider
	DB                          *aorm.DB
	T                           func(key string, defaul ...interface{}) string
	NotifyPlainPasswordDisabled bool
	NotifyMailer                UpdatedPasswordNotifier
	NotifyTo                    []mail.Address
	NotifyToUserDisabled        bool
}

func (PasswordUpdater) Context

func (this PasswordUpdater) Context(context *auth.Context) (Claims *claims.Claims, err error)

func (*PasswordUpdater) Success

func (this *PasswordUpdater) Success() session.Message

func (*PasswordUpdater) Update

func (this *PasswordUpdater) Update(context *auth.Context) (err error)

type Plugin

type Plugin struct {
}

type Provider

type Provider struct {
	*Config
}

Provider provide login with password method

func GetProvider

func GetProvider(Auth *auth.Auth) *Provider

func New

func New(config *Config) *Provider

New initialize password provider

func (Provider) Callback

func (provider Provider) Callback(context *auth.Context)

Callback implement Callback with password provider

func (Provider) ConfigAuth

func (provider Provider) ConfigAuth(auth *auth.Auth)

ConfigAuth config auth

func (Provider) GetName

func (Provider) GetName() string

GetName return provider name

func (Provider) I18n

func (p Provider) I18n(key ...string) string

I18n returh i18n key prefix

func (Provider) Login

func (provider Provider) Login(context *auth.LoginContext) (*claims.Claims, error)

Login implemented login with password provider

func (Provider) Logout

func (provider Provider) Logout(context *auth.Context)

Logout implemented logout with password provider

func (Provider) ParseRequestForm

func (provider Provider) ParseRequestForm(req *http.Request) (data maps.Map, err error)

func (Provider) ParseValues

func (provider Provider) ParseValues(values url.Values) (data maps.Map, err error)

func (Provider) PrepareLoginContext

func (provider Provider) PrepareLoginContext(context *auth.LoginContext) (err error)

func (Provider) Register

func (provider Provider) Register(context *auth.Context)

Register implemented register with password provider

func (Provider) ServeHTTP

func (provider Provider) ServeHTTP(context *auth.Context)

ServeHTTP implement ServeHTTP with password provider

func (Provider) SetLoginPassword

func (provider Provider) SetLoginPassword(context *auth.LoginContext, login, password string) *auth.LoginContext

type UpdatedPasswordNotifier

type UpdatedPasswordNotifier interface {
	Notify(TO []mail.Address, context *auth.Context, user auth.User, passwd string) error
}

type UpdatedPasswordNotifierFunc

type UpdatedPasswordNotifierFunc func(TO []mail.Address, context *auth.Context, user auth.User, passwd string) error

func (UpdatedPasswordNotifierFunc) Notify

func (this UpdatedPasswordNotifierFunc) Notify(TO []mail.Address, context *auth.Context, user auth.User, passwd string) error

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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