// TestInvalidWebTokens tests create an invalid web token and tests it fails. func TestInvalidWebTokens(t *testing.T) { tests.ResetLog() defer tests.DisplayLog() db, err := db.NewMGO(tests.Context, tests.TestSession) if err != nil { t.Fatalf("\t%s\tShould be able to get a Mongo session : %v", tests.Failed, err) } defer db.CloseMGO(tests.Context) tokens := []string{ "", "6dcda2da-92c3-11e5-8994-feff819cdc9f", "OGY4OGI3YWQtZjc5Ny00ODI1LWI0MmUtMjIwZTY5ZDQxYjMzOmFKT2U1b0pFZlZ4cWUrR0JONEl0WlhmQTY0K3JsN2VGcmM2MVNQMkV1WVE9", } t.Log("Given the need to validate bad web tokens don't validate.") { for _, token := range tokens { t.Logf("\tWhen using token [%s]", token) { if _, err := auth.ValidateWebToken(tests.Context, db, token); err == nil { t.Errorf("\t%s\tShould Not be able to validate the web token : %v", tests.Failed, err) } else { t.Logf("\t%s\tShould Not be able to validate the web token.", tests.Success) } } } } }
// Auth handles token authentication. func Auth(h app.Handler) app.Handler { // Check if authentication is turned off. on, err := cfg.Bool(cfgAuth) if err == nil && !on { return func(c *app.Context) error { log.Dev(c.SessionID, "Auth", "******> Authentication Off") return h(c) } } // Turn authentication on. return func(c *app.Context) error { token := c.Request.Header.Get("Authorization") log.Dev(c.SessionID, "Auth", "Started : Token[%s]", token) if len(token) < 5 || token[0:5] != "Basic" { log.Error(c.SessionID, "Auth", app.ErrNotAuthorized, "Validating token") return app.ErrNotAuthorized } var err error if c.User, err = auth.ValidateWebToken(c.SessionID, c.DB, token[6:]); err != nil { log.Error(c.SessionID, "Auth", err, "Validating token") return app.ErrNotAuthorized } log.Dev(c.SessionID, "Auth", "Completed") return h(c) } }
// TestExpiredWebToken tests create a web token and tests when it expires. func TestExpiredWebToken(t *testing.T) { tests.ResetLog() defer tests.DisplayLog() db, err := db.NewMGO(tests.Context, tests.TestSession) if err != nil { t.Fatalf("\t%s\tShould be able to get a Mongo session : %v", tests.Failed, err) } defer db.CloseMGO(tests.Context) var publicID string defer func() { if err := removeUser(db, publicID); err != nil { t.Fatalf("\t%s\tShould be able to remove the test user : %v", tests.Failed, err) } t.Logf("\t%s\tShould be able to remove the test user.", tests.Success) }() t.Log("Given the need to validate web tokens expire.") { t.Log("\tWhen using a new user.") { u1, err := auth.NewUser(auth.NUser{ Status: auth.StatusActive, FullName: "Test Kennedy", Email: "*****@*****.**", Password: "******", }) if err != nil { t.Fatalf("\t%s\tShould be able to build a new user : %v", tests.Failed, err) } t.Logf("\t%s\tShould be able to build a new user.", tests.Success) if err := auth.CreateUser(tests.Context, db, u1); err != nil { t.Fatalf("\t%s\tShould be able to create a user : %v", tests.Failed, err) } t.Logf("\t%s\tShould be able to create a user.", tests.Success) // We need to do this so we can clean up after. publicID = u1.PublicID webTok, err := auth.CreateWebToken(tests.Context, db, u1, 1*time.Millisecond) if err != nil { t.Fatalf("\t%s\tShould be able to create a web token : %v", tests.Failed, err) } t.Logf("\t%s\tShould be able to create a web token.", tests.Success) if _, err := auth.ValidateWebToken(tests.Context, db, webTok); err == nil { t.Fatalf("\t%s\tShould Not be able to validate the web token : %v", tests.Failed, err) } t.Logf("\t%s\tShould Not be able to validate the web token.", tests.Success) } } }
// TestCreateWebToken tests create a web token and a pairing session. func TestCreateWebToken(t *testing.T) { tests.ResetLog() defer tests.DisplayLog() db, err := db.NewMGO(tests.Context, tests.TestSession) if err != nil { t.Fatalf("\t%s\tShould be able to get a Mongo session : %v", tests.Failed, err) } defer db.CloseMGO(tests.Context) var publicID string defer func() { if err := removeUser(db, publicID); err != nil { t.Fatalf("\t%s\tShould be able to remove the test user : %v", tests.Failed, err) } t.Logf("\t%s\tShould be able to remove the test user.", tests.Success) }() t.Log("Given the need to create a web token.") { t.Log("\tWhen using a new user.") { u1, err := auth.NewUser(auth.NUser{ Status: auth.StatusActive, FullName: "Test Kennedy", Email: "*****@*****.**", Password: "******", }) if err != nil { t.Fatalf("\t%s\tShould be able to build a new user : %v", tests.Failed, err) } t.Logf("\t%s\tShould be able to build a new user.", tests.Success) if err := auth.CreateUser(tests.Context, db, u1); err != nil { t.Fatalf("\t%s\tShould be able to create a user : %v", tests.Failed, err) } t.Logf("\t%s\tShould be able to create a user.", tests.Success) // We need to do this so we can clean up after. publicID = u1.PublicID webTok, err := auth.CreateWebToken(tests.Context, db, u1, time.Second) if err != nil { t.Fatalf("\t%s\tShould be able to create a web token : %v", tests.Failed, err) } t.Logf("\t%s\tShould be able to create a web token.", tests.Success) sId, _, err := auth.DecodeWebToken(tests.Context, webTok) if err != nil { t.Fatalf("\t%s\tShould be able to decode the web token : %v", tests.Failed, err) } t.Logf("\t%s\tShould be able to decode the web token.", tests.Success) s2, err := session.GetBySessionID(tests.Context, db, sId) if err != nil { t.Fatalf("\t%s\tShould be able to retrieve the session : %v", tests.Failed, err) } t.Logf("\t%s\tShould be able to retrieve the session.", tests.Success) u2, err := auth.GetUserByPublicID(tests.Context, db, u1.PublicID, true) if err != nil { t.Fatalf("\t%s\tShould be able to retrieve the user by PublicID : %v", tests.Failed, err) } t.Logf("\t%s\tShould be able to retrieve the user by PublicID.", tests.Success) if u2.PublicID != s2.PublicID { t.Fatalf("\t%s\tShould have the right session for user.", tests.Failed) t.Log(u2.PublicID) t.Log(s2.PublicID) } t.Logf("\t%s\tShould have the right session for user.", tests.Success) webTok2, err := u2.WebToken(sId) if err != nil { t.Fatalf("\t%s\tShould be able to create a new web token : %v", tests.Failed, err) } t.Logf("\t%s\tShould be able to create a web new token.", tests.Success) if webTok != webTok2 { t.Log(webTok) t.Log(webTok2) t.Fatalf("\t%s\tShould be able to create the same web token.", tests.Failed) } t.Logf("\t%s\tShould be able to create the same web token.", tests.Success) u3, err := auth.ValidateWebToken(tests.Context, db, webTok2) if err != nil { t.Fatalf("\t%s\tShould be able to validate the new web token : %v", tests.Failed, err) } t.Logf("\t%s\tShould be able to validate the new web token.", tests.Success) if u1.PublicID != u3.PublicID { t.Log(u1.PublicID) t.Log(u3.PublicID) t.Fatalf("\t%s\tShould have the right user for the token.", tests.Failed) } t.Logf("\t%s\tShould have the right user for the token.", tests.Success) webTok3, err := auth.GetUserWebToken(tests.Context, db, u2.PublicID) if err != nil { t.Fatalf("\t%s\tShould be able to get the web token : %v", tests.Failed, err) } t.Logf("\t%s\tShould be able to get the web token.", tests.Success) if webTok3 != webTok2 { t.Log(webTok3) t.Log(webTok2) t.Fatalf("\t%s\tShould match existing tokens.", tests.Failed) } t.Logf("\t%s\tShould match existing tokens.", tests.Success) } } }
// TestUpdateUserPassword tests we can update user password. func TestUpdateUserPassword(t *testing.T) { tests.ResetLog() defer tests.DisplayLog() db, err := db.NewMGO(tests.Context, tests.TestSession) if err != nil { t.Fatalf("\t%s\tShould be able to get a Mongo session : %v", tests.Failed, err) } defer db.CloseMGO(tests.Context) var publicID string defer func() { if err := removeUser(db, publicID); err != nil { t.Fatalf("\t%s\tShould be able to remove the test user : %v", tests.Failed, err) } t.Logf("\t%s\tShould be able to remove the test user.", tests.Success) }() t.Log("Given the need to update a user.") { t.Log("\tWhen using an existing user.") { u1, err := auth.NewUser(auth.NUser{ Status: auth.StatusActive, FullName: "Test Kennedy", Email: "*****@*****.**", Password: "******", }) if err != nil { t.Fatalf("\t%s\tShould be able to build a new user : %v", tests.Failed, err) } t.Logf("\t%s\tShould be able to build a new user.", tests.Success) if err := auth.CreateUser(tests.Context, db, u1); err != nil { t.Fatalf("\t%s\tShould be able to create a user : %v", tests.Failed, err) } t.Logf("\t%s\tShould be able to create a user.", tests.Success) // We need to do this so we can clean up after. publicID = u1.PublicID webTok, err := auth.CreateWebToken(tests.Context, db, u1, 5*time.Second) if err != nil { t.Fatalf("\t%s\tShould be able to create a web token : %v", tests.Failed, err) } t.Logf("\t%s\tShould be able to create a web token.", tests.Success) if err := auth.UpdateUserPassword(tests.Context, db, u1, "_Password567"); err != nil { t.Fatalf("\t%s\tShould be able to update a user : %v", tests.Failed, err) } t.Logf("\t%s\tShould be able to update a user.", tests.Success) if _, err := auth.ValidateWebToken(tests.Context, db, webTok); err == nil { t.Fatalf("\t%s\tShould Not be able to validate the org web token : %v", tests.Failed, err) } t.Logf("\t%s\tShould Not be able to validate the new org token.", tests.Success) u2, err := auth.GetUserByPublicID(tests.Context, db, u1.PublicID, true) if err != nil { t.Fatalf("\t%s\tShould be able to retrieve the user by PublicID : %v", tests.Failed, err) } t.Logf("\t%s\tShould be able to retrieve the user by PublicID.", tests.Success) webTok2, err := auth.CreateWebToken(tests.Context, db, u2, 5*time.Second) if err != nil { t.Fatalf("\t%s\tShould be able to create a new web token : %v", tests.Failed, err) } t.Logf("\t%s\tShould be able to create a new web token.", tests.Success) if webTok == webTok2 { t.Fatalf("\t%s\tShould have different web tokens after the update.", tests.Failed) } t.Logf("\t%s\tShould have different web tokens after the update.", tests.Success) u3, err := auth.ValidateWebToken(tests.Context, db, webTok2) if err != nil { t.Fatalf("\t%s\tShould be able to validate the new web token : %v", tests.Failed, err) } t.Logf("\t%s\tShould be able to validate the new web token.", tests.Success) if u1.PublicID != u3.PublicID { t.Log(u2.PublicID) t.Log(u3.PublicID) t.Fatalf("\t%s\tShould have the right user for the new token.", tests.Failed) } t.Logf("\t%s\tShould have the right user for the new token.", tests.Success) } } }
// TestNoSession tests when a nil session is used. func TestNoSession(t *testing.T) { tests.ResetLog() defer tests.DisplayLog() t.Log("Given the need to test calls with a bad session.") { t.Log("\tWhen using a nil session") { u1, err := auth.NewUser(auth.NUser{ Status: auth.StatusActive, FullName: "Test Kennedy", Email: "*****@*****.**", Password: "******", }) if err != nil { t.Fatalf("\t%s\tShould be able to build a new user : %v", tests.Failed, err) } t.Logf("\t%s\tShould be able to build a new user.", tests.Success) if err := auth.CreateUser(tests.Context, nil, u1); err == nil { t.Errorf("\t%s\tShould Not be able to create a user.", tests.Failed) } else { t.Logf("\t%s\tShould Not be able to create a user.", tests.Success) } if _, err := auth.CreateWebToken(tests.Context, nil, u1, time.Second); err == nil { t.Errorf("\t%s\tShould Not be able to create a web token.", tests.Failed) } else { t.Logf("\t%s\tShould Not be able to create a web token.", tests.Success) } webTok := "OGY4OGI3YWQtZjc5Ny00ODI1LWI0MmUtMjIwZTY5ZDQxYjMzOmFKT2U1b0pFZlZ4cWUrR0JONEl0WlhmQTY0K3JsN2VGcmM2MVNQMkV1WVE9" if _, err := auth.ValidateWebToken(tests.Context, nil, webTok); err == nil { t.Errorf("\t%s\tShould Not be able to validate a web token.", tests.Failed) } else { t.Logf("\t%s\tShould Not be able to validate a web token.", tests.Success) } if _, err := auth.GetUserByPublicID(tests.Context, nil, "6dcda2da-92c3-11e5-8994-feff819cdc9f", true); err == nil { t.Errorf("\t%s\tShould Not be able to get a user by PublicID.", tests.Failed) } else { t.Logf("\t%s\tShould Not be able to get a user by PublicID.", tests.Success) } if _, err := auth.GetUserByEmail(tests.Context, nil, "*****@*****.**", true); err == nil { t.Errorf("\t%s\tShould Not be able to get a user by Email.", tests.Failed) } else { t.Logf("\t%s\tShould Not be able to get a user by Email.", tests.Success) } uu := auth.UpdUser{ PublicID: "6dcda2da-92c3-11e5-8994-feff819cdc9f", Status: auth.StatusActive, FullName: "Update Kennedy", Email: "*****@*****.**", } if err := auth.UpdateUser(tests.Context, nil, uu); err == nil { t.Errorf("\t%s\tShould Not be able to update a user.", tests.Failed) } else { t.Logf("\t%s\tShould Not be able to update a user.", tests.Success) } if err := auth.UpdateUserPassword(tests.Context, nil, u1, "password890"); err == nil { t.Errorf("\t%s\tShould Not be able to update a user pasword.", tests.Failed) } else { t.Logf("\t%s\tShould Not be able to update a user password.", tests.Success) } if err := auth.UpdateUserStatus(tests.Context, nil, "6dcda2da-92c3-11e5-8994-feff819cdc9f", auth.StatusDisabled); err == nil { t.Errorf("\t%s\tShould Not be able to disable a user.", tests.Failed) } else { t.Logf("\t%s\tShould Not be able to disable a user.", tests.Success) } if _, err := auth.LoginUser(tests.Context, nil, "*****@*****.**", "_pass"); err == nil { t.Errorf("\t%s\tShould Not be able to login a user.", tests.Failed) } else { t.Logf("\t%s\tShould Not be able to login a user.", tests.Success) } if _, err := auth.GetUserWebToken(tests.Context, nil, "6dcda2da-92c3-11e5-8994-feff819cdc9f"); err == nil { t.Errorf("\t%s\tShould Not be able to get user web token.", tests.Failed) } else { t.Logf("\t%s\tShould Not be able to get user web token.", tests.Success) } } } }
// TestInvalidWebTokenUpdateEmail tests a token becomes invalid after an update. func TestInvalidWebTokenUpdateEmail(t *testing.T) { tests.ResetLog() defer tests.DisplayLog() db := db.NewMGO() defer db.CloseMGO() var publicID string defer func() { if err := removeUser(db, publicID); err != nil { t.Fatalf("\t%s\tShould be able to remove the test user : %v", tests.Failed, err) } t.Logf("\t%s\tShould be able to remove the test user.", tests.Success) }() t.Log("Given the need to validate web tokens don't work after user update.") { t.Log("\tWhen using a new user.") { u1, err := auth.NewUser(auth.NUser{ Status: auth.StatusActive, FullName: "Test Kennedy", Email: "*****@*****.**", Password: "******", }) if err != nil { t.Fatalf("\t%s\tShould be able to build a new user : %v", tests.Failed, err) } t.Logf("\t%s\tShould be able to build a new user.", tests.Success) if err := auth.CreateUser(tests.Context, db, u1); err != nil { t.Fatalf("\t%s\tShould be able to create a user : %v", tests.Failed, err) } t.Logf("\t%s\tShould be able to create a user.", tests.Success) // We need to do this so we can clean up after. publicID = u1.PublicID webTok, err := auth.CreateWebToken(tests.Context, db, u1, 5*time.Second) if err != nil { t.Fatalf("\t%s\tShould be able to create a web token : %v", tests.Failed, err) } t.Logf("\t%s\tShould be able to create a web token.", tests.Success) if _, err := auth.ValidateWebToken(tests.Context, db, webTok); err != nil { t.Fatalf("\t%s\tShould be able to validate the web token : %v", tests.Failed, err) } t.Logf("\t%s\tShould be able to validate the web token.", tests.Success) uu := auth.UpdUser{ PublicID: publicID, Status: auth.StatusActive, FullName: "Update Kennedy", Email: "*****@*****.**", } if err := auth.UpdateUser(tests.Context, db, uu); err != nil { t.Fatalf("\t%s\tShould be able to update a user : %v", tests.Failed, err) } t.Logf("\t%s\tShould be able to update a user.", tests.Success) if _, err := auth.ValidateWebToken(tests.Context, db, webTok); err == nil { t.Fatalf("\t%s\tShould Not be able to validate the org web token.", tests.Failed) } t.Logf("\t%s\tShould Not be able to validate the org web token.", tests.Success) } } }