func (um *UserManager) ResetPassword(id string, tr *ResetTokenRequest) error { //Read the user user := User{} userDb := Connection.SelectDB(UserDbName, AdminAuth) rev, err := userDb.Read(UserPrefix+id, &user, nil) if err != nil { return err } //Check the token tok := user.PassResetToken.Token expireTime := user.PassResetToken.Expires nowTime := time.Now().UTC() if tok != tr.Token || nowTime.After(expireTime) { return &couchdb.Error{ StatusCode: 400, Reason: "This token is invalid or expired.", } } cpr := ChangePasswordRequest{NewPassword: tr.NewPassword} rev, err = um.ChangePassword(id, rev, &cpr, services.GetAdminUser()) if err != nil { return err } //Now, expire the token user.PassResetToken.Token = "" user.PassResetToken.Expires = nowTime _, err = um.Update(id, rev, &user, services.GetAdminUser()) return err }
//Request a password reset (forgot password, etc). func (um *UserManager) RequestPasswordReset(id string) error { //Read the user user := User{} userDb := Connection.SelectDB(UserDbName, AdminAuth) rev, err := userDb.Read(UserPrefix+id, &user, nil) if err != nil { return err } //Generate a token tok := util.GenToken() //Set token expiration time nowTime := time.Now().UTC() //Tokens are good for 4 hours hours := time.Duration(4) * time.Hour expireTime := nowTime.Add(hours) user.PassResetToken.Token = tok user.PassResetToken.Expires = expireTime //Now save the user log.Println("Saving reset token to user document") rev, err = um.Update(id, rev, &user, services.GetAdminUser()) if err != nil { return err } //Now we need to send an email to the user containing our token notifEndpoint, err := registry.GetServiceLocation("notifications") if err != nil { return err } nr := NotificationRequest{ To: user.Public.Contact.Email, Subject: "Reset Password Request", Data: map[string]string{ "user": user.Public.FirstName, "uri": "/reset_password?user="******"&token=" + tok, }, } nrJson, _, err := util.EncodeJsonData(&nr) if err != nil { return err } //Assemble the request reqUrl := notifEndpoint + "/api/v1/notifications/reset_password/send" client := &http.Client{} request, err := http.NewRequest("POST", reqUrl, nrJson) if err != nil { return err } request.Header.Add("Content-Type", "application/json") resp, err := client.Do(request) if err != nil { return err } defer resp.Body.Close() return nil }
//Register a new user func (um *UserManager) Register(newUser *User) (string, error) { adminUser := services.GetAdminUser() return um.Create(newUser, adminUser) }