예제 #1
0
func convertTeamTo30(primaryTeamName string, team *TeamForUpgrade, uniqueEmails map[string]bool, uniqueUsernames map[string]bool) []*UserForUpgrade {
	store := api.Srv.Store.(*store.SqlStore)
	var users []*UserForUpgrade
	if _, err := store.GetMaster().Select(&users, "SELECT Users.Id, Users.Username, Users.Email, Users.Roles, Users.TeamId FROM Users WHERE Users.TeamId = :TeamId", map[string]interface{}{"TeamId": team.Id}); err != nil {
		l4g.Error("Failed to load profiles for team details=%v", err)
		flushLogAndExit(1)
	}

	var members []*model.TeamMember
	if result := <-api.Srv.Store.Team().GetMembers(team.Id); result.Err != nil {
		l4g.Error("Failed to load team membership details=%v", result.Err)
		flushLogAndExit(1)
	} else {
		members = result.Data.([]*model.TeamMember)
	}

	for _, user := range users {
		shouldUpdateUser := false
		previousRole := user.Roles
		previousEmail := user.Email
		previousUsername := user.Username

		member := &model.TeamMember{
			TeamId: team.Id,
			UserId: user.Id,
		}

		if model.IsInRole(user.Roles, model.ROLE_TEAM_ADMIN) {
			member.Roles = model.ROLE_TEAM_ADMIN
			user.Roles = ""
			shouldUpdateUser = true
		}

		exists := false
		for _, member := range members {
			if member.UserId == user.Id {
				exists = true
				break
			}
		}

		if !exists {
			if result := <-api.Srv.Store.Team().SaveMember(member); result.Err != nil {
				l4g.Error("Failed to save membership for %v details=%v", user.Email, result.Err)
				flushLogAndExit(1)
			}
		}

		err := api.MoveFile(
			"teams/"+team.Id+"/users/"+user.Id+"/profile.png",
			"users/"+user.Id+"/profile.png",
		)

		if err != nil {
			l4g.Warn("No profile image to move for %v", user.Email)
		}

		if uniqueEmails[user.Email] {
			shouldUpdateUser = true
			emailParts := strings.Split(user.Email, "@")
			if len(emailParts) == 2 {
				user.Email = emailParts[0] + "+" + team.Name + "@" + emailParts[1]
			} else {
				user.Email = user.Email + "." + team.Name
			}

			if len(user.Email) > 127 {
				user.Email = user.Email[:127]
			}
		}

		if uniqueUsernames[user.Username] {
			shouldUpdateUser = true
			user.Username = team.Name + "." + user.Username

			if len(user.Username) > 63 {
				user.Username = user.Username[:63]
			}
		}

		if shouldUpdateUser {
			if _, err := store.GetMaster().Exec(`
				UPDATE Users 
				SET 
				    Email = :Email,
				    Username = :Username,
				    Roles = :Roles
				WHERE
				    Id = :Id
				`,
				map[string]interface{}{
					"Email":    user.Email,
					"Username": user.Username,
					"Roles":    user.Roles,
					"Id":       user.Id,
				},
			); err != nil {
				l4g.Error("Failed to update user %v details=%v", user.Email, err)
				flushLogAndExit(1)
			}

			l4g.Info("modified user_id=%v, changed email from=%v to=%v, changed username from=%v to %v changed roles from=%v to=%v", user.Id, previousEmail, user.Email, previousUsername, user.Username, previousRole, user.Roles)

			emailChanged := previousEmail != user.Email
			usernameChanged := previousUsername != user.Username

			if emailChanged || usernameChanged {
				bodyPage := utils.NewHTMLTemplate("upgrade_30_body", "")

				EmailChanged := ""
				UsernameChanged := ""

				if emailChanged {
					EmailChanged = "true"
				}

				if usernameChanged {
					UsernameChanged = "true"
				}

				bodyPage.Html["Info"] = template.HTML(utils.T("api.templates.upgrade_30_body.info",
					map[string]interface{}{
						"SiteName":        utils.ClientCfg["SiteName"],
						"TeamName":        team.Name,
						"Email":           user.Email,
						"Username":        user.Username,
						"EmailChanged":    EmailChanged,
						"UsernameChanged": UsernameChanged,
					}))

				utils.SendMail(
					previousEmail,
					utils.T("api.templates.upgrade_30_subject.info"),
					bodyPage.Render(),
				)
			}
		}

		uniqueEmails[user.Email] = true
		uniqueUsernames[user.Username] = true
	}

	return users
}
예제 #2
0
// ADDED for 3.0 REMOVE for 3.4
func cmdUpdateDb30() {
	if flagCmdUpdateDb30 {
		api.Srv = &api.Server{}
		api.Srv.Store = store.NewSqlStoreForUpgrade30()
		store := api.Srv.Store.(*store.SqlStore)
		utils.InitHTML()

		l4g.Info("Attempting to run speical upgrade of the database schema to version 3.0 for user model changes")
		time.Sleep(time.Second)

		if !store.DoesColumnExist("Users", "TeamId") {
			fmt.Println("**WARNING** the database schema appears to be upgraded to 3.0")
			flushLogAndExit(1)
		}

		if !(store.SchemaVersion == "2.2.0" ||
			store.SchemaVersion == "2.1.0" ||
			store.SchemaVersion == "2.0.0") {
			fmt.Println("**WARNING** the database schema needs to be version 2.2.0, 2.1.0 or 2.0.0 to upgrade")
			flushLogAndExit(1)
		}

		var confirmBackup string
		fmt.Println("\nPlease see http://www.mattermost.org/upgrade-to-3-0/")
		fmt.Println("**WARNING** This upgrade process will be irreversible.")
		fmt.Print("Have you performed a database backup? (YES/NO): ")
		fmt.Scanln(&confirmBackup)
		if confirmBackup != "YES" {
			fmt.Fprintln(os.Stderr, "ABORTED: You did not answer YES exactly, in all capitals.")
			flushLogAndExit(1)
		}

		var flagTeamName string
		var teams []*TeamForUpgrade

		if _, err := store.GetMaster().Select(&teams, "SELECT Id, Name FROM Teams"); err != nil {
			l4g.Error("Failed to load all teams details=%v", err)
			flushLogAndExit(1)
		}

		fmt.Println(fmt.Sprintf("We found %v teams.", len(teams)))

		for _, team := range teams {
			fmt.Println(team.Name)
		}

		fmt.Print("Please pick a primary team from the list above: ")
		fmt.Scanln(&flagTeamName)

		var team *TeamForUpgrade
		for _, t := range teams {
			if t.Name == flagTeamName {
				team = t
				break
			}
		}

		if team == nil {
			l4g.Error("Failed to find primary team details")
			flushLogAndExit(1)
		}

		l4g.Info("Starting speical 3.0 database upgrade with performed_backup=YES team_name=%v", team.Name)
		l4g.Info("Primary team %v will be left unchanged", team.Name)
		l4g.Info("Upgrading primary team %v", team.Name)

		uniqueEmails := make(map[string]bool)
		uniqueUsernames := make(map[string]bool)
		primaryUsers := convertTeamTo30(team.Name, team, uniqueEmails, uniqueUsernames)

		l4g.Info("Upgraded %v users", len(primaryUsers))

		for _, otherTeam := range teams {
			if otherTeam.Id != team.Id {
				l4g.Info("Upgrading team %v", otherTeam.Name)
				users := convertTeamTo30(team.Name, otherTeam, uniqueEmails, uniqueUsernames)
				l4g.Info("Upgraded %v users", len(users))

			}
		}

		l4g.Info("Altering other scheme changes needed 3.0 for user model changes")

		if _, err := store.GetMaster().Exec(`
				UPDATE Channels 
				SET 
				    TeamId = ''
				WHERE
				    Type = 'D'
				`,
		); err != nil {
			l4g.Error("Failed to update direct channel types details=%v", err)
			flushLogAndExit(1)
		}

		extraLength := store.GetMaxLengthOfColumnIfExists("Audits", "ExtraInfo")
		if len(extraLength) > 0 && extraLength != "1024" {
			store.AlterColumnTypeIfExists("Audits", "ExtraInfo", "VARCHAR(1024)", "VARCHAR(1024)")
		}

		actionLength := store.GetMaxLengthOfColumnIfExists("Audits", "Action")
		if len(actionLength) > 0 && actionLength != "512" {
			store.AlterColumnTypeIfExists("Audits", "Action", "VARCHAR(512)", "VARCHAR(512)")
		}

		if store.DoesColumnExist("Sessions", "TeamId") {
			store.RemoveColumnIfExists("Sessions", "TeamId")
			store.GetMaster().Exec(`TRUNCATE Sessions`)
		}

		// ADDED for 2.2 REMOVE for 2.6
		store.CreateColumnIfNotExists("Users", "MfaActive", "tinyint(1)", "boolean", "0")
		store.CreateColumnIfNotExists("Users", "MfaSecret", "varchar(128)", "character varying(128)", "")

		// ADDED for 2.2 REMOVE for 2.6
		if store.DoesColumnExist("Users", "TeamId") {
			store.RemoveIndexIfExists("idx_users_team_id", "Users")
			store.CreateUniqueIndexIfNotExists("idx_users_email_unique", "Users", "Email")
			store.CreateUniqueIndexIfNotExists("idx_users_username_unique", "Users", "Username")
			store.RemoveColumnIfExists("Teams", "AllowTeamListing")
			store.RemoveColumnIfExists("Users", "TeamId")
		}

		l4g.Info("Finished running speical upgrade of the database schema to version 3.0 for user model changes")

		if result := <-store.System().Update(&model.System{Name: "Version", Value: model.CurrentVersion}); result.Err != nil {
			l4g.Error("Failed to update system schema version details=%v", result.Err)
			flushLogAndExit(1)
		}

		l4g.Info(utils.T("store.sql.upgraded.warn"), model.CurrentVersion)
		fmt.Println("**SUCCESS** with upgrade")

		flushLogAndExit(0)
	}
}