github.com/qichengzx/mattermost-server@v4.5.1-0.20180604164826-2c75247c97d0+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 result = s.createScheme(ctx, scheme, transaction, hints...) 42 43 if result.Err != nil { 44 transaction.Rollback() 45 } else 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 } else { 50 if !scheme.IsValid() { 51 result.Err = model.NewAppError("SqlSchemeStore.Save", "store.sql_scheme.save.invalid_scheme.app_error", nil, "", http.StatusBadRequest) 52 return result 53 } 54 55 scheme.UpdateAt = model.GetMillis() 56 57 if rowsChanged, err := s.GetMaster().Update(scheme); err != nil { 58 result.Err = model.NewAppError("SqlSchemeStore.Save", "store.sql_scheme.save.update.app_error", nil, err.Error(), http.StatusInternalServerError) 59 } else if rowsChanged != 1 { 60 result.Err = model.NewAppError("SqlSchemeStore.Save", "store.sql_scheme.save.update.app_error", nil, "no record to update", http.StatusInternalServerError) 61 } 62 63 result.Data = scheme 64 } 65 66 return result 67 } 68 69 func (s *SqlSupplier) createScheme(ctx context.Context, scheme *model.Scheme, transaction *gorp.Transaction, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult { 70 result := store.NewSupplierResult() 71 72 // Fetch the default system scheme roles to populate default permissions. 73 defaultRoleNames := []string{model.TEAM_ADMIN_ROLE_ID, model.TEAM_USER_ROLE_ID, model.CHANNEL_ADMIN_ROLE_ID, model.CHANNEL_USER_ROLE_ID} 74 defaultRoles := make(map[string]*model.Role) 75 if rolesResult := s.RoleGetByNames(ctx, defaultRoleNames); rolesResult.Err != nil { 76 result.Err = rolesResult.Err 77 return result 78 } else { 79 for _, role := range rolesResult.Data.([]*model.Role) { 80 switch role.Name { 81 case model.TEAM_ADMIN_ROLE_ID: 82 defaultRoles[model.TEAM_ADMIN_ROLE_ID] = role 83 case model.TEAM_USER_ROLE_ID: 84 defaultRoles[model.TEAM_USER_ROLE_ID] = role 85 case model.CHANNEL_ADMIN_ROLE_ID: 86 defaultRoles[model.CHANNEL_ADMIN_ROLE_ID] = role 87 case model.CHANNEL_USER_ROLE_ID: 88 defaultRoles[model.CHANNEL_USER_ROLE_ID] = role 89 } 90 } 91 92 if len(defaultRoles) != 4 { 93 result.Err = model.NewAppError("SqlSchemeStore.SaveScheme", "store.sql_scheme.save.retrieve_default_scheme_roles.app_error", nil, "", http.StatusInternalServerError) 94 return result 95 } 96 } 97 98 // Create the appropriate default roles for the scheme. 99 if scheme.Scope == model.SCHEME_SCOPE_TEAM { 100 // Team Admin Role 101 teamAdminRole := &model.Role{ 102 Name: model.NewId(), 103 DisplayName: fmt.Sprintf("Team Admin Role for Scheme %s", scheme.Name), 104 Permissions: defaultRoles[model.TEAM_ADMIN_ROLE_ID].Permissions, 105 SchemeManaged: true, 106 } 107 108 if saveRoleResult := s.createRole(ctx, teamAdminRole, transaction); saveRoleResult.Err != nil { 109 result.Err = saveRoleResult.Err 110 return result 111 } else { 112 scheme.DefaultTeamAdminRole = saveRoleResult.Data.(*model.Role).Name 113 } 114 115 // Team User Role 116 teamUserRole := &model.Role{ 117 Name: model.NewId(), 118 DisplayName: fmt.Sprintf("Team User Role for Scheme %s", scheme.Name), 119 Permissions: defaultRoles[model.TEAM_USER_ROLE_ID].Permissions, 120 SchemeManaged: true, 121 } 122 123 if saveRoleResult := s.createRole(ctx, teamUserRole, transaction); saveRoleResult.Err != nil { 124 result.Err = saveRoleResult.Err 125 return result 126 } else { 127 scheme.DefaultTeamUserRole = saveRoleResult.Data.(*model.Role).Name 128 } 129 } 130 if scheme.Scope == model.SCHEME_SCOPE_TEAM || scheme.Scope == model.SCHEME_SCOPE_CHANNEL { 131 // Channel Admin Role 132 channelAdminRole := &model.Role{ 133 Name: model.NewId(), 134 DisplayName: fmt.Sprintf("Channel Admin Role for Scheme %s", scheme.Name), 135 Permissions: defaultRoles[model.CHANNEL_ADMIN_ROLE_ID].Permissions, 136 SchemeManaged: true, 137 } 138 139 if saveRoleResult := s.createRole(ctx, channelAdminRole, transaction); saveRoleResult.Err != nil { 140 result.Err = saveRoleResult.Err 141 return result 142 } else { 143 scheme.DefaultChannelAdminRole = saveRoleResult.Data.(*model.Role).Name 144 } 145 146 // Channel User Role 147 channelUserRole := &model.Role{ 148 Name: model.NewId(), 149 DisplayName: fmt.Sprintf("Channel User Role for Scheme %s", scheme.Name), 150 Permissions: defaultRoles[model.CHANNEL_USER_ROLE_ID].Permissions, 151 SchemeManaged: true, 152 } 153 154 if saveRoleResult := s.createRole(ctx, channelUserRole, transaction); saveRoleResult.Err != nil { 155 result.Err = saveRoleResult.Err 156 return result 157 } else { 158 scheme.DefaultChannelUserRole = saveRoleResult.Data.(*model.Role).Name 159 } 160 } 161 162 scheme.Id = model.NewId() 163 if len(scheme.Name) == 0 { 164 scheme.Name = model.NewId() 165 } 166 scheme.CreateAt = model.GetMillis() 167 scheme.UpdateAt = scheme.CreateAt 168 169 // Validate the scheme 170 if !scheme.IsValidForCreate() { 171 result.Err = model.NewAppError("SqlSchemeStore.Save", "store.sql_scheme.save.invalid_scheme.app_error", nil, "", http.StatusBadRequest) 172 return result 173 } 174 175 if err := transaction.Insert(scheme); err != nil { 176 result.Err = model.NewAppError("SqlSchemeStore.Save", "store.sql_scheme.save.insert.app_error", nil, err.Error(), http.StatusInternalServerError) 177 } 178 179 result.Data = scheme 180 181 return result 182 } 183 184 func (s *SqlSupplier) SchemeGet(ctx context.Context, schemeId string, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult { 185 result := store.NewSupplierResult() 186 187 var scheme model.Scheme 188 189 if err := s.GetReplica().SelectOne(&scheme, "SELECT * from Schemes WHERE Id = :Id", map[string]interface{}{"Id": schemeId}); err != nil { 190 if err == sql.ErrNoRows { 191 result.Err = model.NewAppError("SqlSchemeStore.Get", "store.sql_scheme.get.app_error", nil, "Id="+schemeId+", "+err.Error(), http.StatusNotFound) 192 } else { 193 result.Err = model.NewAppError("SqlSchemeStore.Get", "store.sql_scheme.get.app_error", nil, err.Error(), http.StatusInternalServerError) 194 } 195 } 196 197 result.Data = &scheme 198 199 return result 200 } 201 202 func (s *SqlSupplier) SchemeDelete(ctx context.Context, schemeId string, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult { 203 result := store.NewSupplierResult() 204 205 // Get the scheme 206 var scheme model.Scheme 207 if err := s.GetReplica().SelectOne(&scheme, "SELECT * from Schemes WHERE Id = :Id", map[string]interface{}{"Id": schemeId}); err != nil { 208 if err == sql.ErrNoRows { 209 result.Err = model.NewAppError("SqlSchemeStore.Delete", "store.sql_scheme.get.app_error", nil, "Id="+schemeId+", "+err.Error(), http.StatusNotFound) 210 } else { 211 result.Err = model.NewAppError("SqlSchemeStore.Delete", "store.sql_scheme.get.app_error", nil, "Id="+schemeId+", "+err.Error(), http.StatusInternalServerError) 212 } 213 214 return result 215 } 216 217 // Update any teams or channels using this scheme to the default scheme. 218 if scheme.Scope == model.SCHEME_SCOPE_TEAM { 219 if _, err := s.GetMaster().Exec("UPDATE Teams SET SchemeId = '' WHERE SchemeId = :SchemeId", map[string]interface{}{"SchemeId": schemeId}); err != nil { 220 result.Err = model.NewAppError("SqlSchemeStore.Delete", "store.sql_scheme.reset_teams.app_error", nil, "Id="+schemeId+", "+err.Error(), http.StatusInternalServerError) 221 return result 222 } 223 } else if scheme.Scope == model.SCHEME_SCOPE_CHANNEL { 224 if _, err := s.GetMaster().Exec("UPDATE Channels SET SchemeId = '' WHERE SchemeId = :SchemeId", map[string]interface{}{"SchemeId": schemeId}); err != nil { 225 result.Err = model.NewAppError("SqlSchemeStore.Delete", "store.sql_scheme.reset_channels.app_error", nil, "Id="+schemeId+", "+err.Error(), http.StatusInternalServerError) 226 return result 227 } 228 229 // Blow away the channel caches. 230 s.Channel().ClearCaches() 231 } 232 233 // Delete the roles belonging to the scheme. 234 roleNames := []string{scheme.DefaultChannelUserRole, scheme.DefaultChannelAdminRole} 235 if scheme.Scope == model.SCHEME_SCOPE_TEAM { 236 roleNames = append(roleNames, scheme.DefaultTeamUserRole, scheme.DefaultTeamAdminRole) 237 } 238 239 var inQueryList []string 240 queryArgs := make(map[string]interface{}) 241 for i, roleId := range roleNames { 242 inQueryList = append(inQueryList, fmt.Sprintf(":RoleName%v", i)) 243 queryArgs[fmt.Sprintf("RoleName%v", i)] = roleId 244 } 245 inQuery := strings.Join(inQueryList, ", ") 246 247 time := model.GetMillis() 248 queryArgs["UpdateAt"] = time 249 queryArgs["DeleteAt"] = time 250 251 if _, err := s.GetMaster().Exec("UPDATE Roles SET UpdateAt = :UpdateAt, DeleteAt = :DeleteAt WHERE Name IN ("+inQuery+")", queryArgs); err != nil { 252 result.Err = model.NewAppError("SqlSchemeStore.Delete", "store.sql_scheme.delete.role_update.app_error", nil, "Id="+schemeId+", "+err.Error(), http.StatusInternalServerError) 253 return result 254 } 255 256 // Delete the scheme itself. 257 scheme.UpdateAt = time 258 scheme.DeleteAt = time 259 260 if rowsChanged, err := s.GetMaster().Update(&scheme); err != nil { 261 result.Err = model.NewAppError("SqlSchemeStore.Delete", "store.sql_scheme.delete.update.app_error", nil, "Id="+schemeId+", "+err.Error(), http.StatusInternalServerError) 262 } else if rowsChanged != 1 { 263 result.Err = model.NewAppError("SqlSchemeStore.Delete", "store.sql_scheme.delete.update.app_error", nil, "no record to update", http.StatusInternalServerError) 264 } else { 265 result.Data = &scheme 266 } 267 268 return result 269 } 270 271 func (s *SqlSupplier) SchemeGetAllPage(ctx context.Context, scope string, offset int, limit int, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult { 272 result := store.NewSupplierResult() 273 274 var schemes []*model.Scheme 275 276 scopeClause := "" 277 if len(scope) > 0 { 278 scopeClause = " AND Scope=:Scope " 279 } 280 281 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 { 282 result.Err = model.NewAppError("SqlSchemeStore.Get", "store.sql_scheme.get.app_error", nil, err.Error(), http.StatusInternalServerError) 283 } 284 285 result.Data = schemes 286 287 return result 288 } 289 290 func (s *SqlSupplier) SchemePermanentDeleteAll(ctx context.Context, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult { 291 result := store.NewSupplierResult() 292 293 if _, err := s.GetMaster().Exec("DELETE from Schemes"); err != nil { 294 result.Err = model.NewAppError("SqlSchemeStore.PermanentDeleteAll", "store.sql_scheme.permanent_delete_all.app_error", nil, err.Error(), http.StatusInternalServerError) 295 } 296 297 return result 298 }