github.com/haalcala/mattermost-server-change-repo/v5@v5.33.2/store/sqlstore/scheme_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  	"strings"
    10  
    11  	"github.com/mattermost/gorp"
    12  	"github.com/pkg/errors"
    13  
    14  	"github.com/mattermost/mattermost-server/v5/model"
    15  	"github.com/mattermost/mattermost-server/v5/store"
    16  )
    17  
    18  type SqlSchemeStore struct {
    19  	*SqlStore
    20  }
    21  
    22  func newSqlSchemeStore(sqlStore *SqlStore) store.SchemeStore {
    23  	s := &SqlSchemeStore{sqlStore}
    24  
    25  	for _, db := range sqlStore.GetAllConns() {
    26  		table := db.AddTableWithName(model.Scheme{}, "Schemes").SetKeys(false, "Id")
    27  		table.ColMap("Id").SetMaxSize(26)
    28  		table.ColMap("Name").SetMaxSize(model.SCHEME_NAME_MAX_LENGTH).SetUnique(true)
    29  		table.ColMap("DisplayName").SetMaxSize(model.SCHEME_DISPLAY_NAME_MAX_LENGTH)
    30  		table.ColMap("Description").SetMaxSize(model.SCHEME_DESCRIPTION_MAX_LENGTH)
    31  		table.ColMap("Scope").SetMaxSize(32)
    32  		table.ColMap("DefaultTeamAdminRole").SetMaxSize(64)
    33  		table.ColMap("DefaultTeamUserRole").SetMaxSize(64)
    34  		table.ColMap("DefaultTeamGuestRole").SetMaxSize(64)
    35  		table.ColMap("DefaultChannelAdminRole").SetMaxSize(64)
    36  		table.ColMap("DefaultChannelUserRole").SetMaxSize(64)
    37  		table.ColMap("DefaultChannelGuestRole").SetMaxSize(64)
    38  	}
    39  
    40  	return s
    41  }
    42  
    43  func (s SqlSchemeStore) createIndexesIfNotExists() {
    44  	s.CreateIndexIfNotExists("idx_schemes_channel_guest_role", "Schemes", "DefaultChannelGuestRole")
    45  	s.CreateIndexIfNotExists("idx_schemes_channel_user_role", "Schemes", "DefaultChannelUserRole")
    46  	s.CreateIndexIfNotExists("idx_schemes_channel_admin_role", "Schemes", "DefaultChannelAdminRole")
    47  }
    48  
    49  func (s *SqlSchemeStore) Save(scheme *model.Scheme) (*model.Scheme, error) {
    50  	if scheme.Id == "" {
    51  		transaction, err := s.GetMaster().Begin()
    52  		if err != nil {
    53  			return nil, errors.Wrap(err, "begin_transaction")
    54  		}
    55  		defer finalizeTransaction(transaction)
    56  
    57  		newScheme, err := s.createScheme(scheme, transaction)
    58  		if err != nil {
    59  			return nil, err
    60  		}
    61  		if err := transaction.Commit(); err != nil {
    62  			return nil, errors.Wrap(err, "commit_transaction")
    63  		}
    64  		return newScheme, nil
    65  	}
    66  
    67  	if !scheme.IsValid() {
    68  		return nil, store.NewErrInvalidInput("Scheme", "<any>", fmt.Sprintf("%v", scheme))
    69  	}
    70  
    71  	scheme.UpdateAt = model.GetMillis()
    72  
    73  	rowsChanged, err := s.GetMaster().Update(scheme)
    74  	if err != nil {
    75  		return nil, errors.Wrap(err, "failed to update Scheme")
    76  	}
    77  	if rowsChanged != 1 {
    78  		return nil, errors.New("no record to update")
    79  	}
    80  
    81  	return scheme, nil
    82  }
    83  
    84  func (s *SqlSchemeStore) createScheme(scheme *model.Scheme, transaction *gorp.Transaction) (*model.Scheme, error) {
    85  	// Fetch the default system scheme roles to populate default permissions.
    86  	defaultRoleNames := []string{model.TEAM_ADMIN_ROLE_ID, model.TEAM_USER_ROLE_ID, model.TEAM_GUEST_ROLE_ID, model.CHANNEL_ADMIN_ROLE_ID, model.CHANNEL_USER_ROLE_ID, model.CHANNEL_GUEST_ROLE_ID}
    87  	defaultRoles := make(map[string]*model.Role)
    88  	roles, err := s.SqlStore.Role().GetByNames(defaultRoleNames)
    89  	if err != nil {
    90  		return nil, err
    91  	}
    92  
    93  	for _, role := range roles {
    94  		switch role.Name {
    95  		case model.TEAM_ADMIN_ROLE_ID:
    96  			defaultRoles[model.TEAM_ADMIN_ROLE_ID] = role
    97  		case model.TEAM_USER_ROLE_ID:
    98  			defaultRoles[model.TEAM_USER_ROLE_ID] = role
    99  		case model.TEAM_GUEST_ROLE_ID:
   100  			defaultRoles[model.TEAM_GUEST_ROLE_ID] = role
   101  		case model.CHANNEL_ADMIN_ROLE_ID:
   102  			defaultRoles[model.CHANNEL_ADMIN_ROLE_ID] = role
   103  		case model.CHANNEL_USER_ROLE_ID:
   104  			defaultRoles[model.CHANNEL_USER_ROLE_ID] = role
   105  		case model.CHANNEL_GUEST_ROLE_ID:
   106  			defaultRoles[model.CHANNEL_GUEST_ROLE_ID] = role
   107  		}
   108  	}
   109  
   110  	if len(defaultRoles) != 6 {
   111  		return nil, errors.New("createScheme: unable to retrieve default scheme roles")
   112  	}
   113  
   114  	// Create the appropriate default roles for the scheme.
   115  	if scheme.Scope == model.SCHEME_SCOPE_TEAM {
   116  		// Team Admin Role
   117  		teamAdminRole := &model.Role{
   118  			Name:          model.NewId(),
   119  			DisplayName:   fmt.Sprintf("Team Admin Role for Scheme %s", scheme.Name),
   120  			Permissions:   defaultRoles[model.TEAM_ADMIN_ROLE_ID].Permissions,
   121  			SchemeManaged: true,
   122  		}
   123  
   124  		savedRole, err := s.SqlStore.Role().(*SqlRoleStore).createRole(teamAdminRole, transaction)
   125  		if err != nil {
   126  			return nil, err
   127  		}
   128  		scheme.DefaultTeamAdminRole = savedRole.Name
   129  
   130  		// Team User Role
   131  		teamUserRole := &model.Role{
   132  			Name:          model.NewId(),
   133  			DisplayName:   fmt.Sprintf("Team User Role for Scheme %s", scheme.Name),
   134  			Permissions:   defaultRoles[model.TEAM_USER_ROLE_ID].Permissions,
   135  			SchemeManaged: true,
   136  		}
   137  
   138  		savedRole, err = s.SqlStore.Role().(*SqlRoleStore).createRole(teamUserRole, transaction)
   139  		if err != nil {
   140  			return nil, err
   141  		}
   142  		scheme.DefaultTeamUserRole = savedRole.Name
   143  
   144  		// Team Guest Role
   145  		teamGuestRole := &model.Role{
   146  			Name:          model.NewId(),
   147  			DisplayName:   fmt.Sprintf("Team Guest Role for Scheme %s", scheme.Name),
   148  			Permissions:   defaultRoles[model.TEAM_GUEST_ROLE_ID].Permissions,
   149  			SchemeManaged: true,
   150  		}
   151  
   152  		savedRole, err = s.SqlStore.Role().(*SqlRoleStore).createRole(teamGuestRole, transaction)
   153  		if err != nil {
   154  			return nil, err
   155  		}
   156  		scheme.DefaultTeamGuestRole = savedRole.Name
   157  	}
   158  
   159  	if scheme.Scope == model.SCHEME_SCOPE_TEAM || scheme.Scope == model.SCHEME_SCOPE_CHANNEL {
   160  		// Channel Admin Role
   161  		channelAdminRole := &model.Role{
   162  			Name:          model.NewId(),
   163  			DisplayName:   fmt.Sprintf("Channel Admin Role for Scheme %s", scheme.Name),
   164  			Permissions:   defaultRoles[model.CHANNEL_ADMIN_ROLE_ID].Permissions,
   165  			SchemeManaged: true,
   166  		}
   167  
   168  		if scheme.Scope == model.SCHEME_SCOPE_CHANNEL {
   169  			channelAdminRole.Permissions = []string{}
   170  		}
   171  
   172  		savedRole, err := s.SqlStore.Role().(*SqlRoleStore).createRole(channelAdminRole, transaction)
   173  		if err != nil {
   174  			return nil, err
   175  		}
   176  		scheme.DefaultChannelAdminRole = savedRole.Name
   177  
   178  		// Channel User Role
   179  		channelUserRole := &model.Role{
   180  			Name:          model.NewId(),
   181  			DisplayName:   fmt.Sprintf("Channel User Role for Scheme %s", scheme.Name),
   182  			Permissions:   defaultRoles[model.CHANNEL_USER_ROLE_ID].Permissions,
   183  			SchemeManaged: true,
   184  		}
   185  
   186  		if scheme.Scope == model.SCHEME_SCOPE_CHANNEL {
   187  			channelUserRole.Permissions = filterModerated(channelUserRole.Permissions)
   188  		}
   189  
   190  		savedRole, err = s.SqlStore.Role().(*SqlRoleStore).createRole(channelUserRole, transaction)
   191  		if err != nil {
   192  			return nil, err
   193  		}
   194  		scheme.DefaultChannelUserRole = savedRole.Name
   195  
   196  		// Channel Guest Role
   197  		channelGuestRole := &model.Role{
   198  			Name:          model.NewId(),
   199  			DisplayName:   fmt.Sprintf("Channel Guest Role for Scheme %s", scheme.Name),
   200  			Permissions:   defaultRoles[model.CHANNEL_GUEST_ROLE_ID].Permissions,
   201  			SchemeManaged: true,
   202  		}
   203  
   204  		if scheme.Scope == model.SCHEME_SCOPE_CHANNEL {
   205  			channelGuestRole.Permissions = filterModerated(channelGuestRole.Permissions)
   206  		}
   207  
   208  		savedRole, err = s.SqlStore.Role().(*SqlRoleStore).createRole(channelGuestRole, transaction)
   209  		if err != nil {
   210  			return nil, err
   211  		}
   212  		scheme.DefaultChannelGuestRole = savedRole.Name
   213  	}
   214  
   215  	scheme.Id = model.NewId()
   216  	if scheme.Name == "" {
   217  		scheme.Name = model.NewId()
   218  	}
   219  	scheme.CreateAt = model.GetMillis()
   220  	scheme.UpdateAt = scheme.CreateAt
   221  
   222  	// Validate the scheme
   223  	if !scheme.IsValidForCreate() {
   224  		return nil, store.NewErrInvalidInput("Scheme", "<any>", fmt.Sprintf("%v", scheme))
   225  	}
   226  
   227  	if err := transaction.Insert(scheme); err != nil {
   228  		return nil, errors.Wrap(err, "failed to save Scheme")
   229  	}
   230  
   231  	return scheme, nil
   232  }
   233  
   234  func filterModerated(permissions []string) []string {
   235  	filteredPermissions := []string{}
   236  	for _, perm := range permissions {
   237  		if _, ok := model.ChannelModeratedPermissionsMap[perm]; ok {
   238  			filteredPermissions = append(filteredPermissions, perm)
   239  		}
   240  	}
   241  	return filteredPermissions
   242  }
   243  
   244  func (s *SqlSchemeStore) Get(schemeId string) (*model.Scheme, error) {
   245  	var scheme model.Scheme
   246  	if err := s.GetReplica().SelectOne(&scheme, "SELECT * from Schemes WHERE Id = :Id", map[string]interface{}{"Id": schemeId}); err != nil {
   247  		if err == sql.ErrNoRows {
   248  			return nil, store.NewErrNotFound("Scheme", fmt.Sprintf("schemeId=%s", schemeId))
   249  		}
   250  		return nil, errors.Wrapf(err, "failed to get Scheme with schemeId=%s", schemeId)
   251  	}
   252  
   253  	return &scheme, nil
   254  }
   255  
   256  func (s *SqlSchemeStore) GetByName(schemeName string) (*model.Scheme, error) {
   257  	var scheme model.Scheme
   258  
   259  	if err := s.GetReplica().SelectOne(&scheme, "SELECT * from Schemes WHERE Name = :Name", map[string]interface{}{"Name": schemeName}); err != nil {
   260  		if err == sql.ErrNoRows {
   261  			return nil, store.NewErrNotFound("Scheme", fmt.Sprintf("schemeName=%s", schemeName))
   262  		}
   263  		return nil, errors.Wrapf(err, "failed to get Scheme with schemeName=%s", schemeName)
   264  	}
   265  
   266  	return &scheme, nil
   267  }
   268  
   269  func (s *SqlSchemeStore) Delete(schemeId string) (*model.Scheme, error) {
   270  	// Get the scheme
   271  	var scheme model.Scheme
   272  	if err := s.GetReplica().SelectOne(&scheme, "SELECT * from Schemes WHERE Id = :Id", map[string]interface{}{"Id": schemeId}); err != nil {
   273  		if err == sql.ErrNoRows {
   274  			return nil, store.NewErrNotFound("Scheme", fmt.Sprintf("schemeId=%s", schemeId))
   275  		}
   276  		return nil, errors.Wrapf(err, "failed to get Scheme with schemeId=%s", schemeId)
   277  	}
   278  
   279  	// Update any teams or channels using this scheme to the default scheme.
   280  	if scheme.Scope == model.SCHEME_SCOPE_TEAM {
   281  		if _, err := s.GetMaster().Exec("UPDATE Teams SET SchemeId = '' WHERE SchemeId = :SchemeId", map[string]interface{}{"SchemeId": schemeId}); err != nil {
   282  			return nil, errors.Wrapf(err, "failed to update Teams with schemeId=%s", schemeId)
   283  		}
   284  
   285  		s.Team().ClearCaches()
   286  	} else if scheme.Scope == model.SCHEME_SCOPE_CHANNEL {
   287  		if _, err := s.GetMaster().Exec("UPDATE Channels SET SchemeId = '' WHERE SchemeId = :SchemeId", map[string]interface{}{"SchemeId": schemeId}); err != nil {
   288  			return nil, errors.Wrapf(err, "failed to update Channels with schemeId=%s", schemeId)
   289  		}
   290  	}
   291  
   292  	// Blow away the channel caches.
   293  	s.Channel().ClearCaches()
   294  
   295  	// Delete the roles belonging to the scheme.
   296  	roleNames := []string{scheme.DefaultChannelGuestRole, scheme.DefaultChannelUserRole, scheme.DefaultChannelAdminRole}
   297  	if scheme.Scope == model.SCHEME_SCOPE_TEAM {
   298  		roleNames = append(roleNames, scheme.DefaultTeamGuestRole, scheme.DefaultTeamUserRole, scheme.DefaultTeamAdminRole)
   299  	}
   300  
   301  	var inQueryList []string
   302  	queryArgs := make(map[string]interface{})
   303  	for i, roleId := range roleNames {
   304  		inQueryList = append(inQueryList, fmt.Sprintf(":RoleName%v", i))
   305  		queryArgs[fmt.Sprintf("RoleName%v", i)] = roleId
   306  	}
   307  	inQuery := strings.Join(inQueryList, ", ")
   308  
   309  	time := model.GetMillis()
   310  	queryArgs["UpdateAt"] = time
   311  	queryArgs["DeleteAt"] = time
   312  
   313  	if _, err := s.GetMaster().Exec("UPDATE Roles SET UpdateAt = :UpdateAt, DeleteAt = :DeleteAt WHERE Name IN ("+inQuery+")", queryArgs); err != nil {
   314  		return nil, errors.Wrapf(err, "failed to update Roles with name in (%s)", inQuery)
   315  	}
   316  
   317  	// Delete the scheme itself.
   318  	scheme.UpdateAt = time
   319  	scheme.DeleteAt = time
   320  
   321  	rowsChanged, err := s.GetMaster().Update(&scheme)
   322  	if err != nil {
   323  		return nil, errors.Wrapf(err, "failed to update Scheme with schemeId=%s", schemeId)
   324  	}
   325  	if rowsChanged != 1 {
   326  		return nil, errors.New("no record to update")
   327  	}
   328  	return &scheme, nil
   329  }
   330  
   331  func (s *SqlSchemeStore) GetAllPage(scope string, offset int, limit int) ([]*model.Scheme, error) {
   332  	var schemes []*model.Scheme
   333  
   334  	scopeClause := ""
   335  	if scope != "" {
   336  		scopeClause = " AND Scope=:Scope "
   337  	}
   338  
   339  	if _, err := s.GetReplica().Select(&schemes, "SELECT * from Schemes WHERE DeleteAt = 0 "+scopeClause+" ORDER BY CreateAt DESC LIMIT :Limit OFFSET :Offset", map[string]interface{}{"Limit": limit, "Offset": offset, "Scope": scope}); err != nil {
   340  		return nil, errors.Wrapf(err, "failed to get Schemes")
   341  	}
   342  
   343  	return schemes, nil
   344  }
   345  
   346  func (s *SqlSchemeStore) PermanentDeleteAll() error {
   347  	if _, err := s.GetMaster().Exec("DELETE from Schemes"); err != nil {
   348  		return errors.Wrap(err, "failed to delete Schemes")
   349  	}
   350  
   351  	return nil
   352  }
   353  
   354  func (s *SqlSchemeStore) CountByScope(scope string) (int64, error) {
   355  	count, err := s.GetReplica().SelectInt("SELECT count(*) FROM Schemes WHERE Scope = :Scope AND DeleteAt = 0", map[string]interface{}{"Scope": scope})
   356  	if err != nil {
   357  		return int64(0), errors.Wrap(err, "failed to count Schemes by scope")
   358  	}
   359  	return count, nil
   360  }
   361  
   362  func (s *SqlSchemeStore) CountWithoutPermission(schemeScope, permissionID string, roleScope model.RoleScope, roleType model.RoleType) (int64, error) {
   363  	joinCol := fmt.Sprintf("Default%s%sRole", roleScope, roleType)
   364  	query := fmt.Sprintf(`
   365  		SELECT
   366  			count(*)
   367  		FROM Schemes
   368  			JOIN Roles ON Roles.Name = Schemes.%s
   369  		WHERE
   370  			Schemes.DeleteAt = 0 AND
   371  			Schemes.Scope = '%s' AND
   372  			Roles.Permissions NOT LIKE '%%%s%%'
   373  	`, joinCol, schemeScope, permissionID)
   374  	count, err := s.GetReplica().SelectInt(query)
   375  	if err != nil {
   376  		return int64(0), errors.Wrap(err, "failed to count Schemes without permission")
   377  	}
   378  	return count, nil
   379  }