github.com/masterhung0112/hk_server/v5@v5.0.0-20220302090640-ec71aef15e1c/store/sqlstore/scheme_store.go (about)

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