1
0
mirror of https://github.com/volatiletech/authboss.git synced 2025-01-24 05:17:10 +02:00

Make "remember" value passing unobtrusive

- Remove RM context key for Values.
- Add values types and code to be able to pull the remember me bool
  checkbox from the user.
This commit is contained in:
Aaron L 2018-03-07 15:17:22 -08:00
parent ac3d2846f8
commit ce2d3dac09
7 changed files with 38 additions and 8 deletions

View File

@ -87,6 +87,8 @@ func (a *Auth) LoginPost(w http.ResponseWriter, r *http.Request) error {
return a.Authboss.Core.Responder.Respond(w, r, http.StatusOK, PageLogin, data)
}
r = r.WithContext(context.WithValue(r.Context(), authboss.CTXKeyValues, validatable))
handled, err = a.Events.FireBefore(authboss.EventAuth, w, r)
if err != nil {
return err

View File

@ -114,12 +114,15 @@ func TestAuthPostSuccess(t *testing.T) {
h := setupMore(testSetup())
var beforeCalled, afterCalled bool
var beforeHasValues, afterHasValues bool
h.ab.Events.Before(authboss.EventAuth, func(w http.ResponseWriter, r *http.Request, handled bool) (bool, error) {
beforeCalled = true
beforeHasValues = r.Context().Value(authboss.CTXKeyValues) != nil
return false, nil
})
h.ab.Events.After(authboss.EventAuth, func(w http.ResponseWriter, r *http.Request, handled bool) (bool, error) {
afterCalled = true
afterHasValues = r.Context().Value(authboss.CTXKeyValues) != nil
return false, nil
})
@ -151,6 +154,12 @@ func TestAuthPostSuccess(t *testing.T) {
if !afterCalled {
t.Error("after should have been called")
}
if !beforeHasValues {
t.Error("before callback should have access to values")
}
if !afterHasValues {
t.Error("after callback should have access to values")
}
})
t.Run("handledBefore", func(t *testing.T) {

View File

@ -20,10 +20,11 @@ const (
// renderer
CTXKeyData contextKey = "data"
// CTXKeyRM is used to flag the remember me module to actually do the
// remembering, since this is a per-user operation, authentication modules
// need to supply this key if they wish to allow users to be remembered.
CTXKeyRM contextKey = "rm"
// CTXKeyValues is to pass the data submitted from API request or form
// along in the context in case modules need it. The only module that needs
// user information currently is remember so only auth/oauth2 are currently
// going to use this.
CTXKeyValues contextKey = "values"
)
func (c contextKey) String() string {

View File

@ -421,6 +421,7 @@ type Values struct {
PID string
Password string
Token string
Remember bool
Errors []error
}
@ -440,6 +441,12 @@ func (v Values) GetToken() string {
return v.Token
}
// GetShouldRemember gets the value that tells
// the remember module if it should remember the user
func (v Values) GetShouldRemember() bool {
return v.Remember
}
// Validate the values
func (v Values) Validate() []error {
return v.Errors

View File

@ -44,10 +44,10 @@ func (r *Remember) Init(ab *authboss.Authboss) error {
// RememberAfterAuth creates a remember token and saves it in the user's cookies.
func (r *Remember) RememberAfterAuth(w http.ResponseWriter, req *http.Request, handled bool) (bool, error) {
rmIntf := req.Context().Value(authboss.CTXKeyRM)
rmIntf := req.Context().Value(authboss.CTXKeyValues)
if rmIntf == nil {
return false, nil
} else if rm, ok := rmIntf.(bool); ok && !rm {
} else if rm, ok := rmIntf.(authboss.RememberValuer); ok && !rm.GetShouldRemember() {
return false, nil
}

View File

@ -59,7 +59,7 @@ func TestRememberAfterAuth(t *testing.T) {
user := &mocks.User{Email: "test@test.com"}
r := mocks.Request("POST")
r = r.WithContext(context.WithValue(r.Context(), authboss.CTXKeyRM, true))
r = r.WithContext(context.WithValue(r.Context(), authboss.CTXKeyValues, mocks.Values{Remember: true}))
r = r.WithContext(context.WithValue(r.Context(), authboss.CTXKeyUser, user))
rec := httptest.NewRecorder()
w := h.ab.NewResponse(rec, r)
@ -101,7 +101,7 @@ func TestRememberAfterAuthSkip(t *testing.T) {
t.Error("expected no tokens to be created")
}
r = r.WithContext(context.WithValue(r.Context(), authboss.CTXKeyRM, false))
r = r.WithContext(context.WithValue(r.Context(), authboss.CTXKeyValues, mocks.Values{Remember: false}))
if handled, err := h.remember.RememberAfterAuth(w, r, false); err != nil {
t.Fatal(err)

View File

@ -65,6 +65,17 @@ type RecoverEndValuer interface {
GetToken() string
}
// RememberValuer allows auth/oauth2 to pass along the remember
// bool from the user to the remember module unobtrusively.
type RememberValuer interface {
// Intentionally omitting validator
// GetShouldRemember is the checkbox or what have you that
// tells the remember module if it should remember that user's
// authentication or not.
GetShouldRemember() bool
}
// ArbitraryValuer provides the "rest" of the fields
// that aren't strictly needed for anything in particular,
// address, secondary e-mail, etc.