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  }