// RegistrationProcess ... func (h *Handler) RegistrationProcess(ctx context.Context, rw http.ResponseWriter, r *http.Request) context.Context { r.ParseForm() validationErrorBuilder := lib.NewValidationErrorBuilder() registrationRequest := request.NewRegistrationRequestFromForm(r.Form) registrationRequest.Validate(validationErrorBuilder) if validationErrorBuilder.HasErrors() { rw.WriteHeader(http.StatusBadRequest) return h.renderTemplateWithData(rw, ctx, map[string]interface{}{ "validationErrors": validationErrorBuilder.Errors(), "request": registrationRequest, }) } user, err := createAndRegisterUser(h.Container.PasswordHasher, h.Container.RM.User, registrationRequest) if err != nil { switch err { case lib.ErrUserUniqueConstraintViolationUsername: validationErrorBuilder.Add("email", "User with given email already exists.") return h.renderTemplateWithData(rw, ctx, map[string]interface{}{ "validationErrors": validationErrorBuilder.Errors(), "request": registrationRequest, }) default: return h.renderTemplate500(rw, ctx, err) } } err = h.Container.ConfirmationMailer.Send(user.Username, map[string]interface{}{ "user": user, }) if err != nil { return h.renderTemplate500(rw, ctx, err) } h.redirect(rw, r, "registration_success", http.StatusFound) return ctx }
// PasswordRecoveryProcess ... func (h *Handler) PasswordRecoveryProcess(ctx context.Context, rw http.ResponseWriter, r *http.Request) context.Context { r.ParseForm() validationErrorBuilder := lib.NewValidationErrorBuilder() passwordRecoveryRequest := request.NewPasswordRecoveryRequestFromForm(r.Form) passwordRecoveryRequest.Validate(validationErrorBuilder) logger := h.Container.Logger.WithFields(logrus.Fields{ "email": passwordRecoveryRequest.Email, }) if validationErrorBuilder.HasErrors() { rw.WriteHeader(http.StatusBadRequest) return h.renderTemplateWithData(rw, ctx, map[string]interface{}{ "validationErrors": validationErrorBuilder.Errors(), "request": passwordRecoveryRequest, }) } err := h.Container.PasswordRecoverer.Start(passwordRecoveryRequest.Email) if err != nil { switch err { case lib.ErrUserNotFound, sql.ErrNoRows: logger.Debug("User does not exists. Password cannot be recovered, user will get fake response") case lib.ErrPasswordRecovererUserIsNotActive: logger.Debug("User is not active. Password cannot be recovered, user will get fake response") case lib.ErrPasswordRecovererUserIsNotConfirmed: logger.Debug("User is not confirmed. Password cannot be recovered, user will get fake response") default: return h.renderTemplate500(rw, ctx, err) } } h.redirect(rw, r, "password_recovery_success", http.StatusFound) return ctx }
// PasswordRecoveryConfirmationProcess ... func (h *Handler) PasswordRecoveryConfirmationProcess(ctx context.Context, rw http.ResponseWriter, r *http.Request) context.Context { r.ParseForm() var ok bool var confirmationToken string var userIDParam string if confirmationToken, ok = routing.ParamFromContext(ctx, "confirmationToken"); !ok { h.Container.Logger.Debug("Confirmation token param is missing.") return h.renderTemplate400(rw, ctx) } if userIDParam, ok = routing.ParamFromContext(ctx, "userId"); !ok { h.Container.Logger.Debug("User id param is missing.") return h.renderTemplate400(rw, ctx) } userID, err := strconv.ParseInt(userIDParam, 10, 64) if err != nil { h.Container.Logger.Debug("User ID param wrong type.") return h.renderTemplate400(rw, ctx) } logger := h.Container.Logger.WithFields(logrus.Fields{ "user_id": userID, "confirmation_token": confirmationToken, }) validationErrorBuilder := lib.NewValidationErrorBuilder() passwordRecoveryConfirmationRequest := request.NewPasswordRecoveryConfirmationRequestFromForm(r.Form) passwordRecoveryConfirmationRequest.Validate(validationErrorBuilder) if validationErrorBuilder.HasErrors() { rw.WriteHeader(http.StatusBadRequest) return h.renderTemplateWithData(rw, ctx, map[string]interface{}{ "validationErrors": validationErrorBuilder.Errors(), "request": passwordRecoveryConfirmationRequest, "user_id": userID, "confirmation_token": confirmationToken, }) } err = h.Container.PasswordRecoverer.Finalize( userID, confirmationToken, passwordRecoveryConfirmationRequest.Password, ) if err != nil { switch err { case lib.ErrUserNotFound, sql.ErrNoRows: logger.Debug("User or PasswordRecovery does not exists. Password cannot be changed, user will get fake response.") case lib.ErrPasswordRecovererUserIsNotActive: logger.Debug("User is not active. Password cannot be recovered, user will get fake response") case lib.ErrPasswordRecovererUserIsNotConfirmed: logger.Debug("User is not confirmed. Password cannot be recovered, user will get fake response") default: return h.renderTemplate500(rw, ctx, err) } } h.redirect(rw, r, "password_recovery_confirmation_success", http.StatusFound) return ctx }
// LoginProcess ... func (h *Handler) LoginProcess(ctx context.Context, rw http.ResponseWriter, r *http.Request) context.Context { r.ParseForm() validationErrorBuilder := lib.NewValidationErrorBuilder() loginRequest := request.NewLoginRequest(r.Form) loginRequest.Validate(validationErrorBuilder) if validationErrorBuilder.HasErrors() { rw.WriteHeader(http.StatusBadRequest) return h.renderTemplateWithData(rw, ctx, map[string]interface{}{ "validationErrors": validationErrorBuilder.Errors(), "request": loginRequest, }) } user, err := h.Container.RM.User.FindOneByUsername(loginRequest.Email) if err != nil { return h.renderTemplate500(rw, ctx, err) } if matches := h.Container.PasswordHasher.Compare(user.Password, loginRequest.Password); !matches { h.Container.Logger.WithFields(logrus.Fields{ "username": loginRequest.Email, "password": loginRequest.Password, }).Debug("Wrong password provided.") validationErrorBuilder.Add("form", "The email address and password you entered do not match.") return h.renderTemplateWithData(rw, ctx, map[string]interface{}{ "validationErrors": validationErrorBuilder.Errors(), "request": loginRequest, }) } if !user.IsConfirmed || !user.IsActive { return h.renderTemplate403(rw, ctx) } session := mnemosyne.Session{} sessionData := mnemosyne.SessionData{ "user_id": strconv.FormatInt(user.ID, 10), "username": user.Username, "first_name": user.FirstName, "last_name": user.LastName, } err = h.Container.Mnemosyne.Call("Store.New", sessionData, &session) if err != nil { return h.renderTemplate500(rw, ctx, err) } err = h.Container.RM.User.UpdateLastLoginAt(user.ID) if err != nil { return h.renderTemplate500(rw, ctx, err) } cookie := &http.Cookie{ Name: "sid", Value: session.ID.String(), HttpOnly: true, // TODO: need to be checked what behavior is preferred // Domain: h.Container.Config.Domain, } http.SetCookie(rw, cookie) h.redirect(rw, r, "dashboard", http.StatusFound) return ctx }