diff --git a/callbacks_test.go b/callbacks_test.go index 244ee2b..2a87d39 100644 --- a/callbacks_test.go +++ b/callbacks_test.go @@ -1,6 +1,9 @@ package authboss -import "testing" +import ( + "errors" + "testing" +) func TestCallbacks(t *testing.T) { afterCalled := false @@ -36,3 +39,32 @@ func TestCallbacks(t *testing.T) { t.Error("Expected after to be called.") } } + +func TestCallbacksInterrupt(t *testing.T) { + before1 := false + before2 := false + c := NewCallbacks() + + errValue := errors.New("Problem occured.") + + c.Before(EventRegister, func(ctx *Context) error { + before1 = true + return errValue + }) + c.Before(EventRegister, func(ctx *Context) error { + before2 = true + return nil + }) + + err := c.FireBefore(EventRegister, NewContext()) + if err != errValue { + t.Error("Expected an error to come back.") + } + + if !before1 { + t.Error("Before1 should have been called.") + } + if before2 { + t.Error("Before2 should not have been called.") + } +} diff --git a/context.go b/context.go index 70de7cc..c33dce1 100644 --- a/context.go +++ b/context.go @@ -1,5 +1,7 @@ package authboss +import "net/http" + // Context provides context for module operations and callbacks. One obvious // need for context is a request's session store. It is not safe for use by // multiple goroutines. @@ -8,7 +10,9 @@ type Context struct { CookieStorer ClientStorer User Attributes - keyValues map[string]interface{} + postFormValues map[string][]string + formValues map[string][]string + keyValues map[string]interface{} } func NewContext() *Context { @@ -17,6 +21,18 @@ func NewContext() *Context { } } +// ContextFromRequest creates a context from an http request. +func ContextFromRequest(r *http.Request) (*Context, error) { + if err := r.ParseForm(); err != nil { + return nil, err + } + + c := NewContext() + c.formValues = map[string][]string(r.Form) + c.postFormValues = map[string][]string(r.PostForm) + return c, nil +} + // Put an arbitrary key-value into the context. func (c *Context) Put(key string, thing interface{}) { c.keyValues[key] = thing @@ -27,3 +43,24 @@ func (c *Context) Get(key string) (thing interface{}, ok bool) { thing, ok = c.keyValues[key] return thing, ok } + +// FormValue gets a form value from a context created with a request. +func (c *Context) FormValue(key string) ([]string, bool) { + val, ok := c.formValues[key] + return val, ok +} + +// PostFormValue gets a form value from a context created with a request. +func (c *Context) PostFormValue(key string) ([]string, bool) { + val, ok := c.postFormValues[key] + return val, ok +} + +// LoadUser loads the user Attributes if they haven't already been loaded. +func (c *Context) LoadUser(storer Storer) error { + if c.User != nil { + return nil + } + + return nil +} diff --git a/context_test.go b/context_test.go new file mode 100644 index 0000000..854e525 --- /dev/null +++ b/context_test.go @@ -0,0 +1,37 @@ +package authboss + +import ( + "bytes" + "net/http" + "testing" +) + +func TestContext_PutGet(t *testing.T) { + ctx := NewContext() + + ctx.Put("key", "value") + if v, has := ctx.Get("key"); !has || v.(string) != "value" { + t.Error("Not retrieving key values correctly.") + } +} + +func TestContext_Request(t *testing.T) { + req, err := http.NewRequest("POST", "http://localhost?query=string", bytes.NewBufferString("post=form")) + if err != nil { + t.Error("Unexpected Error:", err) + } + req.Header.Set("Content-Type", "application/x-www-form-urlencoded") + + ctx, err := ContextFromRequest(req) + if err != nil { + t.Error("Unexpected Error:", err) + } + + if query, ok := ctx.FormValue("query"); !ok || query[0] != "string" { + t.Error("Form value not getting recorded correctly.") + } + + if post, ok := ctx.PostFormValue("post"); !ok || post[0] != "form" { + t.Error("Postform value not getting recorded correctly.") + } +} diff --git a/module_test.go b/module_test.go index 0d6ce12..74a5b0f 100644 --- a/module_test.go +++ b/module_test.go @@ -44,6 +44,10 @@ func TestRegister(t *testing.T) { if _, ok := modules["testmodule"]; !ok { t.Error("Expected module to be saved.") } + + if !IsLoaded("testmodule") { + t.Error("Expected module to be loaded.") + } } func TestLoadedModules(t *testing.T) { diff --git a/remember/remember.go b/remember/remember.go index 3912021..37608e1 100644 --- a/remember/remember.go +++ b/remember/remember.go @@ -72,12 +72,12 @@ func (r *Remember) AfterAuth(ctx *authboss.Context) { return } - /*if err := ctx.LoadUser(r.storer); err != nil { + if err := ctx.LoadUser(r.storer); err != nil { fmt.Fprintln(r.logger, "remember: Failed to load user:", err) return - }*/ + } - key := ctx.User["Username"].Value.(string) + key := ctx.User["Username"].(string) if _, err := r.New(ctx.CookieStorer, key); err != nil { fmt.Fprintf(r.logger, "Failed to create remember token: %v", err) } diff --git a/storer_test.go b/storer_test.go index dfc23b9..1a2e34e 100644 --- a/storer_test.go +++ b/storer_test.go @@ -12,6 +12,58 @@ func (t testStorer) Create(key string, attr Attributes) error func (t testStorer) Put(key string, attr Attributes) error { return nil } func (t testStorer) Get(key string, attrMeta AttributeMeta) (interface{}, error) { return nil, nil } +func TestAttributes_Names(t *testing.T) { + attr := Attributes{ + "integer": 5, + "string": "string", + "date": time.Now(), + } + names := attr.Names() + + found := map[string]bool{"integer": false, "string": false, "date": false} + for _, n := range names { + found[n] = true + } + + for k, v := range found { + if !v { + t.Error("Could not find:", k) + } + } +} + +func TestAttributeMeta_Names(t *testing.T) { + meta := AttributeMeta{ + "integer": Integer, + "string": String, + "date": DateTime, + } + names := meta.Names() + + found := map[string]bool{"integer": false, "string": false, "date": false} + for _, n := range names { + found[n] = true + } + + for k, v := range found { + if !v { + t.Error("Could not find:", k) + } + } +} + +func TestDataType_String(t *testing.T) { + if Integer.String() != "Integer" { + t.Error("Expected Integer:", Integer) + } + if String.String() != "String" { + t.Error("Expected String:", String) + } + if DateTime.String() != "DateTime" { + t.Error("Expected DateTime:", DateTime) + } +} + func TestAttributes_Bind(t *testing.T) { anInteger := 5 aString := "string" @@ -117,7 +169,7 @@ func TestAttributes_Unbind(t *testing.T) { unexported int }{5, "string", time.Now(), 5, nil, 5} - attr := Unbind(s1) + attr := Unbind(&s1) if len(attr) != 3 { t.Error("Expected three fields, got:", len(attr)) }