mirror of
				https://github.com/volatiletech/authboss.git
				synced 2025-10-30 23:47:59 +02:00 
			
		
		
		
	Work on the auth module
- Move more *User interfaces into storage.go, no need for them to be in each individual module.
This commit is contained in:
		
							
								
								
									
										86
									
								
								auth/auth.go
									
									
									
									
									
								
							
							
						
						
									
										86
									
								
								auth/auth.go
									
									
									
									
									
								
							| @@ -6,7 +6,6 @@ import ( | ||||
| 	"net/http" | ||||
|  | ||||
| 	"github.com/pkg/errors" | ||||
|  | ||||
| 	"github.com/volatiletech/authboss" | ||||
| 	"github.com/volatiletech/authboss/internal/response" | ||||
| 	"golang.org/x/crypto/bcrypt" | ||||
| @@ -25,57 +24,47 @@ type Auth struct { | ||||
| 	*authboss.Authboss | ||||
| } | ||||
|  | ||||
| // Initialize module | ||||
| func (a *Auth) Initialize(ab *authboss.Authboss) (err error) { | ||||
| // Init module | ||||
| func (a *Auth) Init(ab *authboss.Authboss) (err error) { | ||||
| 	a.Authboss = ab | ||||
|  | ||||
| 	if a.Storer == nil && a.StoreMaker == nil { | ||||
| 		return errors.New("need a storer") | ||||
| 	} | ||||
|  | ||||
| 	if len(a.XSRFName) == 0 { | ||||
| 		return errors.New("xsrfName must be set") | ||||
| 	} | ||||
|  | ||||
| 	if a.XSRFMaker == nil { | ||||
| 		return errors.New("xsrfMaker must be defined") | ||||
| 	} | ||||
|  | ||||
| 	a.templates, err = response.LoadTemplates(a.Authboss, a.Layout, a.ViewsPath, tplLogin) | ||||
| 	if err != nil { | ||||
| 	if err := a.Authboss.Config.Core.ViewRenderer.Load(tplLogin); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	var logoutRouteMethod func(string, http.Handler) | ||||
| 	switch a.Authboss.Config.Modules.LogoutMethod { | ||||
| 	case "GET": | ||||
| 		logoutRouteMethod = a.Authboss.Config.Core.Router.Get | ||||
| 	case "POST": | ||||
| 		logoutRouteMethod = a.Authboss.Config.Core.Router.Post | ||||
| 	case "DELETE": | ||||
| 		logoutRouteMethod = a.Authboss.Config.Core.Router.Delete | ||||
| 	default: | ||||
| 		return errors.Errorf("auth wants to register a logout route but is given an invalid method: %s", a.Authboss.Config.Modules.LogoutMethod) | ||||
| 	} | ||||
|  | ||||
| 	a.Authboss.Config.Core.Router.Get("/login", http.HandlerFunc(loginGet)) | ||||
| 	a.Authboss.Config.Core.Router.Post("/login", http.HandlerFunc(loginPost)) | ||||
| 	logoutRouteMethod("/logout", http.HandlerFunc(logout)) | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Routes for the module | ||||
| func (a *Auth) Routes() authboss.RouteTable { | ||||
| 	return authboss.RouteTable{ | ||||
| 		"/login":  a.loginHandlerFunc, | ||||
| 		"/logout": a.logoutHandlerFunc, | ||||
| 	} | ||||
| func (a *Auth) loginGet(w http.ResponseWriter, r *http.Request) error { | ||||
| 	data := authboss.NewHTMLData( | ||||
| 		"showRemember", a.IsLoaded("remember"), | ||||
| 		"showRecover", a.IsLoaded("recover"), | ||||
| 		"showRegister", a.IsLoaded("register"), | ||||
| 		"primaryID", a.PrimaryID, | ||||
| 		"primaryIDValue", "", | ||||
| 	) | ||||
| 	return a.templates.Render(ctx, w, r, tplLogin, data) | ||||
| } | ||||
|  | ||||
| // Storage requirements | ||||
| func (a *Auth) Storage() authboss.StorageOptions { | ||||
| 	return authboss.StorageOptions{ | ||||
| 		a.PrimaryID:            authboss.String, | ||||
| 		authboss.StorePassword: authboss.String, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (a *Auth) loginHandlerFunc(ctx *authboss.Context, w http.ResponseWriter, r *http.Request) error { | ||||
| func (a *Auth) loginPost(w http.ResponseWriter, r *http.Request) error { | ||||
| 	switch r.Method { | ||||
| 	case methodGET: | ||||
| 		data := authboss.NewHTMLData( | ||||
| 			"showRemember", a.IsLoaded("remember"), | ||||
| 			"showRecover", a.IsLoaded("recover"), | ||||
| 			"showRegister", a.IsLoaded("register"), | ||||
| 			"primaryID", a.PrimaryID, | ||||
| 			"primaryIDValue", "", | ||||
| 		) | ||||
| 		return a.templates.Render(ctx, w, r, tplLogin, data) | ||||
| 	case methodPOST: | ||||
| 		key := r.FormValue(a.PrimaryID) | ||||
| 		password := r.FormValue("password") | ||||
| @@ -130,7 +119,7 @@ func (a *Auth) loginHandlerFunc(ctx *authboss.Context, w http.ResponseWriter, r | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func validateCredentials(ctx *authboss.Context, key, password string) (bool, error) { | ||||
| func validateCredentials(key, password string) (bool, error) { | ||||
| 	if err := ctx.LoadUser(key); err == authboss.ErrUserNotFound { | ||||
| 		return false, nil | ||||
| 	} else if err != nil { | ||||
| @@ -149,17 +138,12 @@ func validateCredentials(ctx *authboss.Context, key, password string) (bool, err | ||||
| 	return true, nil | ||||
| } | ||||
|  | ||||
| func (a *Auth) logoutHandlerFunc(ctx *authboss.Context, w http.ResponseWriter, r *http.Request) error { | ||||
| 	switch r.Method { | ||||
| 	case methodGET: | ||||
| 		ctx.SessionStorer.Del(authboss.SessionKey) | ||||
| 		ctx.CookieStorer.Del(authboss.CookieRemember) | ||||
| 		ctx.SessionStorer.Del(authboss.SessionLastAction) | ||||
| func (a *Auth) logout(w http.ResponseWriter, r *http.Request) error { | ||||
| 	ctx.SessionStorer.Del(authboss.SessionKey) | ||||
| 	ctx.CookieStorer.Del(authboss.CookieRemember) | ||||
| 	ctx.SessionStorer.Del(authboss.SessionLastAction) | ||||
|  | ||||
| 		response.Redirect(ctx, w, r, a.AuthLogoutOKPath, "You have logged out", "", true) | ||||
| 	default: | ||||
| 		w.WriteHeader(http.StatusMethodNotAllowed) | ||||
| 	} | ||||
| 	response.Redirect(ctx, w, r, a.AuthLogoutOKPath, "You have logged out", "", true) | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|   | ||||
| @@ -30,7 +30,10 @@ type Config struct { | ||||
|  | ||||
| 	Modules struct { | ||||
| 		// BCryptCost is the cost of the bcrypt password hashing function. | ||||
| 		BCryptCost int | ||||
| 		AuthBCryptCost int | ||||
|  | ||||
| 		// LogoutMethod is the method the logout route should use (default should be DELETE) | ||||
| 		LogoutMethod string | ||||
|  | ||||
| 		// OAuth2Providers lists all providers that can be used. See | ||||
| 		// OAuthProvider documentation for more details. | ||||
|   | ||||
							
								
								
									
										40
									
								
								storage.go
									
									
									
									
									
								
							
							
						
						
									
										40
									
								
								storage.go
									
									
									
									
									
								
							| @@ -49,11 +49,27 @@ type ServerStorer interface { | ||||
| // a single unique identifier to any given user (very typically e-mail | ||||
| // or username). | ||||
| type User interface { | ||||
| 	PutPID(ctx context.Context, pid string) error | ||||
| 	PutPassword(ctx context.Context, password string) error | ||||
|  | ||||
| 	GetPID(ctx context.Context) (pid string, err error) | ||||
| 	PutPID(ctx context.Context, pid string) error | ||||
| } | ||||
|  | ||||
| // AuthableUser is identified by a password | ||||
| type AuthableUser interface { | ||||
| 	User | ||||
|  | ||||
| 	GetPassword(ctx context.Context) (password string, err error) | ||||
| 	PutPassword(ctx context.Context, password string) error | ||||
| } | ||||
|  | ||||
| // ConfirmableUser can be in a state of confirmed or not | ||||
| type ConfirmableUser interface { | ||||
| 	User | ||||
|  | ||||
| 	GetConfirmed(ctx context.Context) (confirmed bool, err error) | ||||
| 	GetConfirmToken(ctx context.Context) (token string, err error) | ||||
|  | ||||
| 	PutConfirmed(ctx context.Context, confirmed bool) error | ||||
| 	PutConfirmToken(ctx context.Context, token string) error | ||||
| } | ||||
|  | ||||
| // ArbitraryUser allows arbitrary data from the web form through. You should | ||||
| @@ -62,12 +78,12 @@ type User interface { | ||||
| type ArbitraryUser interface { | ||||
| 	User | ||||
|  | ||||
| 	// PutArbitrary allows arbitrary fields defined by the authboss library | ||||
| 	// consumer to add fields to the user registration piece. | ||||
| 	PutArbitrary(ctx context.Context, arbitrary map[string]string) error | ||||
| 	// GetArbitrary is used only to display the arbitrary data back to the user | ||||
| 	// when the form is reset. | ||||
| 	GetArbitrary(ctx context.Context) (arbitrary map[string]string, err error) | ||||
| 	// PutArbitrary allows arbitrary fields defined by the authboss library | ||||
| 	// consumer to add fields to the user registration piece. | ||||
| 	PutArbitrary(ctx context.Context, arbitrary map[string]string) error | ||||
| } | ||||
|  | ||||
| // OAuth2User allows reading and writing values relating to OAuth2 | ||||
| @@ -78,15 +94,15 @@ type OAuth2User interface { | ||||
| 	// oauth2 user. | ||||
| 	IsOAuth2User(ctx context.Context) (bool, error) | ||||
|  | ||||
| 	PutUID(ctx context.Context, uid string) error | ||||
| 	PutProvider(ctx context.Context, provider string) error | ||||
| 	PutToken(ctx context.Context, token string) error | ||||
| 	PutRefreshToken(ctx context.Context, refreshToken string) error | ||||
| 	PutExpiry(ctx context.Context, expiry time.Duration) error | ||||
|  | ||||
| 	GetUID(ctx context.Context) (uid string, err error) | ||||
| 	GetProvider(ctx context.Context) (provider string, err error) | ||||
| 	GetToken(ctx context.Context) (token string, err error) | ||||
| 	GetRefreshToken(ctx context.Context) (refreshToken string, err error) | ||||
| 	GetExpiry(ctx context.Context) (expiry time.Duration, err error) | ||||
|  | ||||
| 	PutUID(ctx context.Context, uid string) error | ||||
| 	PutProvider(ctx context.Context, provider string) error | ||||
| 	PutToken(ctx context.Context, token string) error | ||||
| 	PutRefreshToken(ctx context.Context, refreshToken string) error | ||||
| 	PutExpiry(ctx context.Context, expiry time.Duration) error | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user