github.com/saadullahsaeed/fragmenta-cms@v1.5.4/src/users/actions/login.go (about)

     1  package useractions
     2  
     3  import (
     4  	"fmt"
     5  	"net/http"
     6  
     7  	"github.com/fragmenta/auth"
     8  	"github.com/fragmenta/mux"
     9  	"github.com/fragmenta/server"
    10  	"github.com/fragmenta/server/log"
    11  	"github.com/fragmenta/view"
    12  
    13  	"github.com/fragmenta/fragmenta-cms/src/lib/session"
    14  	"github.com/fragmenta/fragmenta-cms/src/users"
    15  )
    16  
    17  // HandleLoginShow shows the page at /users/login
    18  func HandleLoginShow(w http.ResponseWriter, r *http.Request) error {
    19  
    20  	// Check they're not logged in already.
    21  	currentUser := session.CurrentUser(w, r)
    22  	if !currentUser.Anon() {
    23  		return server.Redirect(w, r, "/?warn=already_logged_in")
    24  	}
    25  
    26  	params, err := mux.Params(r)
    27  	if err != nil {
    28  		return server.NotFoundError(err)
    29  	}
    30  
    31  	// Show the login page, with login failure warnings.
    32  	view := view.NewRenderer(w, r)
    33  	switch params.Get("error") {
    34  	case "failed_email":
    35  		view.AddKey("warning", "Sorry, we couldn't find a user with that email.")
    36  	case "failed_password":
    37  		view.AddKey("warning", "Sorry, the password was incorrect, please try again.")
    38  	}
    39  	return view.Render()
    40  }
    41  
    42  // HandleLogin responds to POST /users/login
    43  // by setting a cookie on the request with encrypted user data.
    44  func HandleLogin(w http.ResponseWriter, r *http.Request) error {
    45  
    46  	// Check the authenticity token
    47  	err := session.CheckAuthenticity(w, r)
    48  	if err != nil {
    49  		return err
    50  	}
    51  
    52  	// Check they're not logged in already if so redirect.
    53  	currentUser := session.CurrentUser(w, r)
    54  	if !currentUser.Anon() {
    55  		return server.Redirect(w, r, "/?warn=already_logged_in")
    56  	}
    57  
    58  	// Get the user details from the database
    59  	params, err := mux.Params(r)
    60  	if err != nil {
    61  		return server.NotFoundError(err)
    62  	}
    63  
    64  	email := params.Get("email")
    65  	password := params.Get("password")
    66  
    67  	// Fetch the first user by email
    68  	user, err := users.FindFirst("email=?", email)
    69  	if err != nil {
    70  		log.Info(log.V{"msg": "login failed", "email": email, "status": http.StatusNotFound})
    71  		return server.Redirect(w, r, "/users/login?error=failed_email")
    72  	}
    73  
    74  	// Check password against the stored password
    75  	log.Info(log.V{"pass": password, "hash": user.PasswordHash})
    76  	err = auth.CheckPassword(password, user.PasswordHash)
    77  	if err != nil {
    78  		log.Info(log.V{"msg": "login failed", "email": email, "user_id": user.ID, "status": http.StatusUnauthorized})
    79  		return server.Redirect(w, r, "/users/login?error=failed_password")
    80  	}
    81  
    82  	// Now save the user details in a secure cookie, so that we remember the next request
    83  	session, err := auth.Session(w, r)
    84  	if err != nil {
    85  		log.Info(log.V{"msg": "login failed", "email": email, "user_id": user.ID, "status": http.StatusInternalServerError})
    86  	}
    87  
    88  	// Success, log it and set the cookie with user id
    89  	session.Set(auth.SessionUserKey, fmt.Sprintf("%d", user.ID))
    90  	session.Save(w)
    91  
    92  	// Log action
    93  	log.Info(log.V{"msg": "login", "user_email": user.Email, "user_id": user.ID})
    94  
    95  	// Redirect - ideally here we'd redirect to their original request path
    96  	return server.Redirect(w, r, "/")
    97  }