Advertisement
Guest User

Password Reset

a guest
Jun 10th, 2016
668
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 6.49 KB | None | 0 0
  1. server.go
  2. ______________________________________________________________________________________
  3.  
  4. // Reset routes
  5. goji.Get("/reset", application.Route(controller, "Reset"))
  6. goji.Post("/reset", application.Route(controller, "ResetPost"))
  7.  
  8.  
  9. views/auth/reset.html
  10. ______________________________________________________________________________________
  11. {{define "auth/reset"}}
  12. <div class="panel panel-default">
  13.     <div class="panel-heading">
  14.         <h4 class="panel-title">Reset password</h4>
  15.     </div>
  16.     <div class="panel-body">
  17.         <form class="form-horizontal" method="post" data-parsley-validate>
  18.         <fieldset>
  19.             {{range .Flash}}
  20.                 <div class="alert alert-danger">{{.}}</div><p>
  21.             {{end}}
  22.             {{range .Success}}
  23.                 <div class="alert alert-success">{{.}}</div><p>
  24.             {{end}}
  25.             <div class="form-group">
  26.                 <label class="col-md-4 control-label" for="email">Email</label>
  27.                 <div class="col-md-6">
  28.                     <input id="email" name="email" type="email" placeholder="Email address" class="form-control input-md" required="" data-parsley-required-message="Please enter your email">
  29.                 </div>
  30.             </div>
  31.             <div class="form-group">
  32.                 <label class="col-md-4 control-label" for=""></label>
  33.                 <div class="col-md-6">
  34.                     <div class="g-recaptcha" data-sitekey=""></div>
  35.                 </div>
  36.             </div>
  37.             <div class="form-group">
  38.                 <label class="col-md-4 control-label" for="reset"></label>
  39.                 <div class="col-md-4">
  40.                     <button id="reset" name="reset" class="btn btn-primary">Reset password</button>
  41.                 </div>
  42.             </div>
  43.         </fieldset>
  44.     <input type="hidden" name="{{.CsrfKey}}" value={{.CsrfToken}}>
  45.         </form>
  46.     </div>
  47. </div>
  48. {{end}}
  49.  
  50.  
  51. models / user.go
  52. ______________________________________________________________________
  53. func ResetPassword(dbMap *gorp.DbMap, id int64, password []byte) (user *User) {
  54.         err := dbMap.SelectOne(&user, "SELECT * FROM Users WHERE UserId = ?", id)
  55.  
  56.         if err != nil {
  57.                 glog.Warningf("Can't get user by id: %v", err)
  58.         }
  59.        
  60.         user.Password = password
  61.  
  62.         _, err = dbMap.Update(user)
  63.  
  64.         if err != nil {
  65.                 glog.Warningf("Couldn't update user: %v", err)
  66.         }
  67.         return
  68. }
  69.  
  70.  
  71. controllers / main.go
  72. ___________________________________________________________________________
  73.  
  74. import (
  75.     "net/smtp"
  76.     "net/mail"
  77.     "encoding/base64"
  78. )
  79.  
  80. // Reset route
  81. func (controller *MainController) Reset(c web.C, r *http.Request) (string, int) {
  82.     t := controller.GetTemplate(c)
  83.     session := controller.GetSession(c)
  84.  
  85.     c.Env["IsReset"] = true
  86.     c.Env["Flash"] = session.Flashes("reset")
  87.     c.Env["Success"] = session.Flashes("reset-success")
  88.     c.Env["RecaptchaSiteKey"] = controller.recaptchaSiteKey
  89.  
  90.     var widgets = controller.Parse(t, "auth/reset", c.Env)
  91.     c.Env["Content"] = template.HTML(widgets)
  92.  
  93.     return controller.Parse(t, "main", c.Env), http.StatusOK
  94. }
  95.  
  96. func (controller *MainController) ResetPost(c web.C, r *http.Request) (string, int) {
  97.  
  98.     re := recaptcha.R{
  99.         Secret: controller.recaptchaSecret,
  100.     }
  101.  
  102.     email := r.FormValue("email")
  103.  
  104.     session := controller.GetSession(c)
  105.  
  106.     isValid := re.Verify(*r)
  107.     if !isValid {
  108.         session.AddFlash("Recaptcha error", "reset")
  109.         glog.Errorf("Error whilst resetting password for user: %v", re.LastError())
  110.         return controller.Reset(c, r)
  111.     }
  112.  
  113.     dbMap := controller.GetDbMap(c)
  114.     user := models.GetUserByEmail(dbMap, email)
  115.  
  116.     if user == nil {
  117.         session.AddFlash("User not found", "reset")
  118.         return controller.Reset(c, r)
  119.     }
  120.  
  121.     password := helpers.NewPass(10)
  122.     user.HashPassword(password)
  123.     models.ResetPassword(dbMap, user.Id, user.Password)
  124.  
  125.     auth := smtp.PlainAuth(
  126.             "",
  127.             "FROM_EMAIL",
  128.             "PASSWORD",
  129.             "smtp.gmail.com",
  130.     )
  131.  
  132.     from := mail.Address{"Stakepool Dcrstats", "info@dcrstats.com"}
  133.     to := mail.Address{email, email}
  134.     title := "Stakepool Dcrstats: New Password"
  135.  
  136.     body := "Hi! Here is your new password at stakepool.dcrstats.com: " + password
  137.  
  138.     header := make(map[string]string)
  139.     header["From"] = from.String()
  140.     header["To"] = to.String()
  141.     header["Subject"] = title
  142.     header["MIME-Version"] = "1.0"
  143.     header["Content-Type"] = "text/plain; charset=\"utf-8\""
  144.     header["Content-Transfer-Encoding"] = "base64"
  145.  
  146.     message := ""
  147.     for k, v := range header {
  148.         message += fmt.Sprintf("%s: %s\r\n", k, v)
  149.     }
  150.     message += "\r\n" + base64.StdEncoding.EncodeToString([]byte(body))
  151.  
  152.     // Connect to the server, authenticate, set the sender and recipient,
  153.     // and send the email all in one step.
  154.     err := smtp.SendMail(
  155.             "smtp.gmail.com:25",
  156.             auth,
  157.             "info@dcrstats.com",
  158.             []string{email},
  159.             []byte(message),
  160.     )
  161.     if err != nil {
  162.         session.AddFlash("Failed to send email with new password", "reset")
  163.         glog.Errorf("Error while resetting password: %v", err)
  164.         return controller.Reset(c, r)
  165.     }
  166.  
  167.     session.AddFlash("Success! We've sent you email with new password", "reset-success")
  168.     return controller.Reset(c, r)
  169. }
  170.  
  171.  
  172. helpers / auth.go
  173. ________________________________________________________________________________________
  174. import (
  175.     "github.com/decred/dcrstakepool/models"
  176.     "golang.org/x/crypto/bcrypt"
  177.     "gopkg.in/gorp.v1"
  178.     "crypto/rand"
  179. )
  180.  
  181. const (
  182.     // StdLen is a standard length of the string to achive ~95 bits of entropy.
  183.     StdLen = 16
  184.     // UUIDLen is a length of uniuri string to achive ~119 bits of entropy, closest
  185.     // to what can be losslessly converted to UUIDv4 (122 bits).
  186.     UUIDLen = 20
  187. )
  188.  
  189. // StdChars is a set of standard characters allowed in the string.
  190. var StdChars = []byte("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")
  191.  
  192. // NewLen returns a new random string of the provided length, consisting of
  193. // standard characters.
  194. func NewPass(length int) string {
  195.     return NewLenChars(length, StdChars)
  196. }
  197.  
  198. // NewLenChars returns a new random string of the provided length, consisting
  199. // of the provided byte slice of allowed characters (maximum 256).
  200. func NewLenChars(length int, chars []byte) string {
  201.     if length == 0 {
  202.         return ""
  203.     }
  204.     clen := len(chars)
  205.     if clen < 2 || clen > 256 {
  206.         panic("uniuri: wrong charset length for NewLenChars")
  207.     }
  208.     maxrb := 255 - (256 % clen)
  209.     b := make([]byte, length)
  210.     r := make([]byte, length+(length/4)) // storage for random bytes.
  211.     i := 0
  212.     for {
  213.         if _, err := rand.Read(r); err != nil {
  214.             panic("uniuri: error reading random bytes: " + err.Error())
  215.         }
  216.         for _, rb := range r {
  217.             c := int(rb)
  218.             if c > maxrb {
  219.                 // Skip this number to avoid modulo bias.
  220.                 continue
  221.             }
  222.             b[i] = chars[c%clen]
  223.             i++
  224.             if i == length {
  225.                 return string(b)
  226.             }
  227.         }
  228.     }
  229. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement