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 }