github.com/bitcubate/cryptojournal@v1.2.5-0.20171102134152-f578b3d788ab/src/users/actions/create.go (about) 1 package useractions 2 3 import ( 4 "fmt" 5 "net/http" 6 7 "github.com/fragmenta/auth" 8 "github.com/fragmenta/auth/can" 9 "github.com/fragmenta/mux" 10 "github.com/fragmenta/server" 11 "github.com/fragmenta/server/log" 12 "github.com/fragmenta/view" 13 14 "github.com/bitcubate/cryptojournal/src/lib/session" 15 "github.com/bitcubate/cryptojournal/src/lib/status" 16 "github.com/bitcubate/cryptojournal/src/users" 17 ) 18 19 // HandleCreateShow serves the create form via GET for users. 20 func HandleCreateShow(w http.ResponseWriter, r *http.Request) error { 21 22 user := users.New() 23 24 // Authorise 25 err := can.Create(user, session.CurrentUser(w, r)) 26 if err != nil { 27 return server.NotAuthorizedError(err) 28 } 29 30 // Check they're not logged in already if so redirect. 31 if !session.CurrentUser(w, r).Anon() { 32 return server.Redirect(w, r, "/?warn=already_logged_in") 33 } 34 35 params, err := mux.Params(r) 36 if err != nil { 37 return server.InternalError(err) 38 } 39 40 // Render the template 41 view := view.NewRenderer(w, r) 42 view.AddKey("user", user) 43 view.AddKey("hideSubmit", true) 44 view.AddKey("error", params.Get("error")) 45 return view.Render() 46 } 47 48 // HandleCreate handles the POST of the create form for users 49 func HandleCreate(w http.ResponseWriter, r *http.Request) error { 50 51 user := users.New() 52 53 // Check the authenticity token 54 err := session.CheckAuthenticity(w, r) 55 if err != nil { 56 return err 57 } 58 59 // Authorise 60 err = can.Create(user, session.CurrentUser(w, r)) 61 if err != nil { 62 return server.NotAuthorizedError(err) 63 } 64 65 // Check they're not logged in already if so redirect. 66 if !session.CurrentUser(w, r).Anon() { 67 return server.Redirect(w, r, "/?warn=already_logged_in") 68 } 69 70 params, err := mux.Params(r) 71 if err != nil { 72 return server.InternalError(err) 73 } 74 75 // Check a user doesn't exist with this name or email already 76 name := params.Get("name") 77 email := params.Get("email") 78 pass := params.Get("password") 79 80 // Name must be at least 2 characters 81 if len(name) < 2 { 82 return server.InternalError(err, "Name too short", "Sorry, names must be at least 2 characters long") 83 } 84 85 // Password must be at least 6 characters 86 if len(pass) < 6 { 87 return server.InternalError(err, "Password too short", "Sorry, passwords must be at least 6 characters long") 88 } 89 90 // Name is not optional so always check duplicates 91 duplicates, err := users.FindAll(users.Where("name=?", name)) 92 if err != nil { 93 return server.InternalError(err) 94 } 95 if len(duplicates) > 0 { 96 return server.Redirect(w, r, "/users/create?error=duplicate_name") 97 } 98 99 // Email is optional, so allow blank email and don't check duplicates if so 100 if email != "" { 101 duplicates, err = users.FindAll(users.Where("email=?", email)) 102 if err != nil { 103 return server.InternalError(err) 104 } 105 if len(duplicates) > 0 { 106 return server.Redirect(w, r, "/users/create?error=duplicate_email") 107 } 108 } 109 110 // Set the password hash from the password 111 hash, err := auth.HashPassword(pass) 112 if err != nil { 113 return server.InternalError(err) 114 } 115 params.SetString("password_hash", hash) 116 117 // Validate the params, removing any we don't accept 118 userParams := user.ValidateParams(params.Map(), users.AllowedParams()) 119 120 // Set some defaults for the new user 121 userParams["status"] = fmt.Sprintf("%d", status.Published) 122 userParams["role"] = fmt.Sprintf("%d", users.Reader) 123 userParams["points"] = "1" 124 125 id, err := user.Create(userParams) 126 if err != nil { 127 return server.InternalError(err) 128 } 129 130 // Redirect to the new user 131 user, err = users.Find(id) 132 if err != nil { 133 return server.InternalError(err) 134 } 135 136 // Log in automatically as the new user they have just created 137 session, err := auth.Session(w, r) 138 if err != nil { 139 log.Info(log.V{"msg": "login failed", "email": user.Email, "user_id": user.ID, "status": http.StatusInternalServerError}) 140 } 141 142 // Success, log it and set the cookie with user id 143 session.Set(auth.SessionUserKey, fmt.Sprintf("%d", user.ID)) 144 session.Save(w) 145 146 // Log action 147 log.Info(log.V{"msg": "login success", "user_email": user.Email, "user_id": user.ID}) 148 149 return server.Redirect(w, r, "/") 150 }