github.com/ngocphuongnb/tetua@v0.0.7-alpha/app/web/user/register.go (about)

     1  package webuser
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"strings"
     7  	"time"
     8  
     9  	netmail "net/mail"
    10  
    11  	"github.com/ngocphuongnb/tetua/app/auth"
    12  	"github.com/ngocphuongnb/tetua/app/config"
    13  	"github.com/ngocphuongnb/tetua/app/entities"
    14  	"github.com/ngocphuongnb/tetua/app/logger"
    15  	"github.com/ngocphuongnb/tetua/app/mail"
    16  	"github.com/ngocphuongnb/tetua/app/repositories"
    17  	"github.com/ngocphuongnb/tetua/app/server"
    18  	"github.com/ngocphuongnb/tetua/app/utils"
    19  	"github.com/ngocphuongnb/tetua/views"
    20  )
    21  
    22  type RegisterData struct {
    23  	Username             string `json:"username"`
    24  	Email                string `json:"email"`
    25  	Password             string `json:"password"`
    26  	PasswordConfirmation string `json:"passwordconfirmation"`
    27  }
    28  
    29  func (r *RegisterData) Parse(c server.Context) error {
    30  	if err := c.BodyParser(r); err != nil {
    31  		return err
    32  	}
    33  
    34  	if r.Username == "" || r.Email == "" || r.Password == "" || r.PasswordConfirmation == "" {
    35  		return errors.New("Please fill all required fields")
    36  	}
    37  
    38  	if _, err := netmail.ParseAddress(r.Email); err != nil {
    39  		return errors.New("Invalid email address")
    40  	}
    41  
    42  	if r.Password != r.PasswordConfirmation {
    43  		return errors.New("Password and Password confirmation doesn't match")
    44  	}
    45  
    46  	foundUsers, err := repositories.User.ByUsernameOrEmail(c.Context(), r.Username, r.Email)
    47  
    48  	if err != nil {
    49  		c.Logger().Error(err)
    50  		return errors.New("Something went wrong")
    51  	}
    52  
    53  	if len(foundUsers) > 0 {
    54  		return errors.New("Username or email already exists")
    55  	}
    56  
    57  	if r.Password, err = utils.GenerateHash(r.Password); err != nil {
    58  		c.Logger().Error(err)
    59  		return errors.New("Something went wrong")
    60  	}
    61  
    62  	return nil
    63  }
    64  
    65  func Register(c server.Context) (err error) {
    66  	if c.User() != nil && c.User().ID > 0 {
    67  		return c.Redirect(utils.Url(""))
    68  	}
    69  	c.Meta().Title = "Register"
    70  	return c.Render(views.Register("", ""))
    71  }
    72  
    73  func PostRegister(c server.Context) (err error) {
    74  	register := &RegisterData{}
    75  	autoApproveUser := config.Setting("auto_approve_user") == "yes"
    76  
    77  	if err = register.Parse(c); err != nil {
    78  		c.Messages().AppendError(err.Error())
    79  		return c.Render(views.Register(register.Username, register.Email))
    80  	}
    81  
    82  	user, err := repositories.User.Create(c.Context(), &entities.User{
    83  		Username: register.Username,
    84  		Email:    register.Email,
    85  		Password: register.Password,
    86  		RoleIDs:  []int{auth.ROLE_USER.ID},
    87  		Provider: "local",
    88  		Active:   autoApproveUser,
    89  	})
    90  
    91  	if err != nil {
    92  		c.WithError("Something went wrong", err)
    93  		return c.Render(views.Register(register.Username, register.Email))
    94  	}
    95  
    96  	mailBody := []string{fmt.Sprintf("Welcome <b>%s</b>, We're happy to have you with us.", user.Username)}
    97  	welcomeMessage := "Your account has been activated. You can now login to the site."
    98  
    99  	if autoApproveUser {
   100  		mailBody = append(
   101  			mailBody,
   102  			fmt.Sprintf("You can now login to your account at %s and start writing your first post", utils.Url("login")),
   103  		)
   104  	} else {
   105  		welcomeMessage = "Your account has been created. We've sent you an email to activate your account, please check your mailbox."
   106  		exp := time.Now().Add(time.Hour * 24)
   107  		activationCode, err := utils.Encrypt(fmt.Sprintf("%d_%d", user.ID, exp.UnixMicro()))
   108  
   109  		if err != nil {
   110  			logger.Error(err)
   111  			welcomeMessage = "Your account has been created. But we can't send you an email to activate your account, "
   112  			welcomeMessage += "please contact us with your username/email and this trace id: " + c.RequestID()
   113  		}
   114  
   115  		mailBody = append(
   116  			mailBody,
   117  			"Follow the link below to complete your registration:",
   118  			utils.Url("/activate?code="+activationCode),
   119  		)
   120  	}
   121  
   122  	go func(user *entities.User, requestID string) {
   123  		mailBody = append(mailBody, fmt.Sprintf("<br><b>Cheer</b>,<br>The %s Team", config.Setting("app_name")))
   124  		if err := mail.Send(
   125  			user.Username,
   126  			user.Email,
   127  			fmt.Sprintf("Welcome to %s", config.Setting("app_name")),
   128  			strings.Join(mailBody, "<br>"),
   129  		); err != nil {
   130  			logger.Get().WithContext(logger.Context{"request_id": requestID}).Error(err)
   131  		}
   132  	}(user, c.RequestID())
   133  
   134  	return c.Render(views.Message("Thank you for signing up", welcomeMessage, "", 0))
   135  }