github.com/mad-app/mattermost-server@v5.11.1+incompatible/store/sqlstore/scheme_supplier.go (about) 1 // Copyright (c) 2018-present Mattermost, Inc. All Rights Reserved. 2 // See License.txt for license information. 3 4 package sqlstore 5 6 import ( 7 "context" 8 "database/sql" 9 "fmt" 10 "net/http" 11 "strings" 12 13 "github.com/mattermost/gorp" 14 15 "github.com/mattermost/mattermost-server/model" 16 "github.com/mattermost/mattermost-server/store" 17 ) 18 19 func initSqlSupplierSchemes(sqlStore SqlStore) { 20 for _, db := range sqlStore.GetAllConns() { 21 table := db.AddTableWithName(model.Scheme{}, "Schemes").SetKeys(false, "Id") 22 table.ColMap("Id").SetMaxSize(26) 23 table.ColMap("Name").SetMaxSize(model.SCHEME_NAME_MAX_LENGTH).SetUnique(true) 24 table.ColMap("DisplayName").SetMaxSize(model.SCHEME_DISPLAY_NAME_MAX_LENGTH) 25 table.ColMap("Description").SetMaxSize(model.SCHEME_DESCRIPTION_MAX_LENGTH) 26 table.ColMap("Scope").SetMaxSize(32) 27 table.ColMap("DefaultTeamAdminRole").SetMaxSize(64) 28 table.ColMap("DefaultTeamUserRole").SetMaxSize(64) 29 table.ColMap("DefaultChannelAdminRole").SetMaxSize(64) 30 table.ColMap("DefaultChannelUserRole").SetMaxSize(64) 31 } 32 } 33 34 func (s *SqlSupplier) SchemeSave(ctx context.Context, scheme *model.Scheme, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult { 35 result := store.NewSupplierResult() 36 37 if len(scheme.Id) == 0 { 38 if transaction, err := s.GetMaster().Begin(); err != nil { 39 result.Err = model.NewAppError("SqlSchemeStore.SaveScheme", "store.sql_scheme.save.open_transaction.app_error", nil, err.Error(), http.StatusInternalServerError) 40 } else { 41 defer finalizeTransaction(transaction) 42 result = s.createScheme(ctx, scheme, transaction, hints...) 43 44 if result.Err == nil { 45 if err := transaction.Commit(); err != nil { 46 result.Err = model.NewAppError("SqlSchemeStore.SchemeSave", "store.sql_scheme.save_scheme.commit_transaction.app_error", nil, err.Error(), http.StatusInternalServerError) 47 } 48 } 49 } 50 } else { 51 if !scheme.IsValid() { 52 result.Err = model.NewAppError("SqlSchemeStore.Save", "store.sql_scheme.save.invalid_scheme.app_error", nil, "schemeId="+scheme.Id, http.StatusBadRequest) 53 return result 54 } 55 56 scheme.UpdateAt = model.GetMillis() 57 58 if rowsChanged, err := s.GetMaster().Update(scheme); err != nil { 59 result.Err = model.NewAppError("SqlSchemeStore.Save", "store.sql_scheme.save.update.app_error", nil, err.Error(), http.StatusInternalServerError) 60 } else if rowsChanged != 1 { 61 result.Err = model.NewAppError("SqlSchemeStore.Save", "store.sql_scheme.save.update.app_error", nil, "no record to update", http.StatusInternalServerError) 62 } 63 64 result.Data = scheme 65 } 66 67 return result 68 } 69 70 func (s *SqlSupplier) createScheme(ctx context.Context, scheme *model.Scheme, transaction *gorp.Transaction, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult { 71 result := store.NewSupplierResult() 72 73 // Fetch the default system scheme roles to populate default permissions. 74 defaultRoleNames := []string{model.TEAM_ADMIN_ROLE_ID, model.TEAM_USER_ROLE_ID, model.CHANNEL_ADMIN_ROLE_ID, model.CHANNEL_USER_ROLE_ID} 75 defaultRoles := make(map[string]*model.Role) 76 if rolesResult := s.RoleGetByNames(ctx, defaultRoleNames); rolesResult.Err != nil { 77 result.Err = rolesResult.Err 78 return result 79 } else { 80 for _, role := range rolesResult.Data.([]*model.Role) { 81 switch role.Name { 82 case model.TEAM_ADMIN_ROLE_ID: 83 defaultRoles[model.TEAM_ADMIN_ROLE_ID] = role 84 case model.TEAM_USER_ROLE_ID: 85 defaultRoles[model.TEAM_USER_ROLE_ID] = role 86 case model.CHANNEL_ADMIN_ROLE_ID: 87 defaultRoles[model.CHANNEL_ADMIN_ROLE_ID] = role 88 case model.CHANNEL_USER_ROLE_ID: 89 defaultRoles[model.CHANNEL_USER_ROLE_ID] = role 90 } 91 } 92 93 if len(defaultRoles) != 4 { 94 result.Err = model.NewAppError("SqlSchemeStore.SaveScheme", "store.sql_scheme.save.retrieve_default_scheme_roles.app_error", nil, "", http.StatusInternalServerError) 95 return result 96 } 97 } 98 99 // Create the appropriate default roles for the scheme. 100 if scheme.Scope == model.SCHEME_SCOPE_TEAM { 101 // Team Admin Role 102 teamAdminRole := &model.Role{ 103 Name: model.NewId(), 104 DisplayName: fmt.Sprintf("Team Admin Role for Scheme %s", scheme.Name), 105 Permissions: defaultRoles[model.TEAM_ADMIN_ROLE_ID].Permissions, 106 SchemeManaged: true, 107 } 108 109 if saveRoleResult := s.createRole(ctx, teamAdminRole, transaction); saveRoleResult.Err != nil { 110 result.Err = saveRoleResult.Err 111 return result 112 } else { 113 scheme.DefaultTeamAdminRole = saveRoleResult.Data.(*model.Role).Name 114 } 115 116 // Team User Role 117 teamUserRole := &model.Role{ 118 Name: model.NewId(), 119 DisplayName: fmt.Sprintf("Team User Role for Scheme %s", scheme.Name), 120 Permissions: defaultRoles[model.TEAM_USER_ROLE_ID].Permissions, 121 SchemeManaged: true, 122 } 123 124 if saveRoleResult := s.createRole(ctx, teamUserRole, transaction); saveRoleResult.Err != nil { 125 result.Err = saveRoleResult.Err 126 return result 127 } else { 128 scheme.DefaultTeamUserRole = saveRoleResult.Data.(*model.Role).Name 129 } 130 } 131 if scheme.Scope == model.SCHEME_SCOPE_TEAM || scheme.Scope == model.SCHEME_SCOPE_CHANNEL { 132 // Channel Admin Role 133 channelAdminRole := &model.Role{ 134 Name: model.NewId(), 135 DisplayName: fmt.Sprintf("Channel Admin Role for Scheme %s", scheme.Name), 136 Permissions: defaultRoles[model.CHANNEL_ADMIN_ROLE_ID].Permissions, 137 SchemeManaged: true, 138 } 139 140 if saveRoleResult := s.createRole(ctx, channelAdminRole, transaction); saveRoleResult.Err != nil { 141 result.Err = saveRoleResult.Err 142 return result 143 } else { 144 scheme.DefaultChannelAdminRole = saveRoleResult.Data.(*model.Role).Name 145 } 146 147 // Channel User Role 148 channelUserRole := &model.Role{ 149 Name: model.NewId(), 150 DisplayName: fmt.Sprintf("Channel User Role for Scheme %s", scheme.Name), 151 Permissions: defaultRoles[model.CHANNEL_USER_ROLE_ID].Permissions, 152 SchemeManaged: true, 153 } 154 155 if saveRoleResult := s.createRole(ctx, channelUserRole, transaction); saveRoleResult.Err != nil { 156 result.Err = saveRoleResult.Err 157 return result 158 } else { 159 scheme.DefaultChannelUserRole = saveRoleResult.Data.(*model.Role).Name 160 } 161 } 162 163 scheme.Id = model.NewId() 164 if len(scheme.Name) == 0 { 165 scheme.Name = model.NewId() 166 } 167 scheme.CreateAt = model.GetMillis() 168 scheme.UpdateAt = scheme.CreateAt 169 170 // Validate the scheme 171 if !scheme.IsValidForCreate() { 172 result.Err = model.NewAppError("SqlSchemeStore.Save", "store.sql_scheme.save.invalid_scheme.app_error", nil, "", http.StatusBadRequest) 173 return result 174 } 175 176 if err := transaction.Insert(scheme); err != nil { 177 result.Err = model.NewAppError("SqlSchemeStore.Save", "store.sql_scheme.save.insert.app_error", nil, err.Error(), http.StatusInternalServerError) 178 } 179 180 result.Data = scheme 181 182 return result 183 } 184 185 func (s *SqlSupplier) SchemeGet(ctx context.Context, schemeId string, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult { 186 result := store.NewSupplierResult() 187 188 var scheme model.Scheme 189 190 if err := s.GetReplica().SelectOne(&scheme, "SELECT * from Schemes WHERE Id = :Id", map[string]interface{}{"Id": schemeId}); err != nil { 191 if err == sql.ErrNoRows { 192 result.Err = model.NewAppError("SqlSchemeStore.Get", "store.sql_scheme.get.app_error", nil, "Id="+schemeId+", "+err.Error(), http.StatusNotFound) 193 } else { 194 result.Err = model.NewAppError("SqlSchemeStore.Get", "store.sql_scheme.get.app_error", nil, err.Error(), http.StatusInternalServerError) 195 } 196 } 197 198 result.Data = &scheme 199 200 return result 201 } 202 203 func (s *SqlSupplier) SchemeGetByName(ctx context.Context, schemeName string, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult { 204 result := store.NewSupplierResult() 205 206 var scheme model.Scheme 207 208 if err := s.GetReplica().SelectOne(&scheme, "SELECT * from Schemes WHERE Name = :Name", map[string]interface{}{"Name": schemeName}); err != nil { 209 if err == sql.ErrNoRows { 210 result.Err = model.NewAppError("SqlSchemeStore.GetByName", "store.sql_scheme.get.app_error", nil, "Name="+schemeName+", "+err.Error(), http.StatusNotFound) 211 } else { 212 result.Err = model.NewAppError("SqlSchemeStore.GetByName", "store.sql_scheme.get.app_error", nil, err.Error(), http.StatusInternalServerError) 213 } 214 } 215 216 result.Data = &scheme 217 218 return result 219 } 220 221 func (s *SqlSupplier) SchemeDelete(ctx context.Context, schemeId string, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult { 222 result := store.NewSupplierResult() 223 224 // Get the scheme 225 var scheme model.Scheme 226 if err := s.GetReplica().SelectOne(&scheme, "SELECT * from Schemes WHERE Id = :Id", map[string]interface{}{"Id": schemeId}); err != nil { 227 if err == sql.ErrNoRows { 228 result.Err = model.NewAppError("SqlSchemeStore.Delete", "store.sql_scheme.get.app_error", nil, "Id="+schemeId+", "+err.Error(), http.StatusNotFound) 229 } else { 230 result.Err = model.NewAppError("SqlSchemeStore.Delete", "store.sql_scheme.get.app_error", nil, "Id="+schemeId+", "+err.Error(), http.StatusInternalServerError) 231 } 232 233 return result 234 } 235 236 // Update any teams or channels using this scheme to the default scheme. 237 if scheme.Scope == model.SCHEME_SCOPE_TEAM { 238 if _, err := s.GetMaster().Exec("UPDATE Teams SET SchemeId = '' WHERE SchemeId = :SchemeId", map[string]interface{}{"SchemeId": schemeId}); err != nil { 239 result.Err = model.NewAppError("SqlSchemeStore.Delete", "store.sql_scheme.reset_teams.app_error", nil, "Id="+schemeId+", "+err.Error(), http.StatusInternalServerError) 240 return result 241 } 242 } else if scheme.Scope == model.SCHEME_SCOPE_CHANNEL { 243 if _, err := s.GetMaster().Exec("UPDATE Channels SET SchemeId = '' WHERE SchemeId = :SchemeId", map[string]interface{}{"SchemeId": schemeId}); err != nil { 244 result.Err = model.NewAppError("SqlSchemeStore.Delete", "store.sql_scheme.reset_channels.app_error", nil, "Id="+schemeId+", "+err.Error(), http.StatusInternalServerError) 245 return result 246 } 247 248 // Blow away the channel caches. 249 s.Channel().ClearCaches() 250 } 251 252 // Delete the roles belonging to the scheme. 253 roleNames := []string{scheme.DefaultChannelUserRole, scheme.DefaultChannelAdminRole} 254 if scheme.Scope == model.SCHEME_SCOPE_TEAM { 255 roleNames = append(roleNames, scheme.DefaultTeamUserRole, scheme.DefaultTeamAdminRole) 256 } 257 258 var inQueryList []string 259 queryArgs := make(map[string]interface{}) 260 for i, roleId := range roleNames { 261 inQueryList = append(inQueryList, fmt.Sprintf(":RoleName%v", i)) 262 queryArgs[fmt.Sprintf("RoleName%v", i)] = roleId 263 } 264 inQuery := strings.Join(inQueryList, ", ") 265 266 time := model.GetMillis() 267 queryArgs["UpdateAt"] = time 268 queryArgs["DeleteAt"] = time 269 270 if _, err := s.GetMaster().Exec("UPDATE Roles SET UpdateAt = :UpdateAt, DeleteAt = :DeleteAt WHERE Name IN ("+inQuery+")", queryArgs); err != nil { 271 result.Err = model.NewAppError("SqlSchemeStore.Delete", "store.sql_scheme.delete.role_update.app_error", nil, "Id="+schemeId+", "+err.Error(), http.StatusInternalServerError) 272 return result 273 } 274 275 // Delete the scheme itself. 276 scheme.UpdateAt = time 277 scheme.DeleteAt = time 278 279 if rowsChanged, err := s.GetMaster().Update(&scheme); err != nil { 280 result.Err = model.NewAppError("SqlSchemeStore.Delete", "store.sql_scheme.delete.update.app_error", nil, "Id="+schemeId+", "+err.Error(), http.StatusInternalServerError) 281 } else if rowsChanged != 1 { 282 result.Err = model.NewAppError("SqlSchemeStore.Delete", "store.sql_scheme.delete.update.app_error", nil, "no record to update", http.StatusInternalServerError) 283 } else { 284 result.Data = &scheme 285 } 286 287 return result 288 } 289 290 func (s *SqlSupplier) SchemeGetAllPage(ctx context.Context, scope string, offset int, limit int, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult { 291 result := store.NewSupplierResult() 292 293 var schemes []*model.Scheme 294 295 scopeClause := "" 296 if len(scope) > 0 { 297 scopeClause = " AND Scope=:Scope " 298 } 299 300 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 { 301 result.Err = model.NewAppError("SqlSchemeStore.Get", "store.sql_scheme.get.app_error", nil, err.Error(), http.StatusInternalServerError) 302 } 303 304 result.Data = schemes 305 306 return result 307 } 308 309 func (s *SqlSupplier) SchemePermanentDeleteAll(ctx context.Context, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult { 310 result := store.NewSupplierResult() 311 312 if _, err := s.GetMaster().Exec("DELETE from Schemes"); err != nil { 313 result.Err = model.NewAppError("SqlSchemeStore.PermanentDeleteAll", "store.sql_scheme.permanent_delete_all.app_error", nil, err.Error(), http.StatusInternalServerError) 314 } 315 316 return result 317 }