// GET /reset/{email}, Request link to reset password--emails user func ResetPasswordHandler(rw http.ResponseWriter, req *http.Request) { // TODO check empty token email := mux.Vars(req)["email"] if email == "" { renderer.JSON(rw, http.StatusBadRequest, map[string]string{ "status": requests.StatusFailed, "error": "no email provided", }) return } u, err := db.GetDeveloper(map[string]interface{}{"email": email}) if err != nil { renderer.JSON(rw, http.StatusBadRequest, map[string]string{ "status": requests.StatusFailed, "error": err.Error(), }) return } message, err := RenderEmail("password_email", map[string]interface{}{ "name": strings.Split(u.Name, " ")[0], "id": u.ID.Hex(), "token": u.Token, "engineer": u.IntegrationEngineer, }) if err != nil { renderer.JSON(rw, http.StatusBadRequest, map[string]string{ "status": requests.StatusFailed, "error": err.Error(), }) return } _, err = mandrill.MessageSend(gochimp.Message{ Subject: "Bowery Password Reset", FromEmail: "*****@*****.**", FromName: "Bowery Support", To: []gochimp.Recipient{{ Email: u.Email, Name: u.Name, }}, Html: message, }, false) if err != nil { renderer.JSON(rw, http.StatusBadRequest, map[string]string{ "status": requests.StatusFailed, "error": err.Error(), }) return } renderer.JSON(rw, http.StatusOK, map[string]string{ "status": requests.StatusSuccess, }) }
// POST /developer/token, logs in a user by creating a new token func CreateTokenHandler(rw http.ResponseWriter, req *http.Request) { var body requests.LoginReq decoder := json.NewDecoder(req.Body) err := decoder.Decode(&body) if err != nil { renderer.JSON(rw, http.StatusBadRequest, map[string]string{ "status": requests.StatusFailed, "error": err.Error(), }) return } email := body.Email password := body.Password if email == "" || password == "" { renderer.JSON(rw, http.StatusBadRequest, map[string]string{ "status": requests.StatusFailed, "error": "Email and Password Required.", }) return } query := map[string]interface{}{"email": email} u, err := db.GetDeveloper(query) if err != nil { renderer.JSON(rw, http.StatusInternalServerError, map[string]string{ "status": requests.StatusFailed, "error": "No such developer with email " + email + ".", }) return } if util.HashPassword(password, u.Salt) != u.Password { renderer.JSON(rw, http.StatusInternalServerError, map[string]string{ "status": requests.StatusFailed, "error": "Incorrect Password", }) return } token := util.HashToken() update := map[string]interface{}{"token": token} if err := db.UpdateDeveloper(query, update); err != nil { renderer.JSON(rw, http.StatusInternalServerError, map[string]string{ "status": requests.StatusFailed, "error": err.Error(), }) return } renderer.JSON(rw, http.StatusOK, map[string]interface{}{ "status": requests.StatusCreated, "token": token, }) }
func CheckAdminHandler(rw http.ResponseWriter, req *http.Request) { var body requests.LoginReq decoder := json.NewDecoder(req.Body) err := decoder.Decode(&body) if err != nil { renderer.JSON(rw, http.StatusBadRequest, map[string]string{ "status": requests.StatusFailed, "error": err.Error(), }) return } email := body.Email password := body.Password if email == "" || password == "" { renderer.JSON(rw, http.StatusBadRequest, map[string]string{ "status": requests.StatusFailed, "error": "Email and Password Required.", }) return } query := map[string]interface{}{"email": email} u, err := db.GetDeveloper(query) if err != nil { renderer.JSON(rw, http.StatusBadRequest, map[string]string{ "status": requests.StatusFailed, "error": "not admin", }) return } if util.HashPassword(password, u.Salt) != u.Password { renderer.JSON(rw, http.StatusBadRequest, map[string]string{ "status": requests.StatusFailed, "error": "not admin", }) return } if !u.IsAdmin { renderer.JSON(rw, http.StatusBadRequest, map[string]string{ "status": requests.StatusFailed, "error": "not admin", }) return } renderer.JSON(rw, http.StatusOK, map[string]string{ "status": requests.StatusSuccess, }) }
func AuthHandler(req *http.Request, user, pass string) (bool, error) { query := bson.M{} if pass == "" { query["token"] = user } else { query["email"] = user } dev, err := db.GetDeveloper(query) if err != nil || dev.ID == "" { return false, err } if pass != "" && dev.Password != util.HashPassword(pass, dev.Salt) { return false, nil } return true, nil }
// GET /admin/developers/{token}, Admin Interface for a single developer func DeveloperInfoHandler(rw http.ResponseWriter, req *http.Request) { token := mux.Vars(req)["token"] d, err := db.GetDeveloper(map[string]interface{}{"token": token}) if err != nil { RenderTemplate(rw, "error", map[string]string{"Error": err.Error()}) return } marshalledTime, _ := d.Expiration.MarshalJSON() RenderTemplate(rw, "developer", map[string]interface{}{ "Token": d.Token, "Name": d.Name, "Email": d.Email, "IsAdmin": d.IsAdmin, "IsPaid": d.IsPaid, "NextPaymentTime": string(marshalledTime[1 : len(marshalledTime)-1]), // trim inexplainable quotes and Z at the end that breaks shit "IntegrationEngineer": d.IntegrationEngineer, }) }
// GET /developers/me, return the logged in developer func GetCurrentDeveloperHandler(rw http.ResponseWriter, req *http.Request) { if err := req.ParseForm(); err != nil { renderer.JSON(rw, http.StatusBadRequest, map[string]string{ "status": requests.StatusFailed, "error": err.Error(), }) return } token := req.FormValue("token") if token == "" { renderer.JSON(rw, http.StatusInternalServerError, map[string]string{ "status": requests.StatusFailed, "error": "Valid token required.", }) return } query := map[string]interface{}{"token": token} u, err := db.GetDeveloper(query) if err != nil { if err == mgo.ErrNotFound { err = errors.New("Invalid Token.") } renderer.JSON(rw, http.StatusInternalServerError, map[string]string{ "status": requests.StatusFailed, "error": err.Error(), }) return } renderer.JSON(rw, http.StatusOK, map[string]interface{}{ "status": requests.StatusFound, "developer": u, }) }
// POST /developers/{token}/pay payments func PaymentHandler(rw http.ResponseWriter, req *http.Request) { var body requests.PaymentReq decoder := json.NewDecoder(req.Body) err := decoder.Decode(&body) if err != nil { renderer.JSON(rw, http.StatusBadRequest, map[string]string{ "status": requests.StatusFailed, "error": err.Error(), }) return } d, err := db.GetDeveloper(map[string]interface{}{"token": mux.Vars(req)["token"]}) if err != nil { renderer.JSON(rw, http.StatusBadRequest, map[string]string{ "status": requests.StatusFailed, "error": err.Error(), }) return } // Create Stripe Customer customerParams := stripe.CustomerParams{ Email: d.Email, Desc: d.Name, Token: body.StripeToken, } customer, err := stripe.Customers.Create(&customerParams) if err != nil { renderer.JSON(rw, http.StatusBadRequest, map[string]string{ "status": requests.StatusFailed, "error": err.Error(), }) return } // Charge Stripe Customer chargeParams := stripe.ChargeParams{ Desc: "Bowery 3", Amount: 2900, Currency: "usd", Customer: customer.Id, } _, err = stripe.Charges.Create(&chargeParams) if err != nil { RenderTemplate(rw, "error", map[string]string{"Error": err.Error()}) return } if err := db.UpdateDeveloper(map[string]interface{}{"token": d.Token}, map[string]interface{}{"isPaid": true}); err != nil { renderer.JSON(rw, http.StatusInternalServerError, map[string]string{ "status": requests.StatusFailed, "error": err.Error(), }) return } renderer.JSON(rw, http.StatusOK, map[string]interface{}{ "status": requests.StatusSuccess, "developer": d, }) }
// POST /developers, Creates a new developer func CreateDeveloperHandler(rw http.ResponseWriter, req *http.Request) { type engineer struct { Name string Email string } integrationEngineers := []*engineer{ &engineer{Name: "Steve Kaliski", Email: "*****@*****.**"}, &engineer{Name: "David Byrd", Email: "*****@*****.**"}, &engineer{Name: "Larz Conwell", Email: "*****@*****.**"}, } integrationEngineer := integrationEngineers[rand.Int()%len(integrationEngineers)] var body requests.LoginReq decoder := json.NewDecoder(req.Body) err := decoder.Decode(&body) if err != nil { renderer.JSON(rw, http.StatusBadRequest, map[string]string{ "status": requests.StatusFailed, "error": err.Error(), }) return } if body.Email == "" || body.Password == "" { renderer.JSON(rw, http.StatusBadRequest, map[string]string{ "status": requests.StatusFailed, "error": "Email and Password Required.", }) return } u := &schemas.Developer{ Name: body.Name, Email: body.Email, Password: body.Password, Token: util.HashToken(), IntegrationEngineer: integrationEngineer.Name, IsPaid: false, CreatedAt: time.Now().UnixNano() / int64(time.Millisecond), } _, err = db.GetDeveloper(bson.M{"email": u.Email}) if err == nil { renderer.JSON(rw, http.StatusInternalServerError, map[string]string{ "status": requests.StatusFailed, "error": "email already exists", }) return } if os.Getenv("ENV") == "production" && !strings.Contains(body.Email, "@bowery.io") { if _, err := chimp.ListsSubscribe(gochimp.ListsSubscribe{ ListId: "200e892f56", Email: gochimp.Email{Email: u.Email}, }); err != nil { renderer.JSON(rw, http.StatusBadRequest, map[string]string{ "status": requests.StatusFailed, "error": err.Error(), }) return } message, err := RenderEmail("welcome", map[string]interface{}{ "name": strings.Split(u.Name, " ")[0], "engineer": integrationEngineer, }) if err != nil { renderer.JSON(rw, http.StatusBadRequest, map[string]string{ "status": requests.StatusFailed, "error": err.Error(), }) return } _, err = mandrill.MessageSend(gochimp.Message{ Subject: "Welcome to Bowery!", FromEmail: "*****@*****.**", FromName: integrationEngineer.Name, To: []gochimp.Recipient{{ Email: u.Email, Name: u.Name, }}, Html: message, }, false) if err != nil { renderer.JSON(rw, http.StatusBadRequest, map[string]string{ "status": requests.StatusFailed, "error": err.Error(), }) return } } if err := db.Save(u); err != nil { renderer.JSON(rw, http.StatusBadRequest, map[string]string{ "status": requests.StatusFailed, "error": err.Error(), }) return } // Post to slack if os.Getenv("ENV") == "production" && !strings.Contains(body.Email, "@bowery.io") { channel := "#activity" message := u.Name + " " + u.Email + " just signed up." username := "******" go slackC.SendMessage(channel, message, username) } renderer.JSON(rw, http.StatusOK, map[string]interface{}{ "status": requests.StatusCreated, "developer": u, }) }
// PUT /developers/{token}, edits a developer func UpdateDeveloperHandler(rw http.ResponseWriter, req *http.Request) { token := mux.Vars(req)["token"] if token == "" { renderer.JSON(rw, http.StatusBadRequest, map[string]string{ "status": requests.StatusFailed, "error": "missing token", }) return } if err := req.ParseForm(); err != nil { renderer.JSON(rw, http.StatusBadRequest, map[string]string{ "status": requests.StatusFailed, "error": err.Error(), }) return } query := map[string]interface{}{"token": token} update := map[string]interface{}{} u, err := db.GetDeveloper(query) if err != nil { renderer.JSON(rw, http.StatusInternalServerError, map[string]string{ "status": requests.StatusFailed, "error": err.Error(), }) return } if password := req.FormValue("password"); password != "" { oldpass := req.FormValue("oldpassword") if oldpass == "" || util.HashPassword(oldpass, u.Salt) != u.Password { renderer.JSON(rw, http.StatusBadRequest, map[string]string{ "status": requests.StatusFailed, "error": "Old password is incorrect.", }) return } update["password"] = util.HashPassword(password, u.Salt) } if nextPaymentTime := req.FormValue("nextPaymentTime"); nextPaymentTime != "" { update["nextPaymentTime"], err = time.Parse(time.RFC3339, nextPaymentTime) } if isAdmin := req.FormValue("isAdmin"); isAdmin != "" { update["isAdmin"] = isAdmin == "on" || isAdmin == "true" } if isPaid := req.FormValue("isPaid"); isPaid != "" { update["isPaid"] = isPaid == "on" || isPaid == "true" } // TODO add datetime parsing for _, field := range []string{"name", "email", "integrationEngineer"} { val := req.FormValue(field) if val != "" { update[field] = val } } if err := db.UpdateDeveloper(query, update); err != nil { renderer.JSON(rw, http.StatusInternalServerError, map[string]string{ "status": requests.StatusFailed, "error": err.Error(), }) return } renderer.JSON(rw, http.StatusOK, map[string]interface{}{ "status": requests.StatusUpdated, "update": update, }) }