func TestGenerateAndValidateClaim(t *testing.T) { certs, err := GenerateTestCerts() if assert.NoError(t, err) { claim, err := GenerateClaim(certs, &models.User{ ID: models.String("123"), Login: models.String("wolfeidau"), Email: models.String("*****@*****.**"), Name: models.String("Mark Wolfe"), Password: models.String("LkSquwzxdgzSTqqc7Rku5NF8/uR7TBFO1IRF1Yj2c0sM4HEVGgp0bJadWtRAaINP"), //Somewh3r3 there is a cow! }) if assert.NoError(t, err) { usr, err := ValidateClaim(certs, claim) if assert.NoError(t, err) { assert.NotNil(t, usr) assert.Equal(t, "123", models.StringValue(usr.ID)) assert.Equal(t, "wolfeidau", models.StringValue(usr.Login)) assert.Equal(t, "*****@*****.**", models.StringValue(usr.Email)) } } } }
func NewUser() *models.User { return &models.User{ ID: models.String("123"), Login: models.String("wolfeidau"), Email: models.String("*****@*****.**"), Name: models.String("Mark Wolfe"), Password: models.String("LkSquwzxdgzSTqqc7Rku5NF8/uR7TBFO1IRF1Yj2c0sM4HEVGgp0bJadWtRAaINP"), //Somewh3r3 there is a cow! } }
// GetPasswordByLogin retrieve the users password for authentication func (usl *UserStoreLocal) GetPasswordByLogin(login string) (string, error) { for _, v := range usl.users { if reflect.DeepEqual(v.Login, models.String(login)) { return models.StringValue(v.Password), nil } } return "", ErrUserNotFound }
func (usl *UserStoreLocal) loginExists(login string) bool { for _, v := range usl.users { if reflect.DeepEqual(v.Login, models.String(login)) { return true } } return false }
// GetByLogin lookup a user by their login func (usl *UserStoreLocal) GetByLogin(login string) (*models.User, error) { for _, v := range usl.users { if reflect.DeepEqual(v.Login, models.String(login)) { return v, nil } } return nil, ErrUserNotFound }
func TestCreateUserRethinkDB(t *testing.T) { _, userStore, _, err := createUserStoreAndSession() if assert.NoError(t, err, "connecting to rethinkdb") { usr, err := userStore.Create(&models.User{ Email: models.String("*****@*****.**"), Login: models.String("wolfeidau"), Name: models.String("Mark Wolfe"), Password: models.String("LkSquwzxdgzSTqqc7Rku5NF8/uR7TBFO1IRF1Yj2c0sM4HEVGgp0bJadWtRAaINP"), }) if assert.Nil(t, err) { assert.NotNil(t, usr.ID) } } }
func extractKey(key string, claims jwt.Claims) *string { if claims.Has(key) { val := claims.Get(key) if s, ok := val.(string); ok { return models.String(s) } } return nil }
// Create create the user in RethinkDB func (us *UserStoreRethinkDB) Create(user *models.User) (*models.User, error) { resp, err := r.DB(DBName).Table(TableName).Insert(user).RunWrite(us.session) if err != nil { return nil, err } user.ID = models.String(resp.GeneratedKeys[0]) return user, nil }
func (ur UserResource) createUser(req *restful.Request, resp *restful.Response) { usr := new(models.User) err := req.ReadEntity(usr) if err != nil { resp.WriteHeaderAndEntity(http.StatusInternalServerError, errorMsg("Server error.")) return } allErrs := validation.ValidateUserRegister(usr) if len(allErrs) != 0 { resp.WriteHeaderAndEntity(http.StatusBadRequest, validationErrors("validation failed", allErrs)) return } exists, err := ur.store.Exists(models.StringValue(usr.Login)) if err != nil { resp.WriteHeaderAndEntity(http.StatusInternalServerError, errorMsg("Server error.")) return } if exists { resp.WriteHeaderAndEntity(http.StatusConflict, errorMsg("User already exists.")) return } // hash the password pass := models.StringValue(usr.Password) pass, err = util.HashPassword(pass) if err != nil { resp.WriteHeaderAndEntity(http.StatusInternalServerError, errorMsg("Server error.")) return } usr.Password = models.String(pass) nusr, err := ur.store.Create(usr) if err != nil { resp.WriteHeaderAndEntity(http.StatusInternalServerError, errorMsg("Server error.")) return } nusr.Password = nil resp.WriteHeaderAndEntity(http.StatusCreated, nusr) }
func TestValidateUpdateUser(t *testing.T) { testCases := []struct { newUser *models.User oldUser *models.User expected field.ErrorList }{ { newUser: models.NewUser("123", "wolfeidau", "*****@*****.**", "Mark Wolfe"), oldUser: models.NewUser("123", "wolfeidau", "*****@*****.**", "Mark Wolfe"), expected: field.ErrorList{}, }, { newUser: &models.User{ Name: models.String("Mark Wolf"), }, oldUser: models.NewUser("123", "wolfeidau", "*****@*****.**", "Mark Wolfe"), expected: field.ErrorList{}, }, { newUser: &models.User{ Name: models.String("Mark Wolf"), Password: models.String("Somewh3r3 there is a cow!"), }, oldUser: models.NewUser("123", "wolfeidau", "*****@*****.**", "Mark Wolfe"), expected: field.ErrorList{ &field.Error{Type: field.ErrorTypeForbidden, Field: field.NewPath("User", "Password").String(), BadValue: "", Detail: "User updates must not supply Password"}, }, }, } for _, testCase := range testCases { errList := ValidateUserUpdate(testCase.newUser, testCase.oldUser) if !reflect.DeepEqual(errList, testCase.expected) { t.Errorf("expected\n%s\ngot\n%s\n", toJSON(testCase.expected), toJSON(errList)) } } }
func TestUpdateUserRethinkDB(t *testing.T) { _, userStore, userID, err := createUserStoreAndSession() if assert.NoError(t, err, "connecting to rethinkdb") { err = userStore.Update(&models.User{ ID: models.String(userID), Name: models.String("Mark Wolfy"), }) assert.NoError(t, err, "updating user in rethinkdb") err = userStore.Update(&models.User{ Name: models.String("Mark Wolfy"), }) if assert.Error(t, err) { assert.Equal(t, err, ErrUserNotFound) } } }
func (ur UserResource) updatePassword(req *restful.Request, resp *restful.Response) { userid, ok := req.Attribute("user_id").(string) if !ok { resp.WriteHeaderAndEntity(http.StatusInternalServerError, errorMsg("Server error.")) return } cusr, err := ur.store.GetByID(userid) if err != nil { resp.WriteHeaderAndEntity(http.StatusNotFound, errorMsg("User not found.")) return } data := make(map[string]string) err = req.ReadEntity(&data) if err != nil { resp.WriteHeaderAndEntity(http.StatusInternalServerError, errorMsg("Server error.")) return } password, ok := data["password"] if !ok { resp.WriteHeaderAndEntity(http.StatusBadRequest, errorMsg("bad request missing password")) return } // hash the password pass, err := util.HashPassword(password) if err != nil { resp.WriteHeaderAndEntity(http.StatusInternalServerError, errorMsg("Server error.")) return } cusr.Password = models.String(pass) err = ur.store.Update(cusr) if err != nil { resp.WriteHeaderAndEntity(http.StatusInternalServerError, errorMsg("Server error.")) return } resp.WriteHeader(http.StatusOK) }
func (ur UserResource) updateUser(req *restful.Request, resp *restful.Response) { userid, ok := req.Attribute("user_id").(string) if !ok { resp.WriteHeaderAndEntity(http.StatusInternalServerError, errorMsg("Server error.")) return } cusr, err := ur.store.GetByID(userid) if err != nil { resp.WriteHeaderAndEntity(http.StatusNotFound, errorMsg("User not found.")) return } usr := new(models.User) err = req.ReadEntity(usr) if err != nil { resp.WriteHeaderAndEntity(http.StatusInternalServerError, errorMsg("Server error.")) return } // ensure the userid is trusted usr.ID = models.String(userid) allErrs := validation.ValidateUserUpdate(usr, cusr) if len(allErrs) != 0 { resp.WriteHeaderAndEntity(http.StatusBadRequest, validationErrors("validation failed", allErrs)) return } err = ur.store.Update(usr) if err != nil { resp.WriteHeaderAndEntity(http.StatusInternalServerError, errorMsg("Server error.")) return } usr.Password = nil resp.WriteEntity(usr) }
// Create create a new user in the system with the given information func (usl *UserStoreLocal) Create(user *models.User) (*models.User, error) { var id string // check for unique login if usl.loginExists(models.StringValue(user.Login)) { return nil, ErrUserAlreadyExists } if user.ID == nil { id = newID() user.ID = models.String(id) } else { id = models.StringValue(user.ID) } usl.users[id] = user return user, nil }
func TestValidateUserRegister(t *testing.T) { testCases := []struct { newUser *models.User expected field.ErrorList }{ { newUser: &models.User{ Login: models.String("wolfeidau"), Email: models.String("*****@*****.**"), Name: models.String("Mark Wolf"), Password: models.String("Somewh3r3 there is a cow!"), }, expected: field.ErrorList{}, }, { newUser: &models.User{ ID: models.String("123"), Login: models.String("wolfeidau"), Email: models.String("*****@*****.**"), Name: models.String("Mark Wolf"), Password: models.String("Somewh3r3 there is a cow!"), }, expected: field.ErrorList{ &field.Error{Type: field.ErrorTypeForbidden, Field: field.NewPath("User", "ID").String(), BadValue: "", Detail: "User updates must not supply ID"}, }, }, { newUser: &models.User{ ID: models.String("123"), Name: models.String("Mark Wolf"), Email: models.String("*****@*****.**"), }, expected: field.ErrorList{ &field.Error{Type: field.ErrorTypeForbidden, Field: field.NewPath("User", "ID").String(), BadValue: "", Detail: "User updates must not supply ID"}, &field.Error{Type: field.ErrorTypeRequired, Field: field.NewPath("User", "Login").String(), BadValue: "", Detail: "User updates must supply Login"}, &field.Error{Type: field.ErrorTypeRequired, Field: field.NewPath("User", "Password").String(), BadValue: "", Detail: "User updates must supply Password"}, &field.Error{Type: field.ErrorTypeInvalid, Field: field.NewPath("User", "Login").String(), BadValue: "", Detail: "User: Login must be between 5 and 255 characters"}, &field.Error{Type: field.ErrorTypeInvalid, Field: field.NewPath("User", "Password").String(), BadValue: "", Detail: "User: Password must be between 5 and 255 characters"}, }, }, } for _, testCase := range testCases { errList := ValidateUserRegister(testCase.newUser) if !reflect.DeepEqual(errList, testCase.expected) { t.Errorf("expected\n%s\ngot\n%s\n", toJSON(testCase.expected), toJSON(errList)) } } }