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 }