Пример #1
0
// 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
}
Пример #2
0
// 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
}
Пример #3
0
// 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
}
Пример #4
0
// 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
}