func setEmailAndFullnameFromTrustedUsername(user *tat.User) { conf := viper.GetString("trusted_usernames_emails_fullnames") tuples := strings.Split(conf, ",") user.Fullname = user.Username user.Email = user.Username + "@" + viper.GetString("default_domain") if len(conf) < 2 { return } for _, tuple := range tuples { t := strings.Split(tuple, ":") if len(t) != 3 { log.Errorf("Misconfiguration of trusted_usernames_emails tuple:%s", tuple) continue } usernameTuple := t[0] emailTuple := t[1] fullnameTuple := t[2] if usernameTuple == user.Username && emailTuple != "" && fullnameTuple != "" { user.Email = emailTuple user.Fullname = strings.Replace(fullnameTuple, "_", " ", -1) return } } }
// Insert a new user, return tokenVerify to user, in order to // validate account after check email func Insert(user *tat.User) (string, error) { user.ID = bson.NewObjectId().Hex() user.DateCreation = time.Now().Unix() user.Auth.DateAskReset = time.Now().Unix() user.Auth.EmailVerified = false user.IsSystem = false user.IsArchived = false user.CanWriteNotifications = false user.CanListUsersAsAdmin = false nbUsers, err := CountUsers() if err != nil { log.Errorf("Error while count all users%s", err) return "", err } if nbUsers > 0 { user.IsAdmin = false } else { log.Infof("user %s is the first user, he is now admin", user.Username) user.IsAdmin = true } tokenVerify := "" tokenVerify, user.Auth.HashedTokenVerify, err = generateUserPassword() if err != nil { log.Errorf("Error while generate Token Verify for new user %s", err) return tokenVerify, err } if err = store.Tat().CUsers.Insert(user); err != nil { log.Errorf("Error while inserting new user %s", err) } return tokenVerify, err }
// Create a new user, record Username, Fullname and Email // A mail is sent to ask user for validation func (u *UsersController) Create(ctx *gin.Context) { var userJSON tat.UserCreateJSON ctx.Bind(&userJSON) var userIn tat.User userIn.Username = u.computeUsername(userJSON) userIn.Fullname = strings.TrimSpace(userJSON.Fullname) userIn.Email = strings.TrimSpace(userJSON.Email) callback := strings.TrimSpace(userJSON.Callback) if len(userIn.Username) < 3 || len(userIn.Fullname) < 3 || len(userIn.Email) < 7 { err := fmt.Errorf("Invalid username (%s) or fullname (%s) or email (%s)", userIn.Username, userIn.Fullname, userIn.Email) AbortWithReturnError(ctx, http.StatusInternalServerError, err) return } if err := u.checkAllowedDomains(userJSON); err != nil { ctx.JSON(http.StatusForbidden, gin.H{"error": err.Error()}) return } user := tat.User{} foundEmail, errEmail := userDB.FindByEmail(&user, userJSON.Email) foundUsername, errUsername := userDB.FindByUsername(&user, userJSON.Username) foundFullname, errFullname := userDB.FindByFullname(&user, userJSON.Fullname) if foundEmail || foundUsername || foundFullname || errEmail != nil || errUsername != nil || errFullname != nil { e := fmt.Errorf("Please check your username, email or fullname. If you are already registered, please reset your password") AbortWithReturnError(ctx, http.StatusBadRequest, e) return } tokenVerify, err := userDB.Insert(&userIn) if err != nil { log.Errorf("Error while InsertUser %s", err) ctx.AbortWithError(http.StatusInternalServerError, err) return } go userDB.SendVerifyEmail(userIn.Username, userIn.Email, tokenVerify, callback) info := "" if viper.GetBool("username_from_email") { info = fmt.Sprintf(" Note that configuration of Tat forced your username to %s", userIn.Username) } ctx.JSON(http.StatusCreated, gin.H{"info": fmt.Sprintf("please check your mail to validate your account.%s", info)}) }
// Me retrieves all information about me (exception information about Authentication) func (*UsersController) Me(ctx *gin.Context) { var user = tat.User{} found, err := userDB.FindByUsername(&user, getCtxUsername(ctx)) if !found { ctx.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"}) return } else if err != nil { ctx.JSON(http.StatusInternalServerError, gin.H{"error": "Error while fetching user"}) return } gs, errGetGroupsOnlyName := groupDB.GetUserGroupsOnlyName(user.Username) if errGetGroupsOnlyName != nil { ctx.JSON(http.StatusInternalServerError, gin.H{"error": "Error while getting groups"}) return } user.Groups = gs out := &tat.UserJSON{User: user} ctx.JSON(http.StatusOK, out) }
// Reset send a mail asking user to confirm reset password func (u *UsersController) Reset(ctx *gin.Context) { var userJSON userResetJSON ctx.Bind(&userJSON) var userIn tat.User userIn.Username = strings.TrimSpace(userJSON.Username) userIn.Email = strings.TrimSpace(userJSON.Email) callback := strings.TrimSpace(userJSON.Callback) if len(userIn.Username) < 3 || len(userIn.Email) < 7 { err := fmt.Errorf("Invalid username (%s) or email (%s)", userIn.Username, userIn.Email) AbortWithReturnError(ctx, http.StatusInternalServerError, err) return } tokenVerify, err := userDB.AskReset(&userIn) if err != nil { log.Errorf("Error while AskReset %s", err) ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } go userDB.SendAskResetEmail(userIn.Username, userIn.Email, tokenVerify, callback) ctx.JSON(http.StatusCreated, gin.H{"info": "please check your mail to validate your account"}) }
// TrustUsername create user is not already registered func TrustUsername(user *tat.User, username string) error { var userCheck = tat.User{} found, errCheck := FindByUsername(&userCheck, username) if errCheck != nil { return fmt.Errorf("Error with DB Backend: %s", errCheck) } else if errCheck == nil && !found { user.Username = username setEmailAndFullnameFromTrustedUsername(user) tokenVerify, err := Insert(user) if err != nil { return fmt.Errorf("TrustUsername, Error while Insert user %s : %s", username, err.Error()) } // force default group and topics, even if it should be done in Verify CheckDefaultGroup(user, true) CheckTopics(user, true) if _, _, err = Verify(user, username, tokenVerify); err != nil { return fmt.Errorf("TrustUsername, Error while verify : %s", err.Error()) } log.Infof("User %s created by TrustUsername", username) } // ok, user is checked, get all fields now //return FindByUsername(user, username) found, err := FindByUsername(user, username) if !found || err != nil { return fmt.Errorf("TrustUsername, Error while find username:%s err:%s", username, err.Error()) } return nil }