github.com/mattermosttest/mattermost-server/v5@v5.0.0-20200917143240-9dfa12e121f9/store/sqlstore/team_store.go (about)

     1  // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
     2  // See LICENSE.txt for license information.
     3  
     4  package sqlstore
     5  
     6  import (
     7  	"database/sql"
     8  	"fmt"
     9  	"net/http"
    10  	"strings"
    11  
    12  	sq "github.com/Masterminds/squirrel"
    13  
    14  	"github.com/mattermost/gorp"
    15  	"github.com/mattermost/mattermost-server/v5/model"
    16  	"github.com/mattermost/mattermost-server/v5/store"
    17  	"github.com/mattermost/mattermost-server/v5/utils"
    18  )
    19  
    20  const (
    21  	TEAM_MEMBER_EXISTS_ERROR = "store.sql_team.save_member.exists.app_error"
    22  )
    23  
    24  type SqlTeamStore struct {
    25  	SqlStore
    26  
    27  	teamsQuery sq.SelectBuilder
    28  }
    29  
    30  type teamMember struct {
    31  	TeamId      string
    32  	UserId      string
    33  	Roles       string
    34  	DeleteAt    int64
    35  	SchemeUser  sql.NullBool
    36  	SchemeAdmin sql.NullBool
    37  	SchemeGuest sql.NullBool
    38  }
    39  
    40  func NewTeamMemberFromModel(tm *model.TeamMember) *teamMember {
    41  	return &teamMember{
    42  		TeamId:      tm.TeamId,
    43  		UserId:      tm.UserId,
    44  		Roles:       tm.ExplicitRoles,
    45  		DeleteAt:    tm.DeleteAt,
    46  		SchemeGuest: sql.NullBool{Valid: true, Bool: tm.SchemeGuest},
    47  		SchemeUser:  sql.NullBool{Valid: true, Bool: tm.SchemeUser},
    48  		SchemeAdmin: sql.NullBool{Valid: true, Bool: tm.SchemeAdmin},
    49  	}
    50  }
    51  
    52  type teamMemberWithSchemeRoles struct {
    53  	TeamId                     string
    54  	UserId                     string
    55  	Roles                      string
    56  	DeleteAt                   int64
    57  	SchemeGuest                sql.NullBool
    58  	SchemeUser                 sql.NullBool
    59  	SchemeAdmin                sql.NullBool
    60  	TeamSchemeDefaultGuestRole sql.NullString
    61  	TeamSchemeDefaultUserRole  sql.NullString
    62  	TeamSchemeDefaultAdminRole sql.NullString
    63  }
    64  
    65  type teamMemberWithSchemeRolesList []teamMemberWithSchemeRoles
    66  
    67  func teamMemberSliceColumns() []string {
    68  	return []string{"TeamId", "UserId", "Roles", "DeleteAt", "SchemeUser", "SchemeAdmin", "SchemeGuest"}
    69  }
    70  
    71  func teamMemberToSlice(member *model.TeamMember) []interface{} {
    72  	resultSlice := []interface{}{}
    73  	resultSlice = append(resultSlice, member.TeamId)
    74  	resultSlice = append(resultSlice, member.UserId)
    75  	resultSlice = append(resultSlice, member.ExplicitRoles)
    76  	resultSlice = append(resultSlice, member.DeleteAt)
    77  	resultSlice = append(resultSlice, member.SchemeUser)
    78  	resultSlice = append(resultSlice, member.SchemeAdmin)
    79  	resultSlice = append(resultSlice, member.SchemeGuest)
    80  	return resultSlice
    81  }
    82  
    83  func wildcardSearchTerm(term string) string {
    84  	return strings.ToLower("%" + term + "%")
    85  }
    86  
    87  type rolesInfo struct {
    88  	roles         []string
    89  	explicitRoles []string
    90  	schemeGuest   bool
    91  	schemeUser    bool
    92  	schemeAdmin   bool
    93  }
    94  
    95  func getTeamRoles(schemeGuest, schemeUser, schemeAdmin bool, defaultTeamGuestRole, defaultTeamUserRole, defaultTeamAdminRole string, roles []string) rolesInfo {
    96  	result := rolesInfo{
    97  		roles:         []string{},
    98  		explicitRoles: []string{},
    99  		schemeGuest:   schemeGuest,
   100  		schemeUser:    schemeUser,
   101  		schemeAdmin:   schemeAdmin,
   102  	}
   103  	// Identify any scheme derived roles that are in "Roles" field due to not yet being migrated, and exclude
   104  	// them from ExplicitRoles field.
   105  	for _, role := range roles {
   106  		switch role {
   107  		case model.TEAM_GUEST_ROLE_ID:
   108  			result.schemeGuest = true
   109  		case model.TEAM_USER_ROLE_ID:
   110  			result.schemeUser = true
   111  		case model.TEAM_ADMIN_ROLE_ID:
   112  			result.schemeAdmin = true
   113  		default:
   114  			result.explicitRoles = append(result.explicitRoles, role)
   115  			result.roles = append(result.roles, role)
   116  		}
   117  	}
   118  
   119  	// Add any scheme derived roles that are not in the Roles field due to being Implicit from the Scheme, and add
   120  	// them to the Roles field for backwards compatibility reasons.
   121  	var schemeImpliedRoles []string
   122  	if result.schemeGuest {
   123  		if defaultTeamGuestRole != "" {
   124  			schemeImpliedRoles = append(schemeImpliedRoles, defaultTeamGuestRole)
   125  		} else {
   126  			schemeImpliedRoles = append(schemeImpliedRoles, model.TEAM_GUEST_ROLE_ID)
   127  		}
   128  	}
   129  	if result.schemeUser {
   130  		if defaultTeamUserRole != "" {
   131  			schemeImpliedRoles = append(schemeImpliedRoles, defaultTeamUserRole)
   132  		} else {
   133  			schemeImpliedRoles = append(schemeImpliedRoles, model.TEAM_USER_ROLE_ID)
   134  		}
   135  	}
   136  	if result.schemeAdmin {
   137  		if defaultTeamAdminRole != "" {
   138  			schemeImpliedRoles = append(schemeImpliedRoles, defaultTeamAdminRole)
   139  		} else {
   140  			schemeImpliedRoles = append(schemeImpliedRoles, model.TEAM_ADMIN_ROLE_ID)
   141  		}
   142  	}
   143  	for _, impliedRole := range schemeImpliedRoles {
   144  		alreadyThere := false
   145  		for _, role := range result.roles {
   146  			if role == impliedRole {
   147  				alreadyThere = true
   148  			}
   149  		}
   150  		if !alreadyThere {
   151  			result.roles = append(result.roles, impliedRole)
   152  		}
   153  	}
   154  	return result
   155  }
   156  
   157  func (db teamMemberWithSchemeRoles) ToModel() *model.TeamMember {
   158  	// Identify any scheme derived roles that are in "Roles" field due to not yet being migrated, and exclude
   159  	// them from ExplicitRoles field.
   160  	schemeGuest := db.SchemeGuest.Valid && db.SchemeGuest.Bool
   161  	schemeUser := db.SchemeUser.Valid && db.SchemeUser.Bool
   162  	schemeAdmin := db.SchemeAdmin.Valid && db.SchemeAdmin.Bool
   163  
   164  	defaultTeamGuestRole := ""
   165  	if db.TeamSchemeDefaultGuestRole.Valid {
   166  		defaultTeamGuestRole = db.TeamSchemeDefaultGuestRole.String
   167  	}
   168  
   169  	defaultTeamUserRole := ""
   170  	if db.TeamSchemeDefaultUserRole.Valid {
   171  		defaultTeamUserRole = db.TeamSchemeDefaultUserRole.String
   172  	}
   173  
   174  	defaultTeamAdminRole := ""
   175  	if db.TeamSchemeDefaultAdminRole.Valid {
   176  		defaultTeamAdminRole = db.TeamSchemeDefaultAdminRole.String
   177  	}
   178  
   179  	rolesResult := getTeamRoles(schemeGuest, schemeUser, schemeAdmin, defaultTeamGuestRole, defaultTeamUserRole, defaultTeamAdminRole, strings.Fields(db.Roles))
   180  
   181  	tm := &model.TeamMember{
   182  		TeamId:        db.TeamId,
   183  		UserId:        db.UserId,
   184  		Roles:         strings.Join(rolesResult.roles, " "),
   185  		DeleteAt:      db.DeleteAt,
   186  		SchemeGuest:   rolesResult.schemeGuest,
   187  		SchemeUser:    rolesResult.schemeUser,
   188  		SchemeAdmin:   rolesResult.schemeAdmin,
   189  		ExplicitRoles: strings.Join(rolesResult.explicitRoles, " "),
   190  	}
   191  	return tm
   192  }
   193  
   194  func (db teamMemberWithSchemeRolesList) ToModel() []*model.TeamMember {
   195  	tms := make([]*model.TeamMember, 0)
   196  
   197  	for _, tm := range db {
   198  		tms = append(tms, tm.ToModel())
   199  	}
   200  
   201  	return tms
   202  }
   203  
   204  func newSqlTeamStore(sqlStore SqlStore) store.TeamStore {
   205  	s := &SqlTeamStore{
   206  		SqlStore: sqlStore,
   207  	}
   208  
   209  	s.teamsQuery = s.getQueryBuilder().
   210  		Select("Teams.*").
   211  		From("Teams")
   212  
   213  	for _, db := range sqlStore.GetAllConns() {
   214  		table := db.AddTableWithName(model.Team{}, "Teams").SetKeys(false, "Id")
   215  		table.ColMap("Id").SetMaxSize(26)
   216  		table.ColMap("DisplayName").SetMaxSize(64)
   217  		table.ColMap("Name").SetMaxSize(64).SetUnique(true)
   218  		table.ColMap("Description").SetMaxSize(255)
   219  		table.ColMap("Email").SetMaxSize(128)
   220  		table.ColMap("CompanyName").SetMaxSize(64)
   221  		table.ColMap("AllowedDomains").SetMaxSize(1000)
   222  		table.ColMap("InviteId").SetMaxSize(32)
   223  
   224  		tablem := db.AddTableWithName(teamMember{}, "TeamMembers").SetKeys(false, "TeamId", "UserId")
   225  		tablem.ColMap("TeamId").SetMaxSize(26)
   226  		tablem.ColMap("UserId").SetMaxSize(26)
   227  		tablem.ColMap("Roles").SetMaxSize(64)
   228  	}
   229  
   230  	return s
   231  }
   232  
   233  func (s SqlTeamStore) createIndexesIfNotExists() {
   234  	s.CreateIndexIfNotExists("idx_teams_name", "Teams", "Name")
   235  	s.RemoveIndexIfExists("idx_teams_description", "Teams")
   236  	s.CreateIndexIfNotExists("idx_teams_invite_id", "Teams", "InviteId")
   237  	s.CreateIndexIfNotExists("idx_teams_update_at", "Teams", "UpdateAt")
   238  	s.CreateIndexIfNotExists("idx_teams_create_at", "Teams", "CreateAt")
   239  	s.CreateIndexIfNotExists("idx_teams_delete_at", "Teams", "DeleteAt")
   240  	s.CreateIndexIfNotExists("idx_teams_scheme_id", "Teams", "SchemeId")
   241  
   242  	s.CreateIndexIfNotExists("idx_teammembers_team_id", "TeamMembers", "TeamId")
   243  	s.CreateIndexIfNotExists("idx_teammembers_user_id", "TeamMembers", "UserId")
   244  	s.CreateIndexIfNotExists("idx_teammembers_delete_at", "TeamMembers", "DeleteAt")
   245  }
   246  
   247  // Save adds the team to the database if a team with the same name does not already
   248  // exist in the database. It returns the team added if the operation is successful.
   249  func (s SqlTeamStore) Save(team *model.Team) (*model.Team, *model.AppError) {
   250  	if len(team.Id) > 0 {
   251  		return nil, model.NewAppError("SqlTeamStore.Save",
   252  			"store.sql_team.save.existing.app_error", nil, "id="+team.Id, http.StatusBadRequest)
   253  	}
   254  
   255  	team.PreSave()
   256  
   257  	if err := team.IsValid(); err != nil {
   258  		return nil, err
   259  	}
   260  
   261  	if err := s.GetMaster().Insert(team); err != nil {
   262  		if IsUniqueConstraintError(err, []string{"Name", "teams_name_key"}) {
   263  			return nil, model.NewAppError("SqlTeamStore.Save", "store.sql_team.save.domain_exists.app_error", nil, "id="+team.Id+", "+err.Error(), http.StatusBadRequest)
   264  		}
   265  		return nil, model.NewAppError("SqlTeamStore.Save", "store.sql_team.save.app_error", nil, "id="+team.Id+", "+err.Error(), http.StatusInternalServerError)
   266  	}
   267  	return team, nil
   268  }
   269  
   270  // Update updates the details of the team passed as the parameter using the team Id
   271  // if the team exists in the database.
   272  // It returns the updated team if the operation is successful.
   273  func (s SqlTeamStore) Update(team *model.Team) (*model.Team, *model.AppError) {
   274  
   275  	team.PreUpdate()
   276  
   277  	if err := team.IsValid(); err != nil {
   278  		return nil, err
   279  	}
   280  
   281  	oldResult, err := s.GetMaster().Get(model.Team{}, team.Id)
   282  	if err != nil {
   283  		return nil, model.NewAppError("SqlTeamStore.Update", "store.sql_team.update.finding.app_error", nil, "id="+team.Id+", "+err.Error(), http.StatusInternalServerError)
   284  
   285  	}
   286  
   287  	if oldResult == nil {
   288  		return nil, model.NewAppError("SqlTeamStore.Update", "store.sql_team.update.find.app_error", nil, "id="+team.Id, http.StatusBadRequest)
   289  	}
   290  
   291  	oldTeam := oldResult.(*model.Team)
   292  	team.CreateAt = oldTeam.CreateAt
   293  	team.UpdateAt = model.GetMillis()
   294  
   295  	count, err := s.GetMaster().Update(team)
   296  	if err != nil {
   297  		return nil, model.NewAppError("SqlTeamStore.Update", "store.sql_team.update.updating.app_error", nil, "id="+team.Id+", "+err.Error(), http.StatusInternalServerError)
   298  	}
   299  	if count != 1 {
   300  		return nil, model.NewAppError("SqlTeamStore.Update", "store.sql_team.update.app_error", nil, "id="+team.Id, http.StatusInternalServerError)
   301  	}
   302  
   303  	return team, nil
   304  }
   305  
   306  // Get returns from the database the team that matches the id provided as parameter.
   307  // If the team doesn't exist it returns a model.AppError with a
   308  // http.StatusNotFound in the StatusCode field.
   309  func (s SqlTeamStore) Get(id string) (*model.Team, *model.AppError) {
   310  	obj, err := s.GetReplica().Get(model.Team{}, id)
   311  	if err != nil {
   312  		return nil, model.NewAppError("SqlTeamStore.Get", "store.sql_team.get.finding.app_error", nil, "id="+id+", "+err.Error(), http.StatusInternalServerError)
   313  	}
   314  	if obj == nil {
   315  		return nil, model.NewAppError("SqlTeamStore.Get", "store.sql_team.get.find.app_error", nil, "id="+id, http.StatusNotFound)
   316  	}
   317  
   318  	return obj.(*model.Team), nil
   319  }
   320  
   321  // GetByInviteId returns from the database the team that matches the inviteId provided as parameter.
   322  // If the parameter provided is empty or if there is no match in the database, it returns a model.AppError
   323  // with a http.StatusNotFound in the StatusCode field.
   324  func (s SqlTeamStore) GetByInviteId(inviteId string) (*model.Team, *model.AppError) {
   325  	team := model.Team{}
   326  
   327  	query, args, err := s.teamsQuery.Where(sq.Eq{"InviteId": inviteId}).ToSql()
   328  	if err != nil {
   329  		return nil, model.NewAppError("SqlTeamStore.GetByInviteId", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError)
   330  	}
   331  	err = s.GetReplica().SelectOne(&team, query, args...)
   332  	if err != nil {
   333  		return nil, model.NewAppError("SqlTeamStore.GetByInviteId", "store.sql_team.get_by_invite_id.finding.app_error", nil, "inviteId="+inviteId+", "+err.Error(), http.StatusNotFound)
   334  	}
   335  
   336  	if len(inviteId) == 0 || team.InviteId != inviteId {
   337  		return nil, model.NewAppError("SqlTeamStore.GetByInviteId", "store.sql_team.get_by_invite_id.find.app_error", nil, "inviteId="+inviteId, http.StatusNotFound)
   338  	}
   339  	return &team, nil
   340  }
   341  
   342  // GetByName returns from the database the team that matches the name provided as parameter.
   343  // If there is no match in the database, it returns a model.AppError with a
   344  // http.StatusNotFound in the StatusCode field.
   345  func (s SqlTeamStore) GetByName(name string) (*model.Team, *model.AppError) {
   346  
   347  	team := model.Team{}
   348  	query, args, err := s.teamsQuery.Where(sq.Eq{"Name": name}).ToSql()
   349  	if err != nil {
   350  		return nil, model.NewAppError("SqlTeamStore.GetByName", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError)
   351  	}
   352  	err = s.GetReplica().SelectOne(&team, query, args...)
   353  	if err != nil {
   354  		if err == sql.ErrNoRows {
   355  			return nil, model.NewAppError("SqlTeamStore.GetByName", "store.sql_team.get_by_name.missing.app_error", nil, "name="+name+","+err.Error(), http.StatusNotFound)
   356  		}
   357  		return nil, model.NewAppError("SqlTeamStore.GetByName", "store.sql_team.get_by_name.app_error", nil, "name="+name+", "+err.Error(), http.StatusInternalServerError)
   358  	}
   359  	return &team, nil
   360  }
   361  
   362  func (s SqlTeamStore) GetByNames(names []string) ([]*model.Team, *model.AppError) {
   363  	uniqueNames := utils.RemoveDuplicatesFromStringArray(names)
   364  
   365  	query, args, err := s.teamsQuery.Where(sq.Eq{"Name": uniqueNames}).ToSql()
   366  
   367  	if err != nil {
   368  		return nil, model.NewAppError("SqlTeamStore.GetByNames", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError)
   369  	}
   370  
   371  	teams := []*model.Team{}
   372  	_, err = s.GetReplica().Select(&teams, query, args...)
   373  	if err != nil {
   374  		if err == sql.ErrNoRows {
   375  			return nil, model.NewAppError("SqlTeamStore.GetByNames", "store.sql_team.get_by_names.missing.app_error", nil, err.Error(), http.StatusNotFound)
   376  		}
   377  		return nil, model.NewAppError("SqlTeamStore.GetByNames", "store.sql_team.get_by_names.app_error", nil, err.Error(), http.StatusInternalServerError)
   378  	}
   379  	if len(teams) != len(uniqueNames) {
   380  		return nil, model.NewAppError("SqlTeamStore.GetByNames", "store.sql_team.get_by_names.missing.app_error", nil, "", http.StatusNotFound)
   381  	}
   382  	return teams, nil
   383  }
   384  
   385  func (s SqlTeamStore) teamSearchQuery(term string, opts *model.TeamSearch, countQuery bool) sq.SelectBuilder {
   386  	var selectStr string
   387  	if countQuery {
   388  		selectStr = "count(*)"
   389  	} else {
   390  		selectStr = "*"
   391  	}
   392  
   393  	query := s.getQueryBuilder().
   394  		Select(selectStr).
   395  		From("Teams as t")
   396  
   397  	// Don't order or limit if getting count
   398  	if !countQuery {
   399  		query = query.OrderBy("t.DisplayName")
   400  
   401  		if opts.IsPaginated() {
   402  			query = query.Limit(uint64(*opts.PerPage)).Offset(uint64(*opts.Page * *opts.PerPage))
   403  		}
   404  	}
   405  
   406  	if len(term) > 0 {
   407  		term = sanitizeSearchTerm(term, "\\")
   408  		term = wildcardSearchTerm(term)
   409  
   410  		operatorKeyword := "ILIKE"
   411  		if s.DriverName() == model.DATABASE_DRIVER_MYSQL {
   412  			operatorKeyword = "LIKE"
   413  		}
   414  
   415  		query = query.Where(fmt.Sprintf("(Name %[1]s ? OR DisplayName %[1]s ?)", operatorKeyword), term, term)
   416  	}
   417  
   418  	var teamFilters sq.Sqlizer
   419  	var openInviteFilter sq.Sqlizer
   420  	if opts.AllowOpenInvite != nil {
   421  		if *opts.AllowOpenInvite {
   422  			openInviteFilter = sq.Eq{"AllowOpenInvite": true}
   423  		} else {
   424  			openInviteFilter = sq.And{
   425  				sq.Or{
   426  					sq.NotEq{"AllowOpenInvite": true},
   427  					sq.Eq{"AllowOpenInvite": nil},
   428  				},
   429  				sq.Or{
   430  					sq.NotEq{"GroupConstrained": true},
   431  					sq.Eq{"GroupConstrained": nil},
   432  				},
   433  			}
   434  		}
   435  
   436  		teamFilters = openInviteFilter
   437  	}
   438  
   439  	var groupConstrainedFilter sq.Sqlizer
   440  	if opts.GroupConstrained != nil {
   441  		if *opts.GroupConstrained {
   442  			groupConstrainedFilter = sq.Eq{"GroupConstrained": true}
   443  		} else {
   444  			groupConstrainedFilter = sq.Or{
   445  				sq.NotEq{"GroupConstrained": true},
   446  				sq.Eq{"GroupConstrained": nil},
   447  			}
   448  		}
   449  
   450  		if teamFilters == nil {
   451  			teamFilters = groupConstrainedFilter
   452  		} else {
   453  			teamFilters = sq.Or{teamFilters, groupConstrainedFilter}
   454  		}
   455  	}
   456  
   457  	query = query.Where(teamFilters)
   458  
   459  	return query
   460  }
   461  
   462  // SearchAll returns from the database a list of teams that match the Name or DisplayName
   463  // passed as the term search parameter.
   464  func (s SqlTeamStore) SearchAll(term string, opts *model.TeamSearch) ([]*model.Team, *model.AppError) {
   465  	var teams []*model.Team
   466  
   467  	queryString, args, err := s.teamSearchQuery(term, opts, false).ToSql()
   468  	if err != nil {
   469  		return nil, model.NewAppError("SqlTeamStore.SearchAll", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError)
   470  	}
   471  
   472  	if _, err = s.GetReplica().Select(&teams, queryString, args...); err != nil {
   473  		return nil, model.NewAppError("SqlTeamStore.SearchAll", "store.sql_team.search_all_team.app_error", nil, "term="+term+", "+err.Error(), http.StatusInternalServerError)
   474  	}
   475  
   476  	return teams, nil
   477  }
   478  
   479  // SearchAllPaged returns a teams list and the total count of teams that matched the search.
   480  func (s SqlTeamStore) SearchAllPaged(term string, opts *model.TeamSearch) ([]*model.Team, int64, *model.AppError) {
   481  	var teams []*model.Team
   482  	var totalCount int64
   483  
   484  	queryString, args, err := s.teamSearchQuery(term, opts, false).ToSql()
   485  	if err != nil {
   486  		return nil, 0, model.NewAppError("SqlTeamStore.SearchAllPage", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError)
   487  	}
   488  	if _, err = s.GetReplica().Select(&teams, queryString, args...); err != nil {
   489  		return nil, 0, model.NewAppError("SqlTeamStore.SearchAllPage", "store.sql_team.search_all_team.app_error", nil, "term="+term+", "+err.Error(), http.StatusInternalServerError)
   490  	}
   491  
   492  	queryString, args, err = s.teamSearchQuery(term, opts, true).ToSql()
   493  	if err != nil {
   494  		return nil, 0, model.NewAppError("SqlTeamStore.SearchAllPage", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError)
   495  	}
   496  	totalCount, err = s.GetReplica().SelectInt(queryString, args...)
   497  	if err != nil {
   498  		return nil, 0, model.NewAppError("SqlTeamStore.SearchAllPage", "store.sql_team.search_all_team.app_error", nil, "term="+term+", "+err.Error(), http.StatusInternalServerError)
   499  	}
   500  
   501  	return teams, totalCount, nil
   502  }
   503  
   504  // SearchOpen returns from the database a list of public teams that match the Name or DisplayName
   505  // passed as the term search parameter.
   506  func (s SqlTeamStore) SearchOpen(term string) ([]*model.Team, *model.AppError) {
   507  	var teams []*model.Team
   508  
   509  	term = sanitizeSearchTerm(term, "\\")
   510  	term = wildcardSearchTerm(term)
   511  	query := s.teamsQuery.Where(sq.Eq{"Type": "O", "AllowOpenInvite": true})
   512  	if s.DriverName() == model.DATABASE_DRIVER_MYSQL {
   513  		query = query.Where(sq.Or{sq.Like{"Name": term}, sq.Like{"DisplayName": term}})
   514  	} else {
   515  		query = query.Where(sq.Or{sq.ILike{"Name": term}, sq.ILike{"DisplayName": term}})
   516  	}
   517  
   518  	queryString, args, err := query.ToSql()
   519  	if err != nil {
   520  		return nil, model.NewAppError("SqlTeamStore.SearchOpen", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError)
   521  	}
   522  
   523  	if _, err = s.GetReplica().Select(&teams, queryString, args...); err != nil {
   524  		return nil, model.NewAppError("SqlTeamStore.SearchOpen", "store.sql_team.search_open_team.app_error", nil, "term="+term+", "+err.Error(), http.StatusInternalServerError)
   525  	}
   526  
   527  	return teams, nil
   528  }
   529  
   530  // SearchPrivate returns from the database a list of private teams that match the Name or DisplayName
   531  // passed as the term search parameter.
   532  func (s SqlTeamStore) SearchPrivate(term string) ([]*model.Team, *model.AppError) {
   533  	var teams []*model.Team
   534  
   535  	term = sanitizeSearchTerm(term, "\\")
   536  	term = wildcardSearchTerm(term)
   537  	query := s.teamsQuery.Where(sq.Eq{"Type": "O", "AllowOpenInvite": false})
   538  	if s.DriverName() == model.DATABASE_DRIVER_MYSQL {
   539  		query = query.Where(sq.Or{sq.Like{"Name": term}, sq.Like{"DisplayName": term}})
   540  	} else {
   541  		query = query.Where(sq.Or{sq.ILike{"Name": term}, sq.ILike{"DisplayName": term}})
   542  	}
   543  
   544  	queryString, args, err := query.ToSql()
   545  	if err != nil {
   546  		return nil, model.NewAppError("SqlTeamStore.SearchPrivate", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError)
   547  	}
   548  
   549  	if _, err = s.GetReplica().Select(&teams, queryString, args...); err != nil {
   550  		return nil, model.NewAppError("SqlTeamStore.SearchPrivate", "store.sql_team.search_private_team.app_error", nil, "term="+term+", "+err.Error(), http.StatusInternalServerError)
   551  	}
   552  	return teams, nil
   553  }
   554  
   555  // GetAll returns all teams
   556  func (s SqlTeamStore) GetAll() ([]*model.Team, *model.AppError) {
   557  	var teams []*model.Team
   558  
   559  	query, args, err := s.teamsQuery.OrderBy("DisplayName").ToSql()
   560  
   561  	if err != nil {
   562  		return nil, model.NewAppError("SqlTeamStore.GetAllTeams", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError)
   563  	}
   564  
   565  	_, err = s.GetReplica().Select(&teams, query, args...)
   566  	if err != nil {
   567  		return nil, model.NewAppError("SqlTeamStore.GetAllTeams", "store.sql_team.get_all.app_error", nil, err.Error(), http.StatusInternalServerError)
   568  	}
   569  	return teams, nil
   570  }
   571  
   572  // GetAllPage returns teams, up to a total limit passed as parameter and paginated by offset number passed as parameter.
   573  func (s SqlTeamStore) GetAllPage(offset int, limit int) ([]*model.Team, *model.AppError) {
   574  	var teams []*model.Team
   575  
   576  	query, args, err := s.teamsQuery.
   577  		OrderBy("DisplayName").
   578  		Limit(uint64(limit)).
   579  		Offset(uint64(offset)).ToSql()
   580  
   581  	if err != nil {
   582  		return nil, model.NewAppError("SqlTeamStore.GetAllTeams", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError)
   583  	}
   584  	if _, err = s.GetReplica().Select(&teams, query, args...); err != nil {
   585  		return nil, model.NewAppError("SqlTeamStore.GetAllTeams",
   586  			"store.sql_team.get_all.app_error", nil, err.Error(), http.StatusInternalServerError)
   587  	}
   588  
   589  	return teams, nil
   590  }
   591  
   592  // GetTeamsByUserId returns from the database all teams that userId belongs to.
   593  func (s SqlTeamStore) GetTeamsByUserId(userId string) ([]*model.Team, *model.AppError) {
   594  	var teams []*model.Team
   595  	query, args, err := s.teamsQuery.
   596  		Join("TeamMembers ON TeamMembers.TeamId = Teams.Id").
   597  		Where(sq.Eq{"TeamMembers.UserId": userId, "TeamMembers.DeleteAt": 0, "Teams.DeleteAt": 0}).ToSql()
   598  
   599  	if err != nil {
   600  		return nil, model.NewAppError("SqlTeamStore.GetTeamsByUserId", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError)
   601  	}
   602  
   603  	if _, err = s.GetReplica().Select(&teams, query, args...); err != nil {
   604  		return nil, model.NewAppError("SqlTeamStore.GetTeamsByUserId", "store.sql_team.get_all.app_error", nil, err.Error(), http.StatusInternalServerError)
   605  	}
   606  
   607  	return teams, nil
   608  }
   609  
   610  // GetAllPrivateTeamListing returns all private teams.
   611  func (s SqlTeamStore) GetAllPrivateTeamListing() ([]*model.Team, *model.AppError) {
   612  	query, args, err := s.teamsQuery.Where(sq.Eq{"AllowOpenInvite": false}).
   613  		OrderBy("DisplayName").ToSql()
   614  	if err != nil {
   615  		return nil, model.NewAppError("SqlTeamStore.GetAllPrivateTeamListing", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError)
   616  	}
   617  	var data []*model.Team
   618  	if _, err = s.GetReplica().Select(&data, query, args...); err != nil {
   619  		return nil, model.NewAppError("SqlTeamStore.GetAllPrivateTeamListing", "store.sql_team.get_all_private_team_listing.app_error", nil, err.Error(), http.StatusInternalServerError)
   620  	}
   621  	return data, nil
   622  }
   623  
   624  // GetAllPublicTeamPageListing returns public teams, up to a total limit passed as parameter and paginated by offset number passed as parameter.
   625  func (s SqlTeamStore) GetAllPublicTeamPageListing(offset int, limit int) ([]*model.Team, *model.AppError) {
   626  	query, args, err := s.teamsQuery.Where(sq.Eq{"AllowOpenInvite": true}).
   627  		OrderBy("DisplayName").
   628  		Limit(uint64(limit)).
   629  		Offset(uint64(offset)).ToSql()
   630  	if err != nil {
   631  		return nil, model.NewAppError("SqlTeamStore.GetAllPublicTeamPageListing", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError)
   632  	}
   633  
   634  	var data []*model.Team
   635  	if _, err = s.GetReplica().Select(&data, query, args...); err != nil {
   636  		return nil, model.NewAppError("SqlTeamStore.GetAllPublicTeamPageListing", "store.sql_team.get_all_private_team_listing.app_error", nil, err.Error(), http.StatusInternalServerError)
   637  	}
   638  
   639  	return data, nil
   640  }
   641  
   642  // GetAllPrivateTeamPageListing returns private teams, up to a total limit passed as paramater and paginated by offset number passed as parameter.
   643  func (s SqlTeamStore) GetAllPrivateTeamPageListing(offset int, limit int) ([]*model.Team, *model.AppError) {
   644  	query, args, err := s.teamsQuery.Where(sq.Eq{"AllowOpenInvite": false}).
   645  		OrderBy("DisplayName").
   646  		Limit(uint64(limit)).
   647  		Offset(uint64(offset)).ToSql()
   648  
   649  	if err != nil {
   650  		return nil, model.NewAppError("SqlTeamStore.GetAllPrivateTeamPageListing", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError)
   651  	}
   652  
   653  	var data []*model.Team
   654  	if _, err = s.GetReplica().Select(&data, query, args...); err != nil {
   655  		return nil, model.NewAppError("SqlTeamStore.GetAllPrivateTeamPageListing", "store.sql_team.get_all_private_team_page_listing.app_error", nil, err.Error(), http.StatusInternalServerError)
   656  	}
   657  
   658  	return data, nil
   659  }
   660  
   661  // GetAllTeamListing returns all public teams.
   662  func (s SqlTeamStore) GetAllTeamListing() ([]*model.Team, *model.AppError) {
   663  	query, args, err := s.teamsQuery.Where(sq.Eq{"AllowOpenInvite": true}).
   664  		OrderBy("DisplayName").ToSql()
   665  
   666  	if err != nil {
   667  		return nil, model.NewAppError("SqlTeamStore.GetAllTeamListing", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError)
   668  	}
   669  
   670  	var data []*model.Team
   671  	if _, err = s.GetReplica().Select(&data, query, args...); err != nil {
   672  		return nil, model.NewAppError("SqlTeamStore.GetAllTeamListing", "store.sql_team.get_all_team_listing.app_error", nil, err.Error(), http.StatusInternalServerError)
   673  	}
   674  
   675  	return data, nil
   676  }
   677  
   678  // GetAllTeamPageListing returns public teams, up to a total limit passed as parameter and paginated by offset number passed as parameter.
   679  func (s SqlTeamStore) GetAllTeamPageListing(offset int, limit int) ([]*model.Team, *model.AppError) {
   680  	query, args, err := s.teamsQuery.Where(sq.Eq{"AllowOpenInvite": true}).
   681  		OrderBy("DisplayName").
   682  		Limit(uint64(limit)).
   683  		Offset(uint64(offset)).ToSql()
   684  
   685  	if err != nil {
   686  		return nil, model.NewAppError("SqlTeamStore.GetAllTeamPageListing", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError)
   687  	}
   688  
   689  	var teams []*model.Team
   690  	if _, err = s.GetReplica().Select(&teams, query, args...); err != nil {
   691  		return nil, model.NewAppError("SqlTeamStore.GetAllTeamPageListing", "store.sql_team.get_all_team_listing.app_error", nil, err.Error(), http.StatusInternalServerError)
   692  	}
   693  
   694  	return teams, nil
   695  }
   696  
   697  // PermanentDelete permanently deletes from the database the team entry that matches the teamId passed as parameter.
   698  // To soft-delete the team you can Update it with the DeleteAt field set to the current millisecond using model.GetMillis()
   699  func (s SqlTeamStore) PermanentDelete(teamId string) *model.AppError {
   700  	sql, args, err := s.getQueryBuilder().
   701  		Delete("Teams").
   702  		Where(sq.Eq{"Id": teamId}).ToSql()
   703  	if err != nil {
   704  		return model.NewAppError("SqlTeamStore.Delete", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError)
   705  	}
   706  	if _, err = s.GetMaster().Exec(sql, args...); err != nil {
   707  		return model.NewAppError("SqlTeamStore.Delete", "store.sql_team.permanent_delete.app_error", nil, "teamId="+teamId+", "+err.Error(), http.StatusInternalServerError)
   708  	}
   709  	return nil
   710  }
   711  
   712  // AnalyticsPublicTeamCount returns the number of active public teams.
   713  func (s SqlTeamStore) AnalyticsPublicTeamCount() (int64, *model.AppError) {
   714  	query, args, err := s.getQueryBuilder().
   715  		Select("COUNT(*) FROM Teams").
   716  		Where(sq.Eq{"DeleteAt": 0, "AllowOpenInvite": true}).ToSql()
   717  
   718  	if err != nil {
   719  		return 0, model.NewAppError("SqlTeamStore.AnalyticsPublicTeamCount", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError)
   720  	}
   721  
   722  	c, err := s.GetReplica().SelectInt(query, args...)
   723  
   724  	if err != nil {
   725  		return int64(0), model.NewAppError("SqlTeamStore.AnalyticsPublicTeamCount", "store.sql_team.analytics_public_team_count.app_error", nil, err.Error(), http.StatusInternalServerError)
   726  	}
   727  
   728  	return c, nil
   729  }
   730  
   731  // AnalyticsPrivateTeamCount returns the number of active private teams.
   732  func (s SqlTeamStore) AnalyticsPrivateTeamCount() (int64, *model.AppError) {
   733  	query, args, err := s.getQueryBuilder().
   734  		Select("COUNT(*) FROM Teams").
   735  		Where(sq.Eq{"DeleteAt": 0, "AllowOpenInvite": false}).ToSql()
   736  
   737  	if err != nil {
   738  		return 0, model.NewAppError("SqlTeamStore.AnalyticsPrivateTeamCount", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError)
   739  	}
   740  	c, err := s.GetReplica().SelectInt(query, args...)
   741  
   742  	if err != nil {
   743  		return int64(0), model.NewAppError("SqlTeamStore.AnalyticsPrivateTeamCount", "store.sql_team.analytics_private_team_count.app_error", nil, err.Error(), http.StatusInternalServerError)
   744  	}
   745  
   746  	return c, nil
   747  }
   748  
   749  // AnalyticsTeamCount returns the total number of teams including deleted teams if parameter passed is set to 'true'.
   750  func (s SqlTeamStore) AnalyticsTeamCount(includeDeleted bool) (int64, *model.AppError) {
   751  	query := s.getQueryBuilder().Select("COUNT(*) FROM Teams")
   752  	if !includeDeleted {
   753  		query = query.Where(sq.Eq{"DeleteAt": 0})
   754  	}
   755  
   756  	queryString, args, err := query.ToSql()
   757  	if err != nil {
   758  		return 0, model.NewAppError("SqlTeamStore.AnalyticsTeamCount", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError)
   759  	}
   760  
   761  	c, err := s.GetReplica().SelectInt(queryString, args...)
   762  
   763  	if err != nil {
   764  		return int64(0), model.NewAppError("SqlTeamStore.AnalyticsTeamCount", "store.sql_team.analytics_team_count.app_error", nil, err.Error(), http.StatusInternalServerError)
   765  	}
   766  
   767  	return c, nil
   768  }
   769  
   770  func (s SqlTeamStore) getTeamMembersWithSchemeSelectQuery() sq.SelectBuilder {
   771  	return s.getQueryBuilder().
   772  		Select(
   773  			"TeamMembers.*",
   774  			"TeamScheme.DefaultTeamGuestRole TeamSchemeDefaultGuestRole",
   775  			"TeamScheme.DefaultTeamUserRole TeamSchemeDefaultUserRole",
   776  			"TeamScheme.DefaultTeamAdminRole TeamSchemeDefaultAdminRole",
   777  		).
   778  		From("TeamMembers").
   779  		LeftJoin("Teams ON TeamMembers.TeamId = Teams.Id").
   780  		LeftJoin("Schemes TeamScheme ON Teams.SchemeId = TeamScheme.Id")
   781  }
   782  
   783  func (s SqlTeamStore) SaveMultipleMembers(members []*model.TeamMember, maxUsersPerTeam int) ([]*model.TeamMember, *model.AppError) {
   784  	newTeamMembers := map[string]int{}
   785  	users := map[string]bool{}
   786  	for _, member := range members {
   787  		newTeamMembers[member.TeamId] = 0
   788  	}
   789  
   790  	for _, member := range members {
   791  		newTeamMembers[member.TeamId]++
   792  		users[member.UserId] = true
   793  
   794  		if err := member.IsValid(); err != nil {
   795  			return nil, err
   796  		}
   797  	}
   798  
   799  	teams := []string{}
   800  	for team := range newTeamMembers {
   801  		teams = append(teams, team)
   802  	}
   803  
   804  	defaultTeamRolesByTeam := map[string]struct {
   805  		Id    string
   806  		Guest sql.NullString
   807  		User  sql.NullString
   808  		Admin sql.NullString
   809  	}{}
   810  
   811  	queryRoles := s.getQueryBuilder().
   812  		Select(
   813  			"Teams.Id as Id",
   814  			"TeamScheme.DefaultTeamGuestRole as Guest",
   815  			"TeamScheme.DefaultTeamUserRole as User",
   816  			"TeamScheme.DefaultTeamAdminRole as Admin",
   817  		).
   818  		From("Teams").
   819  		LeftJoin("Schemes TeamScheme ON Teams.SchemeId = TeamScheme.Id").
   820  		Where(sq.Eq{"Teams.Id": teams})
   821  
   822  	sqlRolesQuery, argsRoles, err := queryRoles.ToSql()
   823  	if err != nil {
   824  		return nil, model.NewAppError("SqlUserStore.Save", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError)
   825  	}
   826  	var defaultTeamsRoles []struct {
   827  		Id    string
   828  		Guest sql.NullString
   829  		User  sql.NullString
   830  		Admin sql.NullString
   831  	}
   832  	_, err = s.GetMaster().Select(&defaultTeamsRoles, sqlRolesQuery, argsRoles...)
   833  	if err != nil {
   834  		return nil, model.NewAppError("SqlUserStore.Save", "store.sql_user.save.member_count.app_error", nil, err.Error(), http.StatusInternalServerError)
   835  	}
   836  
   837  	for _, defaultRoles := range defaultTeamsRoles {
   838  		defaultTeamRolesByTeam[defaultRoles.Id] = defaultRoles
   839  	}
   840  
   841  	if maxUsersPerTeam >= 0 {
   842  		queryCount := s.getQueryBuilder().
   843  			Select(
   844  				"COUNT(0) as Count, TeamMembers.TeamId as TeamId",
   845  			).
   846  			From("TeamMembers").
   847  			Join("Users ON TeamMembers.UserId = Users.Id").
   848  			Where(sq.Eq{"TeamMembers.TeamId": teams}).
   849  			Where(sq.Eq{"TeamMembers.DeleteAt": 0}).
   850  			Where(sq.Eq{"Users.DeleteAt": 0}).
   851  			GroupBy("TeamMembers.TeamId")
   852  
   853  		sqlCountQuery, argsCount, errCount := queryCount.ToSql()
   854  		if errCount != nil {
   855  			return nil, model.NewAppError("SqlUserStore.Save", "store.sql.build_query.app_error", nil, errCount.Error(), http.StatusInternalServerError)
   856  		}
   857  
   858  		var counters []struct {
   859  			Count  int    `db:"Count"`
   860  			TeamId string `db:"TeamId"`
   861  		}
   862  
   863  		_, err = s.GetMaster().Select(&counters, sqlCountQuery, argsCount...)
   864  		if err != nil {
   865  			return nil, model.NewAppError("SqlUserStore.Save", "store.sql_user.save.member_count.app_error", nil, err.Error(), http.StatusInternalServerError)
   866  		}
   867  
   868  		for teamId, newMembers := range newTeamMembers {
   869  			existingMembers := 0
   870  			for _, counter := range counters {
   871  				if counter.TeamId == teamId {
   872  					existingMembers = counter.Count
   873  				}
   874  			}
   875  			if existingMembers+newMembers > maxUsersPerTeam {
   876  				return nil, model.NewAppError("SqlUserStore.Save", "store.sql_user.save.max_accounts.app_error", nil, "", http.StatusBadRequest)
   877  			}
   878  		}
   879  	}
   880  
   881  	query := s.getQueryBuilder().Insert("TeamMembers").Columns(teamMemberSliceColumns()...)
   882  	for _, member := range members {
   883  		query = query.Values(teamMemberToSlice(member)...)
   884  	}
   885  
   886  	sql, args, err := query.ToSql()
   887  	if err != nil {
   888  		return nil, model.NewAppError("SqlTeamStore.SaveMember", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError)
   889  	}
   890  
   891  	if _, err = s.GetMaster().Exec(sql, args...); err != nil {
   892  		if IsUniqueConstraintError(err, []string{"TeamId", "teammembers_pkey", "PRIMARY"}) {
   893  			return nil, model.NewAppError("SqlTeamStore.SaveMember", TEAM_MEMBER_EXISTS_ERROR, nil, err.Error(), http.StatusBadRequest)
   894  		}
   895  		return nil, model.NewAppError("SqlTeamStore.SaveMember", "store.sql_team.save_member.save.app_error", nil, err.Error(), http.StatusInternalServerError)
   896  	}
   897  
   898  	newMembers := []*model.TeamMember{}
   899  	for _, member := range members {
   900  		s.InvalidateAllTeamIdsForUser(member.UserId)
   901  		defaultTeamGuestRole := defaultTeamRolesByTeam[member.TeamId].Guest.String
   902  		defaultTeamUserRole := defaultTeamRolesByTeam[member.TeamId].User.String
   903  		defaultTeamAdminRole := defaultTeamRolesByTeam[member.TeamId].Admin.String
   904  		rolesResult := getTeamRoles(member.SchemeGuest, member.SchemeUser, member.SchemeAdmin, defaultTeamGuestRole, defaultTeamUserRole, defaultTeamAdminRole, strings.Fields(member.ExplicitRoles))
   905  		newMember := *member
   906  		newMember.SchemeGuest = rolesResult.schemeGuest
   907  		newMember.SchemeUser = rolesResult.schemeUser
   908  		newMember.SchemeAdmin = rolesResult.schemeAdmin
   909  		newMember.Roles = strings.Join(rolesResult.roles, " ")
   910  		newMember.ExplicitRoles = strings.Join(rolesResult.explicitRoles, " ")
   911  		newMembers = append(newMembers, &newMember)
   912  	}
   913  
   914  	return newMembers, nil
   915  }
   916  
   917  func (s SqlTeamStore) SaveMember(member *model.TeamMember, maxUsersPerTeam int) (*model.TeamMember, *model.AppError) {
   918  	members, err := s.SaveMultipleMembers([]*model.TeamMember{member}, maxUsersPerTeam)
   919  	if err != nil {
   920  		return nil, err
   921  	}
   922  	return members[0], nil
   923  }
   924  
   925  func (s SqlTeamStore) UpdateMultipleMembers(members []*model.TeamMember) ([]*model.TeamMember, *model.AppError) {
   926  	teams := []string{}
   927  	for _, member := range members {
   928  		member.PreUpdate()
   929  
   930  		if err := member.IsValid(); err != nil {
   931  			return nil, err
   932  		}
   933  
   934  		if _, err := s.GetMaster().Update(NewTeamMemberFromModel(member)); err != nil {
   935  			return nil, model.NewAppError("SqlTeamStore.UpdateMember", "store.sql_team.save_member.save.app_error", nil, err.Error(), http.StatusInternalServerError)
   936  		}
   937  		teams = append(teams, member.TeamId)
   938  	}
   939  
   940  	query := s.getQueryBuilder().
   941  		Select(
   942  			"Teams.Id as Id",
   943  			"TeamScheme.DefaultTeamGuestRole as Guest",
   944  			"TeamScheme.DefaultTeamUserRole as User",
   945  			"TeamScheme.DefaultTeamAdminRole as Admin",
   946  		).
   947  		From("Teams").
   948  		LeftJoin("Schemes TeamScheme ON Teams.SchemeId = TeamScheme.Id").
   949  		Where(sq.Eq{"Teams.Id": teams})
   950  
   951  	sqlQuery, args, err := query.ToSql()
   952  	if err != nil {
   953  		return nil, model.NewAppError("SqlUserStore.Save", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError)
   954  	}
   955  	var defaultTeamsRoles []struct {
   956  		Id    string
   957  		Guest sql.NullString
   958  		User  sql.NullString
   959  		Admin sql.NullString
   960  	}
   961  	_, err = s.GetMaster().Select(&defaultTeamsRoles, sqlQuery, args...)
   962  	if err != nil {
   963  		return nil, model.NewAppError("SqlUserStore.Save", "store.sql_user.save.member_count.app_error", nil, err.Error(), http.StatusInternalServerError)
   964  	}
   965  
   966  	defaultTeamRolesByTeam := map[string]struct {
   967  		Id    string
   968  		Guest sql.NullString
   969  		User  sql.NullString
   970  		Admin sql.NullString
   971  	}{}
   972  	for _, defaultRoles := range defaultTeamsRoles {
   973  		defaultTeamRolesByTeam[defaultRoles.Id] = defaultRoles
   974  	}
   975  
   976  	updatedMembers := []*model.TeamMember{}
   977  	for _, member := range members {
   978  		s.InvalidateAllTeamIdsForUser(member.UserId)
   979  		defaultTeamGuestRole := defaultTeamRolesByTeam[member.TeamId].Guest.String
   980  		defaultTeamUserRole := defaultTeamRolesByTeam[member.TeamId].User.String
   981  		defaultTeamAdminRole := defaultTeamRolesByTeam[member.TeamId].Admin.String
   982  		rolesResult := getTeamRoles(member.SchemeGuest, member.SchemeUser, member.SchemeAdmin, defaultTeamGuestRole, defaultTeamUserRole, defaultTeamAdminRole, strings.Fields(member.ExplicitRoles))
   983  		updatedMember := *member
   984  		updatedMember.SchemeGuest = rolesResult.schemeGuest
   985  		updatedMember.SchemeUser = rolesResult.schemeUser
   986  		updatedMember.SchemeAdmin = rolesResult.schemeAdmin
   987  		updatedMember.Roles = strings.Join(rolesResult.roles, " ")
   988  		updatedMember.ExplicitRoles = strings.Join(rolesResult.explicitRoles, " ")
   989  		updatedMembers = append(updatedMembers, &updatedMember)
   990  	}
   991  
   992  	return updatedMembers, nil
   993  }
   994  
   995  func (s SqlTeamStore) UpdateMember(member *model.TeamMember) (*model.TeamMember, *model.AppError) {
   996  	members, err := s.UpdateMultipleMembers([]*model.TeamMember{member})
   997  	if err != nil {
   998  		return nil, err
   999  	}
  1000  	return members[0], nil
  1001  }
  1002  
  1003  func (s SqlTeamStore) GetMember(teamId string, userId string) (*model.TeamMember, *model.AppError) {
  1004  	query := s.getTeamMembersWithSchemeSelectQuery().
  1005  		Where(sq.Eq{"TeamMembers.TeamId": teamId}).
  1006  		Where(sq.Eq{"TeamMembers.UserId": userId})
  1007  
  1008  	queryString, args, err := query.ToSql()
  1009  	if err != nil {
  1010  		return nil, model.NewAppError("SqlTeamStore.GetMember", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError)
  1011  	}
  1012  
  1013  	var dbMember teamMemberWithSchemeRoles
  1014  	err = s.GetReplica().SelectOne(&dbMember, queryString, args...)
  1015  	if err != nil {
  1016  		if err == sql.ErrNoRows {
  1017  			return nil, model.NewAppError("SqlTeamStore.GetMember", "store.sql_team.get_member.missing.app_error", nil, "teamId="+teamId+" userId="+userId+" "+err.Error(), http.StatusNotFound)
  1018  		}
  1019  		return nil, model.NewAppError("SqlTeamStore.GetMember", "store.sql_team.get_member.app_error", nil, "teamId="+teamId+" userId="+userId+" "+err.Error(), http.StatusInternalServerError)
  1020  	}
  1021  
  1022  	return dbMember.ToModel(), nil
  1023  }
  1024  
  1025  func (s SqlTeamStore) GetMembers(teamId string, offset int, limit int, teamMembersGetOptions *model.TeamMembersGetOptions) ([]*model.TeamMember, *model.AppError) {
  1026  	query := s.getTeamMembersWithSchemeSelectQuery().
  1027  		Where(sq.Eq{"TeamMembers.TeamId": teamId}).
  1028  		Where(sq.Eq{"TeamMembers.DeleteAt": 0}).
  1029  		Limit(uint64(limit)).
  1030  		Offset(uint64(offset))
  1031  
  1032  	if teamMembersGetOptions == nil || teamMembersGetOptions.Sort == "" {
  1033  		query = query.OrderBy("UserId")
  1034  	}
  1035  
  1036  	if teamMembersGetOptions != nil {
  1037  		if teamMembersGetOptions.Sort == model.USERNAME || teamMembersGetOptions.ExcludeDeletedUsers {
  1038  			query = query.LeftJoin("Users ON TeamMembers.UserId = Users.Id")
  1039  		}
  1040  
  1041  		if teamMembersGetOptions.ExcludeDeletedUsers {
  1042  			query = query.Where(sq.Eq{"Users.DeleteAt": 0})
  1043  		}
  1044  
  1045  		if teamMembersGetOptions.Sort == model.USERNAME {
  1046  			query = query.OrderBy(model.USERNAME)
  1047  		}
  1048  
  1049  		query = applyTeamMemberViewRestrictionsFilter(query, teamId, teamMembersGetOptions.ViewRestrictions)
  1050  	}
  1051  
  1052  	queryString, args, err := query.ToSql()
  1053  	if err != nil {
  1054  		return nil, model.NewAppError("SqlTeamStore.GetMembers", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError)
  1055  	}
  1056  
  1057  	var dbMembers teamMemberWithSchemeRolesList
  1058  	_, err = s.GetReplica().Select(&dbMembers, queryString, args...)
  1059  	if err != nil {
  1060  		return nil, model.NewAppError("SqlTeamStore.GetMembers", "store.sql_team.get_members.app_error", nil, "teamId="+teamId+" "+err.Error(), http.StatusInternalServerError)
  1061  	}
  1062  
  1063  	return dbMembers.ToModel(), nil
  1064  }
  1065  
  1066  func (s SqlTeamStore) GetTotalMemberCount(teamId string, restrictions *model.ViewUsersRestrictions) (int64, *model.AppError) {
  1067  	query := s.getQueryBuilder().
  1068  		Select("count(DISTINCT TeamMembers.UserId)").
  1069  		From("TeamMembers, Users").
  1070  		Where("TeamMembers.DeleteAt = 0").
  1071  		Where("TeamMembers.UserId = Users.Id").
  1072  		Where(sq.Eq{"TeamMembers.TeamId": teamId})
  1073  
  1074  	query = applyTeamMemberViewRestrictionsFilterForStats(query, teamId, restrictions)
  1075  	queryString, args, err := query.ToSql()
  1076  	if err != nil {
  1077  		return int64(0), model.NewAppError("SqlTeamStore.GetTotalMemberCount", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError)
  1078  	}
  1079  
  1080  	count, err := s.GetReplica().SelectInt(queryString, args...)
  1081  	if err != nil {
  1082  		return int64(0), model.NewAppError("SqlTeamStore.GetTotalMemberCount", "store.sql_team.get_member_count.app_error", nil, "teamId="+teamId+" "+err.Error(), http.StatusInternalServerError)
  1083  	}
  1084  	return count, nil
  1085  }
  1086  
  1087  func (s SqlTeamStore) GetActiveMemberCount(teamId string, restrictions *model.ViewUsersRestrictions) (int64, *model.AppError) {
  1088  	query := s.getQueryBuilder().
  1089  		Select("count(DISTINCT TeamMembers.UserId)").
  1090  		From("TeamMembers, Users").
  1091  		Where("TeamMembers.DeleteAt = 0").
  1092  		Where("TeamMembers.UserId = Users.Id").
  1093  		Where("Users.DeleteAt = 0").
  1094  		Where(sq.Eq{"TeamMembers.TeamId": teamId})
  1095  
  1096  	query = applyTeamMemberViewRestrictionsFilterForStats(query, teamId, restrictions)
  1097  	queryString, args, err := query.ToSql()
  1098  	if err != nil {
  1099  		return 0, model.NewAppError("SqlTeamStore.GetActiveMemberCount", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError)
  1100  	}
  1101  
  1102  	count, err := s.GetReplica().SelectInt(queryString, args...)
  1103  	if err != nil {
  1104  		return 0, model.NewAppError("SqlTeamStore.GetActiveMemberCount", "store.sql_team.get_active_member_count.app_error", nil, "teamId="+teamId+" "+err.Error(), http.StatusInternalServerError)
  1105  	}
  1106  
  1107  	return count, nil
  1108  }
  1109  
  1110  func (s SqlTeamStore) GetMembersByIds(teamId string, userIds []string, restrictions *model.ViewUsersRestrictions) ([]*model.TeamMember, *model.AppError) {
  1111  	if len(userIds) == 0 {
  1112  		return nil, model.NewAppError("SqlTeamStore.GetMembersByIds", "store.sql_team.get_members_by_ids.app_error", nil, "Invalid list of user ids", http.StatusInternalServerError)
  1113  	}
  1114  
  1115  	query := s.getTeamMembersWithSchemeSelectQuery().
  1116  		Where(sq.Eq{"TeamMembers.TeamId": teamId}).
  1117  		Where(sq.Eq{"TeamMembers.UserId": userIds}).
  1118  		Where(sq.Eq{"TeamMembers.DeleteAt": 0})
  1119  
  1120  	query = applyTeamMemberViewRestrictionsFilter(query, teamId, restrictions)
  1121  
  1122  	queryString, args, err := query.ToSql()
  1123  	if err != nil {
  1124  		return nil, model.NewAppError("SqlTeamStore.GetMembersByIds", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError)
  1125  	}
  1126  
  1127  	var dbMembers teamMemberWithSchemeRolesList
  1128  	if _, err = s.GetReplica().Select(&dbMembers, queryString, args...); err != nil {
  1129  		return nil, model.NewAppError("SqlTeamStore.GetMembersByIds", "store.sql_team.get_members_by_ids.app_error", nil, "teamId="+teamId+" "+err.Error(), http.StatusInternalServerError)
  1130  	}
  1131  	return dbMembers.ToModel(), nil
  1132  }
  1133  
  1134  func (s SqlTeamStore) GetTeamsForUser(userId string) ([]*model.TeamMember, *model.AppError) {
  1135  	query := s.getTeamMembersWithSchemeSelectQuery().
  1136  		Where(sq.Eq{"TeamMembers.UserId": userId})
  1137  
  1138  	queryString, args, err := query.ToSql()
  1139  	if err != nil {
  1140  		return nil, model.NewAppError("SqlTeamStore.GetMembers", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError)
  1141  	}
  1142  
  1143  	var dbMembers teamMemberWithSchemeRolesList
  1144  	_, err = s.GetReplica().Select(&dbMembers, queryString, args...)
  1145  	if err != nil {
  1146  		return nil, model.NewAppError("SqlTeamStore.GetMembers", "store.sql_team.get_members.app_error", nil, "userId="+userId+" "+err.Error(), http.StatusInternalServerError)
  1147  	}
  1148  
  1149  	return dbMembers.ToModel(), nil
  1150  }
  1151  
  1152  func (s SqlTeamStore) GetTeamsForUserWithPagination(userId string, page, perPage int) ([]*model.TeamMember, *model.AppError) {
  1153  	query := s.getTeamMembersWithSchemeSelectQuery().
  1154  		Where(sq.Eq{"TeamMembers.UserId": userId}).
  1155  		Limit(uint64(perPage)).
  1156  		Offset(uint64(page * perPage))
  1157  
  1158  	queryString, args, err := query.ToSql()
  1159  	if err != nil {
  1160  		return nil, model.NewAppError("SqlTeamStore.GetTeamsForUserWithPagination", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError)
  1161  	}
  1162  
  1163  	var dbMembers teamMemberWithSchemeRolesList
  1164  	_, err = s.GetReplica().Select(&dbMembers, queryString, args...)
  1165  	if err != nil {
  1166  		return nil, model.NewAppError("SqlTeamStore.GetTeamsForUserWithPagination", "store.sql_team.get_members.app_error", nil, "userId="+userId+" "+err.Error(), http.StatusInternalServerError)
  1167  	}
  1168  
  1169  	return dbMembers.ToModel(), nil
  1170  }
  1171  
  1172  func (s SqlTeamStore) GetChannelUnreadsForAllTeams(excludeTeamId, userId string) ([]*model.ChannelUnread, *model.AppError) {
  1173  	query, args, err := s.getQueryBuilder().
  1174  		Select("Channels.TeamId TeamId", "Channels.Id ChannelId", "(Channels.TotalMsgCount - ChannelMembers.MsgCount) MsgCount", "ChannelMembers.MentionCount MentionCount", "ChannelMembers.NotifyProps NotifyProps").
  1175  		From("Channels").
  1176  		Join("ChannelMembers ON Id = ChannelId").
  1177  		Where(sq.Eq{"UserId": userId, "DeleteAt": 0}).
  1178  		Where(sq.NotEq{"TeamId": excludeTeamId}).ToSql()
  1179  
  1180  	if err != nil {
  1181  		return nil, model.NewAppError("SqlTeamStore.GetChannelUnreadsForAllTeams", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError)
  1182  	}
  1183  	var data []*model.ChannelUnread
  1184  	_, err = s.GetReplica().Select(&data, query, args...)
  1185  
  1186  	if err != nil {
  1187  		return nil, model.NewAppError("SqlTeamStore.GetChannelUnreadsForAllTeams", "store.sql_team.get_unread.app_error", nil, "userId="+userId+" "+err.Error(), http.StatusInternalServerError)
  1188  	}
  1189  
  1190  	return data, nil
  1191  }
  1192  
  1193  func (s SqlTeamStore) GetChannelUnreadsForTeam(teamId, userId string) ([]*model.ChannelUnread, *model.AppError) {
  1194  	query, args, err := s.getQueryBuilder().
  1195  		Select("Channels.TeamId TeamId", "Channels.Id ChannelId", "(Channels.TotalMsgCount - ChannelMembers.MsgCount) MsgCount", "ChannelMembers.MentionCount MentionCount", "ChannelMembers.NotifyProps NotifyProps").
  1196  		From("Channels").
  1197  		Join("ChannelMembers ON Id = ChannelId").
  1198  		Where(sq.Eq{"UserId": userId, "TeamId": teamId, "DeleteAt": 0}).ToSql()
  1199  
  1200  	if err != nil {
  1201  		return nil, model.NewAppError("SqlTeamStore.GetChannelUnreadsForTeam", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError)
  1202  	}
  1203  
  1204  	var channels []*model.ChannelUnread
  1205  	_, err = s.GetReplica().Select(&channels, query, args...)
  1206  
  1207  	if err != nil {
  1208  		return nil, model.NewAppError("SqlTeamStore.GetChannelUnreadsForTeam", "store.sql_team.get_unread.app_error", nil, "teamId="+teamId+" "+err.Error(), http.StatusInternalServerError)
  1209  	}
  1210  	return channels, nil
  1211  }
  1212  
  1213  func (s SqlTeamStore) RemoveMembers(teamId string, userIds []string) *model.AppError {
  1214  	query := s.getQueryBuilder().
  1215  		Delete("TeamMembers").
  1216  		Where(sq.Eq{"TeamId": teamId}).
  1217  		Where(sq.Eq{"UserId": userIds})
  1218  
  1219  	sql, args, err := query.ToSql()
  1220  	if err != nil {
  1221  		return model.NewAppError("SqlTeamStore.RemoveMembers", "store.sql.build_query.app_error", nil, "team_id="+teamId+", "+err.Error(), http.StatusInternalServerError)
  1222  	}
  1223  	_, err = s.GetMaster().Exec(sql, args...)
  1224  	if err != nil {
  1225  		return model.NewAppError("SqlTeamStore.RemoveMembers", "store.sql_team.remove_member.app_error", nil, "team_id="+teamId+", "+err.Error(), http.StatusInternalServerError)
  1226  	}
  1227  	return nil
  1228  }
  1229  
  1230  // RemoveMember remove from the database the team members that match the userId and teamId passed as parameter.
  1231  func (s SqlTeamStore) RemoveMember(teamId string, userId string) *model.AppError {
  1232  	return s.RemoveMembers(teamId, []string{userId})
  1233  }
  1234  
  1235  // RemoveAllMembersByTeam removes from the database the team members that belong to the teamId passed as parameter.
  1236  func (s SqlTeamStore) RemoveAllMembersByTeam(teamId string) *model.AppError {
  1237  	sql, args, err := s.getQueryBuilder().
  1238  		Delete("TeamMembers").
  1239  		Where(sq.Eq{"TeamId": teamId}).ToSql()
  1240  	if err != nil {
  1241  		return model.NewAppError("SqlTeamStore.RemoveMembers", "store.sql.build_query.app_error", nil, "team_id="+teamId+", "+err.Error(), http.StatusInternalServerError)
  1242  	}
  1243  
  1244  	_, err = s.GetMaster().Exec(sql, args...)
  1245  	if err != nil {
  1246  		return model.NewAppError("SqlTeamStore.RemoveMember", "store.sql_team.remove_member.app_error", nil, "team_id="+teamId+", "+err.Error(), http.StatusInternalServerError)
  1247  	}
  1248  	return nil
  1249  }
  1250  
  1251  // RemoveAllMembersByUser removes from the database the team members that match the userId passed as parameter.
  1252  func (s SqlTeamStore) RemoveAllMembersByUser(userId string) *model.AppError {
  1253  	sql, args, err := s.getQueryBuilder().
  1254  		Delete("TeamMembers").
  1255  		Where(sq.Eq{"UserId": userId}).ToSql()
  1256  	if err != nil {
  1257  		return model.NewAppError("SqlTeamStore.RemoveMembers", "store.sql.build_query.app_error", nil, "team_id="+userId+", "+err.Error(), http.StatusInternalServerError)
  1258  	}
  1259  	_, err = s.GetMaster().Exec(sql, args...)
  1260  	if err != nil {
  1261  		return model.NewAppError("SqlTeamStore.RemoveMember", "store.sql_team.remove_member.app_error", nil, "user_id="+userId+", "+err.Error(), http.StatusInternalServerError)
  1262  	}
  1263  	return nil
  1264  }
  1265  
  1266  func (s SqlTeamStore) UpdateLastTeamIconUpdate(teamId string, curTime int64) *model.AppError {
  1267  	sql, args, err := s.getQueryBuilder().
  1268  		Update("Teams").
  1269  		SetMap(sq.Eq{"LastTeamIconUpdate": curTime, "UpdateAt": curTime}).
  1270  		Where(sq.Eq{"Id": teamId}).ToSql()
  1271  	if err != nil {
  1272  		return model.NewAppError("SqlTeamStore.UpdateLastTeamIconUpdate", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError)
  1273  	}
  1274  
  1275  	if _, err = s.GetMaster().Exec(sql, args...); err != nil {
  1276  		return model.NewAppError("SqlTeamStore.UpdateLastTeamIconUpdate", "store.sql_team.update_last_team_icon_update.app_error", nil, "team_id="+teamId, http.StatusInternalServerError)
  1277  	}
  1278  	return nil
  1279  }
  1280  
  1281  // GetTeamsByScheme returns from the database all teams that match the schemeId provided as parameter, up to
  1282  // a total limit passed as paramater and paginated by offset number passed as parameter.
  1283  func (s SqlTeamStore) GetTeamsByScheme(schemeId string, offset int, limit int) ([]*model.Team, *model.AppError) {
  1284  	query, args, err := s.teamsQuery.Where(sq.Eq{"SchemeId": schemeId}).
  1285  		OrderBy("DisplayName").
  1286  		Limit(uint64(limit)).
  1287  		Offset(uint64(offset)).ToSql()
  1288  
  1289  	if err != nil {
  1290  		return nil, model.NewAppError("SqlTeamStore.GetTeamsByScheme", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError)
  1291  	}
  1292  
  1293  	var teams []*model.Team
  1294  	_, err = s.GetReplica().Select(&teams, query, args...)
  1295  	if err != nil {
  1296  		return nil, model.NewAppError("SqlTeamStore.GetTeamsByScheme", "store.sql_team.get_by_scheme.app_error", nil, "schemeId="+schemeId+" "+err.Error(), http.StatusInternalServerError)
  1297  	}
  1298  	return teams, nil
  1299  }
  1300  
  1301  // This function does the Advanced Permissions Phase 2 migration for TeamMember objects. It performs the migration
  1302  // in batches as a single transaction per batch to ensure consistency but to also minimise execution time to avoid
  1303  // causing unnecessary table locks. **THIS FUNCTION SHOULD NOT BE USED FOR ANY OTHER PURPOSE.** Executing this function
  1304  // *after* the new Schemes functionality has been used on an installation will have unintended consequences.
  1305  func (s SqlTeamStore) MigrateTeamMembers(fromTeamId string, fromUserId string) (map[string]string, *model.AppError) {
  1306  	var transaction *gorp.Transaction
  1307  	var err error
  1308  
  1309  	if transaction, err = s.GetMaster().Begin(); err != nil {
  1310  		return nil, model.NewAppError("SqlTeamStore.MigrateTeamMembers", "store.sql_team.migrate_team_members.open_transaction.app_error", nil, err.Error(), http.StatusInternalServerError)
  1311  	}
  1312  	defer finalizeTransaction(transaction)
  1313  
  1314  	var teamMembers []teamMember
  1315  	if _, err := transaction.Select(&teamMembers, "SELECT * from TeamMembers WHERE (TeamId, UserId) > (:FromTeamId, :FromUserId) ORDER BY TeamId, UserId LIMIT 100", map[string]interface{}{"FromTeamId": fromTeamId, "FromUserId": fromUserId}); err != nil {
  1316  		return nil, model.NewAppError("SqlTeamStore.MigrateTeamMembers", "store.sql_team.migrate_team_members.select.app_error", nil, err.Error(), http.StatusInternalServerError)
  1317  	}
  1318  
  1319  	if len(teamMembers) == 0 {
  1320  		// No more team members in query result means that the migration has finished.
  1321  		return nil, nil
  1322  	}
  1323  
  1324  	for i := range teamMembers {
  1325  		member := teamMembers[i]
  1326  		roles := strings.Fields(member.Roles)
  1327  		var newRoles []string
  1328  		if !member.SchemeAdmin.Valid {
  1329  			member.SchemeAdmin = sql.NullBool{Bool: false, Valid: true}
  1330  		}
  1331  		if !member.SchemeUser.Valid {
  1332  			member.SchemeUser = sql.NullBool{Bool: false, Valid: true}
  1333  		}
  1334  		if !member.SchemeGuest.Valid {
  1335  			member.SchemeGuest = sql.NullBool{Bool: false, Valid: true}
  1336  		}
  1337  		for _, role := range roles {
  1338  			if role == model.TEAM_ADMIN_ROLE_ID {
  1339  				member.SchemeAdmin = sql.NullBool{Bool: true, Valid: true}
  1340  			} else if role == model.TEAM_USER_ROLE_ID {
  1341  				member.SchemeUser = sql.NullBool{Bool: true, Valid: true}
  1342  			} else if role == model.TEAM_GUEST_ROLE_ID {
  1343  				member.SchemeGuest = sql.NullBool{Bool: true, Valid: true}
  1344  			} else {
  1345  				newRoles = append(newRoles, role)
  1346  			}
  1347  		}
  1348  		member.Roles = strings.Join(newRoles, " ")
  1349  
  1350  		if _, err := transaction.Update(&member); err != nil {
  1351  			return nil, model.NewAppError("SqlTeamStore.MigrateTeamMembers", "store.sql_team.migrate_team_members.update.app_error", nil, err.Error(), http.StatusInternalServerError)
  1352  		}
  1353  
  1354  	}
  1355  
  1356  	if err := transaction.Commit(); err != nil {
  1357  		return nil, model.NewAppError("SqlTeamStore.MigrateTeamMembers", "store.sql_team.migrate_team_members.commit_transaction.app_error", nil, err.Error(), http.StatusInternalServerError)
  1358  	}
  1359  
  1360  	data := make(map[string]string)
  1361  	data["TeamId"] = teamMembers[len(teamMembers)-1].TeamId
  1362  	data["UserId"] = teamMembers[len(teamMembers)-1].UserId
  1363  
  1364  	return data, nil
  1365  }
  1366  
  1367  func (s SqlTeamStore) ResetAllTeamSchemes() *model.AppError {
  1368  	if _, err := s.GetMaster().Exec("UPDATE Teams SET SchemeId=''"); err != nil {
  1369  		return model.NewAppError("SqlTeamStore.ResetAllTeamSchemes", "store.sql_team.reset_all_team_schemes.app_error", nil, err.Error(), http.StatusInternalServerError)
  1370  	}
  1371  	return nil
  1372  }
  1373  
  1374  func (s SqlTeamStore) ClearCaches() {}
  1375  
  1376  func (s SqlTeamStore) InvalidateAllTeamIdsForUser(userId string) {}
  1377  
  1378  func (s SqlTeamStore) ClearAllCustomRoleAssignments() *model.AppError {
  1379  
  1380  	builtInRoles := model.MakeDefaultRoles()
  1381  	lastUserId := strings.Repeat("0", 26)
  1382  	lastTeamId := strings.Repeat("0", 26)
  1383  
  1384  	for {
  1385  		var transaction *gorp.Transaction
  1386  		var err error
  1387  
  1388  		if transaction, err = s.GetMaster().Begin(); err != nil {
  1389  			return model.NewAppError("SqlTeamStore.ClearAllCustomRoleAssignments", "store.sql_team.clear_all_custom_role_assignments.open_transaction.app_error", nil, err.Error(), http.StatusInternalServerError)
  1390  		}
  1391  		defer finalizeTransaction(transaction)
  1392  
  1393  		var teamMembers []*teamMember
  1394  		if _, err := transaction.Select(&teamMembers, "SELECT * from TeamMembers WHERE (TeamId, UserId) > (:TeamId, :UserId) ORDER BY TeamId, UserId LIMIT 1000", map[string]interface{}{"TeamId": lastTeamId, "UserId": lastUserId}); err != nil {
  1395  			return model.NewAppError("SqlTeamStore.ClearAllCustomRoleAssignments", "store.sql_team.clear_all_custom_role_assignments.select.app_error", nil, err.Error(), http.StatusInternalServerError)
  1396  		}
  1397  
  1398  		if len(teamMembers) == 0 {
  1399  			break
  1400  		}
  1401  
  1402  		for _, member := range teamMembers {
  1403  			lastUserId = member.UserId
  1404  			lastTeamId = member.TeamId
  1405  
  1406  			var newRoles []string
  1407  
  1408  			for _, role := range strings.Fields(member.Roles) {
  1409  				for name := range builtInRoles {
  1410  					if name == role {
  1411  						newRoles = append(newRoles, role)
  1412  						break
  1413  					}
  1414  				}
  1415  			}
  1416  
  1417  			newRolesString := strings.Join(newRoles, " ")
  1418  			if newRolesString != member.Roles {
  1419  				if _, err := transaction.Exec("UPDATE TeamMembers SET Roles = :Roles WHERE UserId = :UserId AND TeamId = :TeamId", map[string]interface{}{"Roles": newRolesString, "TeamId": member.TeamId, "UserId": member.UserId}); err != nil {
  1420  					return model.NewAppError("SqlTeamStore.ClearAllCustomRoleAssignments", "store.sql_team.clear_all_custom_role_assignments.update.app_error", nil, err.Error(), http.StatusInternalServerError)
  1421  				}
  1422  			}
  1423  		}
  1424  
  1425  		if err := transaction.Commit(); err != nil {
  1426  			return model.NewAppError("SqlTeamStore.ClearAllCustomRoleAssignments", "store.sql_team.clear_all_custom_role_assignments.commit_transaction.app_error", nil, err.Error(), http.StatusInternalServerError)
  1427  		}
  1428  	}
  1429  	return nil
  1430  }
  1431  
  1432  // AnalyticsGetTeamCountForScheme returns the number of active teams that match the schemeId passed as parameter.
  1433  func (s SqlTeamStore) AnalyticsGetTeamCountForScheme(schemeId string) (int64, *model.AppError) {
  1434  	query, args, err := s.getQueryBuilder().
  1435  		Select("count(*)").
  1436  		From("Teams").
  1437  		Where(sq.Eq{"SchemeId": schemeId, "DeleteAt": 0}).ToSql()
  1438  
  1439  	if err != nil {
  1440  		return 0, model.NewAppError("SqlTeamStore.AnalyticsGetTeamCountForScheme", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError)
  1441  	}
  1442  	count, err := s.GetReplica().SelectInt(query, args...)
  1443  	if err != nil {
  1444  		return 0, model.NewAppError("SqlTeamStore.AnalyticsGetTeamCountForScheme", "store.sql_team.analytics_get_team_count_for_scheme.app_error", nil, "schemeId="+schemeId+" "+err.Error(), http.StatusInternalServerError)
  1445  	}
  1446  
  1447  	return count, nil
  1448  }
  1449  
  1450  // GetAllForExportAfter returns teams for export, up to a total limit passed as paramater where Teams.Id is greater than the afterId passed as parameter.
  1451  func (s SqlTeamStore) GetAllForExportAfter(limit int, afterId string) ([]*model.TeamForExport, *model.AppError) {
  1452  	var data []*model.TeamForExport
  1453  	query, args, err := s.getQueryBuilder().
  1454  		Select("Teams.*", "Schemes.Name as SchemeName").
  1455  		From("Teams").
  1456  		LeftJoin("Schemes ON Teams.SchemeId = Schemes.Id").
  1457  		Where(sq.Gt{"Teams.Id": afterId}).
  1458  		OrderBy("Id").
  1459  		Limit(uint64(limit)).ToSql()
  1460  
  1461  	if err != nil {
  1462  		return nil, model.NewAppError("SqlTeamStore.GetAllTeams", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError)
  1463  	}
  1464  	if _, err = s.GetReplica().Select(&data, query, args...); err != nil {
  1465  		return nil, model.NewAppError("SqlTeamStore.GetAllTeams", "store.sql_team.get_all.app_error", nil, err.Error(), http.StatusInternalServerError)
  1466  	}
  1467  
  1468  	return data, nil
  1469  }
  1470  
  1471  // GetUserTeamIds get the team ids to which the user belongs to. allowFromCache parameter does not have any effect in this Store
  1472  func (s SqlTeamStore) GetUserTeamIds(userID string, allowFromCache bool) ([]string, *model.AppError) {
  1473  	var teamIds []string
  1474  	query, args, err := s.getQueryBuilder().
  1475  		Select("TeamId").
  1476  		From("TeamMembers").
  1477  		Join("Teams ON TeamMembers.TeamId = Teams.Id").
  1478  		Where(sq.Eq{"TeamMembers.UserId": userID, "TeamMembers.DeleteAt": 0, "Teams.DeleteAt": 0}).ToSql()
  1479  
  1480  	if err != nil {
  1481  		return []string{}, model.NewAppError("SqlTeamStore.GetUserTeamIds", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError)
  1482  	}
  1483  	_, err = s.GetReplica().Select(&teamIds, query, args...)
  1484  	if err != nil {
  1485  		return []string{}, model.NewAppError("SqlTeamStore.GetUserTeamIds", "store.sql_team.get_user_team_ids.app_error", nil, "userID="+userID+" "+err.Error(), http.StatusInternalServerError)
  1486  	}
  1487  
  1488  	return teamIds, nil
  1489  }
  1490  
  1491  func (s SqlTeamStore) GetTeamMembersForExport(userId string) ([]*model.TeamMemberForExport, *model.AppError) {
  1492  	var members []*model.TeamMemberForExport
  1493  	query, args, err := s.getQueryBuilder().
  1494  		Select("TeamMembers.TeamId", "TeamMembers.UserId", "TeamMembers.Roles", "TeamMembers.DeleteAt",
  1495  			"(TeamMembers.SchemeGuest IS NOT NULL AND TeamMembers.SchemeGuest) as SchemeGuest",
  1496  			"TeamMembers.SchemeUser", "TeamMembers.SchemeAdmin", "Teams.Name as TeamName").
  1497  		From("TeamMembers").
  1498  		Join("Teams ON TeamMembers.TeamId = Teams.Id").
  1499  		Where(sq.Eq{"TeamMembers.UserId": userId, "Teams.DeleteAt": 0}).ToSql()
  1500  
  1501  	if err != nil {
  1502  		return nil, model.NewAppError("SqlTeamStore.GetTeamMembersForExport", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError)
  1503  	}
  1504  	_, err = s.GetReplica().Select(&members, query, args...)
  1505  	if err != nil {
  1506  		return nil, model.NewAppError("SqlTeamStore.GetTeamMembersForExport", "store.sql_team.get_members.app_error", nil, "userId="+userId+" "+err.Error(), http.StatusInternalServerError)
  1507  	}
  1508  	return members, nil
  1509  }
  1510  
  1511  func (s SqlTeamStore) UserBelongsToTeams(userId string, teamIds []string) (bool, *model.AppError) {
  1512  	idQuery := sq.Eq{
  1513  		"UserId":   userId,
  1514  		"TeamId":   teamIds,
  1515  		"DeleteAt": 0,
  1516  	}
  1517  
  1518  	query, params, err := s.getQueryBuilder().Select("Count(*)").From("TeamMembers").Where(idQuery).ToSql()
  1519  	if err != nil {
  1520  		return false, model.NewAppError("SqlTeamStore.UserBelongsToTeams", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError)
  1521  	}
  1522  
  1523  	c, err := s.GetReplica().SelectInt(query, params...)
  1524  	if err != nil {
  1525  		return false, model.NewAppError("SqlTeamStore.UserBelongsToTeams", "store.sql_team.user_belongs_to_teams.app_error", nil, err.Error(), http.StatusInternalServerError)
  1526  	}
  1527  
  1528  	return c > 0, nil
  1529  }
  1530  
  1531  func (s SqlTeamStore) UpdateMembersRole(teamID string, userIDs []string) *model.AppError {
  1532  	sql, args, err := s.getQueryBuilder().
  1533  		Update("TeamMembers").
  1534  		Set("SchemeAdmin", sq.Case().When(sq.Eq{"UserId": userIDs}, "true").Else("false")).
  1535  		Where(sq.Eq{"TeamId": teamID, "DeleteAt": 0}).
  1536  		Where(sq.Or{sq.Eq{"SchemeGuest": false}, sq.Expr("SchemeGuest IS NULL")}).ToSql()
  1537  	if err != nil {
  1538  		return model.NewAppError("SqlTeamStore.UpdateMembersRole", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError)
  1539  	}
  1540  	if _, err = s.GetMaster().Exec(sql, args...); err != nil {
  1541  		return model.NewAppError("SqlTeamStore.UpdateMembersRole", "store.update_error", nil, err.Error(), http.StatusInternalServerError)
  1542  	}
  1543  
  1544  	return nil
  1545  }
  1546  
  1547  func applyTeamMemberViewRestrictionsFilter(query sq.SelectBuilder, teamId string, restrictions *model.ViewUsersRestrictions) sq.SelectBuilder {
  1548  	if restrictions == nil {
  1549  		return query
  1550  	}
  1551  
  1552  	// If you have no access to teams or channels, return and empty result.
  1553  	if restrictions.Teams != nil && len(restrictions.Teams) == 0 && restrictions.Channels != nil && len(restrictions.Channels) == 0 {
  1554  		return query.Where("1 = 0")
  1555  	}
  1556  
  1557  	teams := make([]interface{}, len(restrictions.Teams))
  1558  	for i, v := range restrictions.Teams {
  1559  		teams[i] = v
  1560  	}
  1561  	channels := make([]interface{}, len(restrictions.Channels))
  1562  	for i, v := range restrictions.Channels {
  1563  		channels[i] = v
  1564  	}
  1565  
  1566  	resultQuery := query.Join("Users ru ON (TeamMembers.UserId = ru.Id)")
  1567  	if restrictions.Teams != nil && len(restrictions.Teams) > 0 {
  1568  		resultQuery = resultQuery.Join(fmt.Sprintf("TeamMembers rtm ON ( rtm.UserId = ru.Id AND rtm.DeleteAt = 0 AND rtm.TeamId IN (%s))", sq.Placeholders(len(teams))), teams...)
  1569  	}
  1570  	if restrictions.Channels != nil && len(restrictions.Channels) > 0 {
  1571  		resultQuery = resultQuery.Join(fmt.Sprintf("ChannelMembers rcm ON ( rcm.UserId = ru.Id AND rcm.ChannelId IN (%s))", sq.Placeholders(len(channels))), channels...)
  1572  	}
  1573  
  1574  	return resultQuery.Distinct()
  1575  }
  1576  
  1577  func applyTeamMemberViewRestrictionsFilterForStats(query sq.SelectBuilder, teamId string, restrictions *model.ViewUsersRestrictions) sq.SelectBuilder {
  1578  	if restrictions == nil {
  1579  		return query
  1580  	}
  1581  
  1582  	// If you have no access to teams or channels, return and empty result.
  1583  	if restrictions.Teams != nil && len(restrictions.Teams) == 0 && restrictions.Channels != nil && len(restrictions.Channels) == 0 {
  1584  		return query.Where("1 = 0")
  1585  	}
  1586  
  1587  	teams := make([]interface{}, len(restrictions.Teams))
  1588  	for i, v := range restrictions.Teams {
  1589  		teams[i] = v
  1590  	}
  1591  	channels := make([]interface{}, len(restrictions.Channels))
  1592  	for i, v := range restrictions.Channels {
  1593  		channels[i] = v
  1594  	}
  1595  
  1596  	resultQuery := query
  1597  	if restrictions.Teams != nil && len(restrictions.Teams) > 0 {
  1598  		resultQuery = resultQuery.Join(fmt.Sprintf("TeamMembers rtm ON ( rtm.UserId = Users.Id AND rtm.DeleteAt = 0 AND rtm.TeamId IN (%s))", sq.Placeholders(len(teams))), teams...)
  1599  	}
  1600  	if restrictions.Channels != nil && len(restrictions.Channels) > 0 {
  1601  		resultQuery = resultQuery.Join(fmt.Sprintf("ChannelMembers rcm ON ( rcm.UserId = Users.Id AND rcm.ChannelId IN (%s))", sq.Placeholders(len(channels))), channels...)
  1602  	}
  1603  
  1604  	return resultQuery
  1605  }
  1606  
  1607  func (s SqlTeamStore) GroupSyncedTeamCount() (int64, *model.AppError) {
  1608  	query := s.getQueryBuilder().Select("COUNT(*)").From("Teams").Where(sq.Eq{"GroupConstrained": true, "DeleteAt": 0})
  1609  
  1610  	sql, args, err := query.ToSql()
  1611  	if err != nil {
  1612  		return 0, model.NewAppError("SqlTeamStore.GroupSyncedTeamCount", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError)
  1613  	}
  1614  
  1615  	count, err := s.GetReplica().SelectInt(sql, args...)
  1616  	if err != nil {
  1617  		return 0, model.NewAppError("SqlTeamStore.GroupSyncedTeamCount", "store.select_error", nil, err.Error(), http.StatusInternalServerError)
  1618  	}
  1619  
  1620  	return count, nil
  1621  }