1
0
mirror of https://github.com/volatiletech/authboss.git synced 2025-01-10 04:17:59 +02:00
authboss/lock/lock_test.go
Aaron f0552cd8c6 Add lock tests.
- Fix some logic errors in lock module.
- Add some more power to the mocks.
2015-01-24 22:19:22 -08:00

226 lines
5.6 KiB
Go

package lock
import (
"io/ioutil"
"testing"
"time"
"gopkg.in/authboss.v0"
"gopkg.in/authboss.v0/internal/mocks"
)
func TestStorage(t *testing.T) {
storage := L.Storage()
if _, ok := storage[UserAttemptNumber]; !ok {
t.Error("Expected attempt number storage option.")
}
if _, ok := storage[UserAttemptTime]; !ok {
t.Error("Expected attempt number time option.")
}
}
func setup(keyValuePairs interface{}) {
storer := mocks.NewMockStorer()
L.storer = storer
_ = make(mocks.MockClientStorer)
_ = make(mocks.MockClientStorer)
}
func TestBeforeAuth(t *testing.T) {
ctx := authboss.NewContext()
if nil != L.BeforeAuth(ctx) {
t.Error("Expected it to break early.")
}
if err := L.BeforeAuth(ctx); err != nil {
t.Error(err)
}
ctx.User = authboss.Attributes{"locked": true}
if err := L.BeforeAuth(ctx); err != ErrLocked {
t.Error("Expected an ErrLocked:", err)
}
}
func TestAfterAuth(t *testing.T) {
lock := Lock{}
lock.logger = ioutil.Discard
ctx := authboss.NewContext()
lock.AfterAuth(ctx)
if _, ok := ctx.User[UserAttemptNumber]; ok {
t.Error("Expected nothing to be set, missing user.")
}
ctx.User = map[string]interface{}{"otherattribute": "somevalue"}
lock.AfterAuth(ctx)
if _, ok := ctx.User[UserAttemptNumber]; ok {
t.Error("Expected username not present to stop this assignment.")
}
ctx.User["username"] = 5
lock.AfterAuth(ctx)
if _, ok := ctx.User[UserAttemptNumber]; ok {
t.Error("Expected username wrong type stop this assignment.")
}
storer := mocks.NewMockStorer()
lock.storer = storer
ctx.User["username"] = "username"
lock.AfterAuth(ctx)
if storer.Users["username"][UserAttemptNumber].(int) != 0 {
t.Error("UserAttemptNumber set incorrectly.")
}
if _, ok := storer.Users["username"][UserAttemptTime].(time.Time); !ok {
t.Error("UserAttemptTime not set.")
}
}
func TestAfterAuthFail_Lock(t *testing.T) {
var old, current time.Time
var ok bool
ctx := authboss.NewContext()
storer := mocks.NewMockStorer()
lock := Lock{}
lock.logger = ioutil.Discard
lock.storer = storer
lock.window = 30 * time.Minute
lock.attempts = 3
ctx.User = map[string]interface{}{"username": "username"}
old = time.Now().UTC().Add(-1 * time.Hour)
for i := 0; i < 3; i++ {
if lockedIntf, ok := storer.Users["username"][UserLocked]; ok && lockedIntf.(bool) {
t.Errorf("%d: User should not be locked.", i)
}
lock.AfterAuthFail(ctx)
if val := storer.Users["username"][UserAttemptNumber].(int); val != i+1 {
t.Errorf("%d: UserAttemptNumber set incorrectly: %v", i, val)
}
if current, ok = storer.Users["username"][UserAttemptTime].(time.Time); !ok || old.After(current) {
t.Error("%d: UserAttemptTime not set correctly: %v", i, current)
}
current = old
}
if !storer.Users["username"][UserLocked].(bool) {
t.Error("User should be locked.")
}
if val := storer.Users["username"][UserAttemptNumber].(int); val != 3 {
t.Error("UserAttemptNumber set incorrectly:", val)
}
if _, ok = storer.Users["username"][UserAttemptTime].(time.Time); !ok {
t.Error("UserAttemptTime not set correctly.")
}
}
func TestAfterAuthFail_Reset(t *testing.T) {
var old, current time.Time
var ok bool
ctx := authboss.NewContext()
storer := mocks.NewMockStorer()
lock := Lock{}
lock.window = 30 * time.Minute
lock.logger = ioutil.Discard
lock.storer = storer
old = time.Now().UTC().Add(-time.Hour)
ctx.User = map[string]interface{}{
"username": "username",
UserAttemptNumber: 2,
UserAttemptTime: old,
UserLocked: false,
}
lock.AfterAuthFail(ctx)
if val := storer.Users["username"][UserAttemptNumber].(int); val != 0 {
t.Error("UserAttemptNumber set incorrectly:", val)
}
if current, ok = storer.Users["username"][UserAttemptTime].(time.Time); !ok || current.Before(old) {
t.Error("UserAttemptTime not set correctly.")
}
if locked := storer.Users["username"][UserLocked].(bool); locked {
t.Error("UserLocked not set correctly:", locked)
}
}
func TestAfterAuthFail_Errors(t *testing.T) {
lock := Lock{}
lock.logger = ioutil.Discard
ctx := authboss.NewContext()
lock.AfterAuthFail(ctx)
if _, ok := ctx.User[UserAttemptNumber]; ok {
t.Error("Expected nothing to be set, missing user.")
}
ctx.User = map[string]interface{}{"otherattribute": "somevalue"}
lock.AfterAuthFail(ctx)
if _, ok := ctx.User[UserAttemptNumber]; ok {
t.Error("Expected username not present to stop this assignment.")
}
ctx.User["username"] = 5
lock.AfterAuthFail(ctx)
if _, ok := ctx.User[UserAttemptNumber]; ok {
t.Error("Expected username wrong type stop this assignment.")
}
}
func TestLock(t *testing.T) {
storer := mocks.NewMockStorer()
lock := Lock{}
storer.Users["username"] = map[string]interface{}{
"username": "username",
"password": "password",
}
err := lock.Lock("username", storer)
if err != nil {
t.Error(err)
}
if locked := storer.Users["username"][UserLocked].(bool); !locked {
t.Error("User should be locked.")
}
}
func TestUnlock(t *testing.T) {
storer := mocks.NewMockStorer()
lock := Lock{}
lock.window = 1 * time.Hour
storer.Users["username"] = map[string]interface{}{
"username": "username",
"password": "password",
"locked": true,
}
err := lock.Unlock("username", storer)
if err != nil {
t.Error(err)
}
attemptTime := storer.Users["username"][UserAttemptTime].(time.Time)
if attemptTime.After(time.Now().UTC().Add(-lock.window)) {
t.Error("UserLocked not set correctly:", attemptTime)
}
if number := storer.Users["username"][UserAttemptNumber].(int); number != 0 {
t.Error("UserLocked not set correctly:", number)
}
if locked := storer.Users["username"][UserLocked].(bool); locked {
t.Error("User should not be locked.")
}
}