github.com/nhannv/mattermost-server@v5.11.1+incompatible/app/import_functions.go (about) 1 // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. 2 // See License.txt for license information. 3 4 package app 5 6 import ( 7 "bytes" 8 "fmt" 9 "io" 10 "net/http" 11 "os" 12 "strings" 13 14 "github.com/mattermost/mattermost-server/mlog" 15 "github.com/mattermost/mattermost-server/model" 16 "github.com/mattermost/mattermost-server/store" 17 "github.com/mattermost/mattermost-server/utils" 18 ) 19 20 // 21 // -- Bulk Import Functions -- 22 // These functions import data directly into the database. Security and permission checks are bypassed but validity is 23 // still enforced. 24 // 25 26 func (a *App) ImportScheme(data *SchemeImportData, dryRun bool) *model.AppError { 27 if err := validateSchemeImportData(data); err != nil { 28 return err 29 } 30 31 // If this is a Dry Run, do not continue any further. 32 if dryRun { 33 return nil 34 } 35 36 scheme, err := a.GetSchemeByName(*data.Name) 37 if err != nil { 38 scheme = new(model.Scheme) 39 } else if scheme.Scope != *data.Scope { 40 return model.NewAppError("BulkImport", "app.import.import_scheme.scope_change.error", map[string]interface{}{"SchemeName": scheme.Name}, "", http.StatusBadRequest) 41 } 42 43 scheme.Name = *data.Name 44 scheme.DisplayName = *data.DisplayName 45 scheme.Scope = *data.Scope 46 47 if data.Description != nil { 48 scheme.Description = *data.Description 49 } 50 51 if len(scheme.Id) == 0 { 52 scheme, err = a.CreateScheme(scheme) 53 } else { 54 scheme, err = a.UpdateScheme(scheme) 55 } 56 57 if err != nil { 58 return err 59 } 60 61 if scheme.Scope == model.SCHEME_SCOPE_TEAM { 62 data.DefaultTeamAdminRole.Name = &scheme.DefaultTeamAdminRole 63 if err := a.ImportRole(data.DefaultTeamAdminRole, dryRun, true); err != nil { 64 return err 65 } 66 67 data.DefaultTeamUserRole.Name = &scheme.DefaultTeamUserRole 68 if err := a.ImportRole(data.DefaultTeamUserRole, dryRun, true); err != nil { 69 return err 70 } 71 } 72 73 if scheme.Scope == model.SCHEME_SCOPE_TEAM || scheme.Scope == model.SCHEME_SCOPE_CHANNEL { 74 data.DefaultChannelAdminRole.Name = &scheme.DefaultChannelAdminRole 75 if err := a.ImportRole(data.DefaultChannelAdminRole, dryRun, true); err != nil { 76 return err 77 } 78 79 data.DefaultChannelUserRole.Name = &scheme.DefaultChannelUserRole 80 if err := a.ImportRole(data.DefaultChannelUserRole, dryRun, true); err != nil { 81 return err 82 } 83 } 84 85 return nil 86 } 87 88 func (a *App) ImportRole(data *RoleImportData, dryRun bool, isSchemeRole bool) *model.AppError { 89 if !isSchemeRole { 90 if err := validateRoleImportData(data); err != nil { 91 return err 92 } 93 } 94 95 // If this is a Dry Run, do not continue any further. 96 if dryRun { 97 return nil 98 } 99 100 role, err := a.GetRoleByName(*data.Name) 101 if err != nil { 102 role = new(model.Role) 103 } 104 105 role.Name = *data.Name 106 107 if data.DisplayName != nil { 108 role.DisplayName = *data.DisplayName 109 } 110 111 if data.Description != nil { 112 role.Description = *data.Description 113 } 114 115 if data.Permissions != nil { 116 role.Permissions = *data.Permissions 117 } 118 119 if isSchemeRole { 120 role.SchemeManaged = true 121 } else { 122 role.SchemeManaged = false 123 } 124 125 if len(role.Id) == 0 { 126 _, err = a.CreateRole(role) 127 } else { 128 _, err = a.UpdateRole(role) 129 } 130 131 return err 132 } 133 134 func (a *App) ImportTeam(data *TeamImportData, dryRun bool) *model.AppError { 135 if err := validateTeamImportData(data); err != nil { 136 return err 137 } 138 139 // If this is a Dry Run, do not continue any further. 140 if dryRun { 141 return nil 142 } 143 144 var team *model.Team 145 if result := <-a.Srv.Store.Team().GetByName(*data.Name); result.Err == nil { 146 team = result.Data.(*model.Team) 147 } else { 148 team = &model.Team{} 149 } 150 151 team.Name = *data.Name 152 team.DisplayName = *data.DisplayName 153 team.Type = *data.Type 154 155 if data.Description != nil { 156 team.Description = *data.Description 157 } 158 159 if data.AllowOpenInvite != nil { 160 team.AllowOpenInvite = *data.AllowOpenInvite 161 } 162 163 if data.Scheme != nil { 164 scheme, err := a.GetSchemeByName(*data.Scheme) 165 if err != nil { 166 return err 167 } 168 169 if scheme.DeleteAt != 0 { 170 return model.NewAppError("BulkImport", "app.import.import_team.scheme_deleted.error", nil, "", http.StatusBadRequest) 171 } 172 173 if scheme.Scope != model.SCHEME_SCOPE_TEAM { 174 return model.NewAppError("BulkImport", "app.import.import_team.scheme_wrong_scope.error", nil, "", http.StatusBadRequest) 175 } 176 177 team.SchemeId = &scheme.Id 178 } 179 180 if team.Id == "" { 181 if _, err := a.CreateTeam(team); err != nil { 182 return err 183 } 184 } else { 185 if _, err := a.updateTeamUnsanitized(team); err != nil { 186 return err 187 } 188 } 189 190 return nil 191 } 192 193 func (a *App) ImportChannel(data *ChannelImportData, dryRun bool) *model.AppError { 194 if err := validateChannelImportData(data); err != nil { 195 return err 196 } 197 198 // If this is a Dry Run, do not continue any further. 199 if dryRun { 200 return nil 201 } 202 203 result := <-a.Srv.Store.Team().GetByName(*data.Team) 204 if result.Err != nil { 205 return model.NewAppError("BulkImport", "app.import.import_channel.team_not_found.error", map[string]interface{}{"TeamName": *data.Team}, result.Err.Error(), http.StatusBadRequest) 206 } 207 team := result.Data.(*model.Team) 208 209 var channel *model.Channel 210 if result := <-a.Srv.Store.Channel().GetByNameIncludeDeleted(team.Id, *data.Name, true); result.Err == nil { 211 channel = result.Data.(*model.Channel) 212 } else { 213 channel = &model.Channel{} 214 } 215 216 channel.TeamId = team.Id 217 channel.Name = *data.Name 218 channel.DisplayName = *data.DisplayName 219 channel.Type = *data.Type 220 221 if data.Header != nil { 222 channel.Header = *data.Header 223 } 224 225 if data.Purpose != nil { 226 channel.Purpose = *data.Purpose 227 } 228 229 if data.Scheme != nil { 230 scheme, err := a.GetSchemeByName(*data.Scheme) 231 if err != nil { 232 return err 233 } 234 235 if scheme.DeleteAt != 0 { 236 return model.NewAppError("BulkImport", "app.import.import_channel.scheme_deleted.error", nil, "", http.StatusBadRequest) 237 } 238 239 if scheme.Scope != model.SCHEME_SCOPE_CHANNEL { 240 return model.NewAppError("BulkImport", "app.import.import_channel.scheme_wrong_scope.error", nil, "", http.StatusBadRequest) 241 } 242 243 channel.SchemeId = &scheme.Id 244 } 245 246 if channel.Id == "" { 247 if _, err := a.CreateChannel(channel, false); err != nil { 248 return err 249 } 250 } else { 251 if _, err := a.UpdateChannel(channel); err != nil { 252 return err 253 } 254 } 255 256 return nil 257 } 258 259 func (a *App) ImportUser(data *UserImportData, dryRun bool) *model.AppError { 260 if err := validateUserImportData(data); err != nil { 261 return err 262 } 263 264 // If this is a Dry Run, do not continue any further. 265 if dryRun { 266 return nil 267 } 268 269 // We want to avoid database writes if nothing has changed. 270 hasUserChanged := false 271 hasNotifyPropsChanged := false 272 hasUserRolesChanged := false 273 hasUserAuthDataChanged := false 274 hasUserEmailVerifiedChanged := false 275 276 var user *model.User 277 if result := <-a.Srv.Store.User().GetByUsername(*data.Username); result.Err == nil { 278 user = result.Data.(*model.User) 279 } else { 280 user = &model.User{} 281 user.MakeNonNil() 282 user.SetDefaultNotifications() 283 hasUserChanged = true 284 } 285 286 user.Username = *data.Username 287 288 if user.Email != *data.Email { 289 hasUserChanged = true 290 hasUserEmailVerifiedChanged = true // Changing the email resets email verified to false by default. 291 user.Email = *data.Email 292 } 293 294 var password string 295 var authService string 296 var authData *string 297 298 if data.AuthService != nil { 299 if user.AuthService != *data.AuthService { 300 hasUserAuthDataChanged = true 301 } 302 authService = *data.AuthService 303 } 304 305 // AuthData and Password are mutually exclusive. 306 if data.AuthData != nil { 307 if user.AuthData == nil || *user.AuthData != *data.AuthData { 308 hasUserAuthDataChanged = true 309 } 310 authData = data.AuthData 311 password = "" 312 } else if data.Password != nil { 313 password = *data.Password 314 authData = nil 315 } else { 316 // If no AuthData or Password is specified, we must generate a password. 317 password = model.NewId() 318 authData = nil 319 } 320 321 user.Password = password 322 user.AuthService = authService 323 user.AuthData = authData 324 325 // Automatically assume all emails are verified. 326 emailVerified := true 327 if user.EmailVerified != emailVerified { 328 user.EmailVerified = emailVerified 329 hasUserEmailVerifiedChanged = true 330 } 331 332 if data.Nickname != nil { 333 if user.Nickname != *data.Nickname { 334 user.Nickname = *data.Nickname 335 hasUserChanged = true 336 } 337 } 338 339 if data.FirstName != nil { 340 if user.FirstName != *data.FirstName { 341 user.FirstName = *data.FirstName 342 hasUserChanged = true 343 } 344 } 345 346 if data.LastName != nil { 347 if user.LastName != *data.LastName { 348 user.LastName = *data.LastName 349 hasUserChanged = true 350 } 351 } 352 353 if data.Position != nil { 354 if user.Position != *data.Position { 355 user.Position = *data.Position 356 hasUserChanged = true 357 } 358 } 359 360 if data.Locale != nil { 361 if user.Locale != *data.Locale { 362 user.Locale = *data.Locale 363 hasUserChanged = true 364 } 365 } else { 366 if user.Locale != *a.Config().LocalizationSettings.DefaultClientLocale { 367 user.Locale = *a.Config().LocalizationSettings.DefaultClientLocale 368 hasUserChanged = true 369 } 370 } 371 372 if data.DeleteAt != nil { 373 if user.DeleteAt != *data.DeleteAt { 374 user.DeleteAt = *data.DeleteAt 375 hasUserChanged = true 376 } 377 } 378 379 var roles string 380 if data.Roles != nil { 381 if user.Roles != *data.Roles { 382 roles = *data.Roles 383 hasUserRolesChanged = true 384 } 385 } else if len(user.Roles) == 0 { 386 // Set SYSTEM_USER roles on newly created users by default. 387 if user.Roles != model.SYSTEM_USER_ROLE_ID { 388 roles = model.SYSTEM_USER_ROLE_ID 389 hasUserRolesChanged = true 390 } 391 } 392 user.Roles = roles 393 394 if data.NotifyProps != nil { 395 if data.NotifyProps.Desktop != nil { 396 if value, ok := user.NotifyProps[model.DESKTOP_NOTIFY_PROP]; !ok || value != *data.NotifyProps.Desktop { 397 user.AddNotifyProp(model.DESKTOP_NOTIFY_PROP, *data.NotifyProps.Desktop) 398 hasNotifyPropsChanged = true 399 } 400 } 401 402 if data.NotifyProps.DesktopSound != nil { 403 if value, ok := user.NotifyProps[model.DESKTOP_SOUND_NOTIFY_PROP]; !ok || value != *data.NotifyProps.DesktopSound { 404 user.AddNotifyProp(model.DESKTOP_SOUND_NOTIFY_PROP, *data.NotifyProps.DesktopSound) 405 hasNotifyPropsChanged = true 406 } 407 } 408 409 if data.NotifyProps.Email != nil { 410 if value, ok := user.NotifyProps[model.EMAIL_NOTIFY_PROP]; !ok || value != *data.NotifyProps.Email { 411 user.AddNotifyProp(model.EMAIL_NOTIFY_PROP, *data.NotifyProps.Email) 412 hasNotifyPropsChanged = true 413 } 414 } 415 416 if data.NotifyProps.Mobile != nil { 417 if value, ok := user.NotifyProps[model.PUSH_NOTIFY_PROP]; !ok || value != *data.NotifyProps.Mobile { 418 user.AddNotifyProp(model.PUSH_NOTIFY_PROP, *data.NotifyProps.Mobile) 419 hasNotifyPropsChanged = true 420 } 421 } 422 423 if data.NotifyProps.MobilePushStatus != nil { 424 if value, ok := user.NotifyProps[model.PUSH_STATUS_NOTIFY_PROP]; !ok || value != *data.NotifyProps.MobilePushStatus { 425 user.AddNotifyProp(model.PUSH_STATUS_NOTIFY_PROP, *data.NotifyProps.MobilePushStatus) 426 hasNotifyPropsChanged = true 427 } 428 } 429 430 if data.NotifyProps.ChannelTrigger != nil { 431 if value, ok := user.NotifyProps[model.CHANNEL_MENTIONS_NOTIFY_PROP]; !ok || value != *data.NotifyProps.ChannelTrigger { 432 user.AddNotifyProp(model.CHANNEL_MENTIONS_NOTIFY_PROP, *data.NotifyProps.ChannelTrigger) 433 hasNotifyPropsChanged = true 434 } 435 } 436 437 if data.NotifyProps.CommentsTrigger != nil { 438 if value, ok := user.NotifyProps[model.COMMENTS_NOTIFY_PROP]; !ok || value != *data.NotifyProps.CommentsTrigger { 439 user.AddNotifyProp(model.COMMENTS_NOTIFY_PROP, *data.NotifyProps.CommentsTrigger) 440 hasNotifyPropsChanged = true 441 } 442 } 443 444 if data.NotifyProps.MentionKeys != nil { 445 if value, ok := user.NotifyProps[model.MENTION_KEYS_NOTIFY_PROP]; !ok || value != *data.NotifyProps.MentionKeys { 446 user.AddNotifyProp(model.MENTION_KEYS_NOTIFY_PROP, *data.NotifyProps.MentionKeys) 447 hasNotifyPropsChanged = true 448 } 449 } else { 450 user.UpdateMentionKeysFromUsername("") 451 } 452 } 453 454 var err *model.AppError 455 var savedUser *model.User 456 if user.Id == "" { 457 if savedUser, err = a.createUser(user); err != nil { 458 return err 459 } 460 } else { 461 if hasUserChanged { 462 if savedUser, err = a.UpdateUser(user, false); err != nil { 463 return err 464 } 465 } 466 if hasUserRolesChanged { 467 if savedUser, err = a.UpdateUserRoles(user.Id, roles, false); err != nil { 468 return err 469 } 470 } 471 if hasNotifyPropsChanged { 472 if savedUser, err = a.UpdateUserNotifyProps(user.Id, user.NotifyProps); err != nil { 473 return err 474 } 475 } 476 if len(password) > 0 { 477 if err = a.UpdatePassword(user, password); err != nil { 478 return err 479 } 480 } else { 481 if hasUserAuthDataChanged { 482 if res := <-a.Srv.Store.User().UpdateAuthData(user.Id, authService, authData, user.Email, false); res.Err != nil { 483 return res.Err 484 } 485 } 486 } 487 if emailVerified { 488 if hasUserEmailVerifiedChanged { 489 if err := a.VerifyUserEmail(user.Id, user.Email); err != nil { 490 return err 491 } 492 } 493 } 494 } 495 496 if savedUser == nil { 497 savedUser = user 498 } 499 500 if data.ProfileImage != nil { 501 file, err := os.Open(*data.ProfileImage) 502 if err != nil { 503 mlog.Error("Unable to open the profile image.", mlog.Any("err", err)) 504 } 505 if err := a.SetProfileImageFromMultiPartFile(savedUser.Id, file); err != nil { 506 mlog.Error("Unable to set the profile image from a file.", mlog.Any("err", err)) 507 } 508 } 509 510 // Preferences. 511 var preferences model.Preferences 512 513 if data.Theme != nil { 514 preferences = append(preferences, model.Preference{ 515 UserId: savedUser.Id, 516 Category: model.PREFERENCE_CATEGORY_THEME, 517 Name: "", 518 Value: *data.Theme, 519 }) 520 } 521 522 if data.UseMilitaryTime != nil { 523 preferences = append(preferences, model.Preference{ 524 UserId: savedUser.Id, 525 Category: model.PREFERENCE_CATEGORY_DISPLAY_SETTINGS, 526 Name: model.PREFERENCE_NAME_USE_MILITARY_TIME, 527 Value: *data.UseMilitaryTime, 528 }) 529 } 530 531 if data.CollapsePreviews != nil { 532 preferences = append(preferences, model.Preference{ 533 UserId: savedUser.Id, 534 Category: model.PREFERENCE_CATEGORY_DISPLAY_SETTINGS, 535 Name: model.PREFERENCE_NAME_COLLAPSE_SETTING, 536 Value: *data.CollapsePreviews, 537 }) 538 } 539 540 if data.MessageDisplay != nil { 541 preferences = append(preferences, model.Preference{ 542 UserId: savedUser.Id, 543 Category: model.PREFERENCE_CATEGORY_DISPLAY_SETTINGS, 544 Name: model.PREFERENCE_NAME_MESSAGE_DISPLAY, 545 Value: *data.MessageDisplay, 546 }) 547 } 548 549 if data.ChannelDisplayMode != nil { 550 preferences = append(preferences, model.Preference{ 551 UserId: savedUser.Id, 552 Category: model.PREFERENCE_CATEGORY_DISPLAY_SETTINGS, 553 Name: "channel_display_mode", 554 Value: *data.ChannelDisplayMode, 555 }) 556 } 557 558 if data.TutorialStep != nil { 559 preferences = append(preferences, model.Preference{ 560 UserId: savedUser.Id, 561 Category: model.PREFERENCE_CATEGORY_TUTORIAL_STEPS, 562 Name: savedUser.Id, 563 Value: *data.TutorialStep, 564 }) 565 } 566 567 if data.UseMarkdownPreview != nil { 568 preferences = append(preferences, model.Preference{ 569 UserId: savedUser.Id, 570 Category: model.PREFERENCE_CATEGORY_ADVANCED_SETTINGS, 571 Name: "feature_enabled_markdown_preview", 572 Value: *data.UseMarkdownPreview, 573 }) 574 } 575 576 if data.UseFormatting != nil { 577 preferences = append(preferences, model.Preference{ 578 UserId: savedUser.Id, 579 Category: model.PREFERENCE_CATEGORY_ADVANCED_SETTINGS, 580 Name: "formatting", 581 Value: *data.UseFormatting, 582 }) 583 } 584 585 if data.ShowUnreadSection != nil { 586 preferences = append(preferences, model.Preference{ 587 UserId: savedUser.Id, 588 Category: model.PREFERENCE_CATEGORY_SIDEBAR_SETTINGS, 589 Name: "show_unread_section", 590 Value: *data.ShowUnreadSection, 591 }) 592 } 593 594 if data.EmailInterval != nil || savedUser.NotifyProps[model.EMAIL_NOTIFY_PROP] == "false" { 595 var intervalSeconds string 596 if value := savedUser.NotifyProps[model.EMAIL_NOTIFY_PROP]; value == "false" { 597 intervalSeconds = "0" 598 } else { 599 switch *data.EmailInterval { 600 case model.PREFERENCE_EMAIL_INTERVAL_IMMEDIATELY: 601 intervalSeconds = model.PREFERENCE_EMAIL_INTERVAL_NO_BATCHING_SECONDS 602 case model.PREFERENCE_EMAIL_INTERVAL_FIFTEEN: 603 intervalSeconds = model.PREFERENCE_EMAIL_INTERVAL_FIFTEEN_AS_SECONDS 604 case model.PREFERENCE_EMAIL_INTERVAL_HOUR: 605 intervalSeconds = model.PREFERENCE_EMAIL_INTERVAL_HOUR_AS_SECONDS 606 } 607 } 608 if intervalSeconds != "" { 609 preferences = append(preferences, model.Preference{ 610 UserId: savedUser.Id, 611 Category: model.PREFERENCE_CATEGORY_NOTIFICATIONS, 612 Name: model.PREFERENCE_NAME_EMAIL_INTERVAL, 613 Value: intervalSeconds, 614 }) 615 } 616 } 617 618 if len(preferences) > 0 { 619 if result := <-a.Srv.Store.Preference().Save(&preferences); result.Err != nil { 620 return model.NewAppError("BulkImport", "app.import.import_user.save_preferences.error", nil, result.Err.Error(), http.StatusInternalServerError) 621 } 622 } 623 624 return a.ImportUserTeams(savedUser, data.Teams) 625 } 626 627 func (a *App) ImportUserTeams(user *model.User, data *[]UserTeamImportData) *model.AppError { 628 if data == nil { 629 return nil 630 } 631 632 var teamThemePreferences model.Preferences 633 for _, tdata := range *data { 634 team, err := a.GetTeamByName(*tdata.Name) 635 if err != nil { 636 return err 637 } 638 639 // Team-specific theme Preferences. 640 if tdata.Theme != nil { 641 teamThemePreferences = append(teamThemePreferences, model.Preference{ 642 UserId: user.Id, 643 Category: model.PREFERENCE_CATEGORY_THEME, 644 Name: team.Id, 645 Value: *tdata.Theme, 646 }) 647 } 648 649 var roles string 650 isSchemeUser := true 651 isSchemeAdmin := false 652 653 if tdata.Roles == nil { 654 isSchemeUser = true 655 } else { 656 rawRoles := *tdata.Roles 657 explicitRoles := []string{} 658 for _, role := range strings.Fields(rawRoles) { 659 if role == model.TEAM_USER_ROLE_ID { 660 isSchemeUser = true 661 } else if role == model.TEAM_ADMIN_ROLE_ID { 662 isSchemeAdmin = true 663 } else { 664 explicitRoles = append(explicitRoles, role) 665 } 666 } 667 roles = strings.Join(explicitRoles, " ") 668 } 669 670 var member *model.TeamMember 671 if member, _, err = a.joinUserToTeam(team, user); err != nil { 672 return err 673 } 674 675 if member.ExplicitRoles != roles { 676 if _, err = a.UpdateTeamMemberRoles(team.Id, user.Id, roles); err != nil { 677 return err 678 } 679 } 680 681 if member.SchemeAdmin != isSchemeAdmin || member.SchemeUser != isSchemeUser { 682 a.UpdateTeamMemberSchemeRoles(team.Id, user.Id, isSchemeUser, isSchemeAdmin) 683 } 684 685 defaultChannel, err := a.GetChannelByName(model.DEFAULT_CHANNEL, team.Id, true) 686 if err != nil { 687 return err 688 } 689 690 if _, err = a.addUserToChannel(user, defaultChannel, member); err != nil { 691 return err 692 } 693 694 if err := a.ImportUserChannels(user, team, member, tdata.Channels); err != nil { 695 return err 696 } 697 } 698 699 if len(teamThemePreferences) > 0 { 700 if result := <-a.Srv.Store.Preference().Save(&teamThemePreferences); result.Err != nil { 701 return model.NewAppError("BulkImport", "app.import.import_user_teams.save_preferences.error", nil, result.Err.Error(), http.StatusInternalServerError) 702 } 703 } 704 705 return nil 706 } 707 708 func (a *App) ImportUserChannels(user *model.User, team *model.Team, teamMember *model.TeamMember, data *[]UserChannelImportData) *model.AppError { 709 if data == nil { 710 return nil 711 } 712 713 var preferences model.Preferences 714 715 // Loop through all channels. 716 for _, cdata := range *data { 717 channel, err := a.GetChannelByName(*cdata.Name, team.Id, true) 718 if err != nil { 719 return err 720 } 721 722 var roles string 723 isSchemeUser := true 724 isSchemeAdmin := false 725 726 if cdata.Roles == nil { 727 isSchemeUser = true 728 } else { 729 rawRoles := *cdata.Roles 730 explicitRoles := []string{} 731 for _, role := range strings.Fields(rawRoles) { 732 if role == model.CHANNEL_USER_ROLE_ID { 733 isSchemeUser = true 734 } else if role == model.CHANNEL_ADMIN_ROLE_ID { 735 isSchemeAdmin = true 736 } else { 737 explicitRoles = append(explicitRoles, role) 738 } 739 } 740 roles = strings.Join(explicitRoles, " ") 741 } 742 743 var member *model.ChannelMember 744 member, err = a.GetChannelMember(channel.Id, user.Id) 745 if err != nil { 746 member, err = a.addUserToChannel(user, channel, teamMember) 747 if err != nil { 748 return err 749 } 750 } 751 752 if member.ExplicitRoles != roles { 753 if _, err := a.UpdateChannelMemberRoles(channel.Id, user.Id, roles); err != nil { 754 return err 755 } 756 } 757 758 if member.SchemeAdmin != isSchemeAdmin || member.SchemeUser != isSchemeUser { 759 a.UpdateChannelMemberSchemeRoles(channel.Id, user.Id, isSchemeUser, isSchemeAdmin) 760 } 761 762 if cdata.NotifyProps != nil { 763 notifyProps := member.NotifyProps 764 765 if cdata.NotifyProps.Desktop != nil { 766 notifyProps[model.DESKTOP_NOTIFY_PROP] = *cdata.NotifyProps.Desktop 767 } 768 769 if cdata.NotifyProps.Mobile != nil { 770 notifyProps[model.PUSH_NOTIFY_PROP] = *cdata.NotifyProps.Mobile 771 } 772 773 if cdata.NotifyProps.MarkUnread != nil { 774 notifyProps[model.MARK_UNREAD_NOTIFY_PROP] = *cdata.NotifyProps.MarkUnread 775 } 776 777 if _, err := a.UpdateChannelMemberNotifyProps(notifyProps, channel.Id, user.Id); err != nil { 778 return err 779 } 780 } 781 782 if cdata.Favorite != nil && *cdata.Favorite { 783 preferences = append(preferences, model.Preference{ 784 UserId: user.Id, 785 Category: model.PREFERENCE_CATEGORY_FAVORITE_CHANNEL, 786 Name: channel.Id, 787 Value: "true", 788 }) 789 } 790 } 791 792 if len(preferences) > 0 { 793 if result := <-a.Srv.Store.Preference().Save(&preferences); result.Err != nil { 794 return model.NewAppError("BulkImport", "app.import.import_user_channels.save_preferences.error", nil, result.Err.Error(), http.StatusInternalServerError) 795 } 796 } 797 798 return nil 799 } 800 801 func (a *App) ImportReaction(data *ReactionImportData, post *model.Post, dryRun bool) *model.AppError { 802 if err := validateReactionImportData(data, post.CreateAt); err != nil { 803 return err 804 } 805 806 result := <-a.Srv.Store.User().GetByUsername(*data.User) 807 if result.Err != nil { 808 return model.NewAppError("BulkImport", "app.import.import_post.user_not_found.error", map[string]interface{}{"Username": data.User}, result.Err.Error(), http.StatusBadRequest) 809 } 810 user := result.Data.(*model.User) 811 812 reaction := &model.Reaction{ 813 UserId: user.Id, 814 PostId: post.Id, 815 EmojiName: *data.EmojiName, 816 CreateAt: *data.CreateAt, 817 } 818 if result := <-a.Srv.Store.Reaction().Save(reaction); result.Err != nil { 819 return result.Err 820 } 821 return nil 822 } 823 824 func (a *App) ImportReply(data *ReplyImportData, post *model.Post, teamId string, dryRun bool) *model.AppError { 825 if err := validateReplyImportData(data, post.CreateAt, a.MaxPostSize()); err != nil { 826 return err 827 } 828 829 result := <-a.Srv.Store.User().GetByUsername(*data.User) 830 if result.Err != nil { 831 return model.NewAppError("BulkImport", "app.import.import_post.user_not_found.error", map[string]interface{}{"Username": data.User}, result.Err.Error(), http.StatusBadRequest) 832 } 833 user := result.Data.(*model.User) 834 835 // Check if this post already exists. 836 result = <-a.Srv.Store.Post().GetPostsCreatedAt(post.ChannelId, *data.CreateAt) 837 if result.Err != nil { 838 return result.Err 839 } 840 replies := result.Data.([]*model.Post) 841 842 var reply *model.Post 843 for _, r := range replies { 844 if r.Message == *data.Message && r.RootId == post.Id { 845 reply = r 846 break 847 } 848 } 849 850 if reply == nil { 851 reply = &model.Post{} 852 } 853 reply.UserId = user.Id 854 reply.ChannelId = post.ChannelId 855 reply.ParentId = post.Id 856 reply.RootId = post.Id 857 reply.Message = *data.Message 858 reply.CreateAt = *data.CreateAt 859 860 if data.Attachments != nil { 861 fileIds, err := a.uploadAttachments(data.Attachments, reply, teamId, dryRun) 862 if err != nil { 863 return err 864 } 865 reply.FileIds = append(reply.FileIds, fileIds...) 866 } 867 868 if reply.Id == "" { 869 if result := <-a.Srv.Store.Post().Save(reply); result.Err != nil { 870 return result.Err 871 } 872 } else { 873 if result := <-a.Srv.Store.Post().Overwrite(reply); result.Err != nil { 874 return result.Err 875 } 876 } 877 878 a.UpdateFileInfoWithPostId(reply) 879 880 return nil 881 } 882 883 func (a *App) ImportAttachment(data *AttachmentImportData, post *model.Post, teamId string, dryRun bool) (*model.FileInfo, *model.AppError) { 884 fileUploadError := model.NewAppError("BulkImport", "app.import.attachment.file_upload.error", map[string]interface{}{"FilePath": *data.Path}, "", http.StatusBadRequest) 885 file, err := os.Open(*data.Path) 886 if err != nil { 887 return nil, model.NewAppError("BulkImport", "app.import.attachment.bad_file.error", map[string]interface{}{"FilePath": *data.Path}, "", http.StatusBadRequest) 888 } 889 if file != nil { 890 timestamp := utils.TimeFromMillis(post.CreateAt) 891 buf := bytes.NewBuffer(nil) 892 io.Copy(buf, file) 893 894 fileInfo, err := a.DoUploadFile(timestamp, teamId, post.ChannelId, post.UserId, file.Name(), buf.Bytes()) 895 896 if err != nil { 897 fmt.Print(err) 898 return nil, fileUploadError 899 } 900 901 a.HandleImages([]string{fileInfo.PreviewPath}, []string{fileInfo.ThumbnailPath}, [][]byte{buf.Bytes()}) 902 903 mlog.Info(fmt.Sprintf("uploading file with name %s", file.Name())) 904 return fileInfo, nil 905 } 906 return nil, fileUploadError 907 } 908 909 func (a *App) ImportPost(data *PostImportData, dryRun bool) *model.AppError { 910 if err := validatePostImportData(data, a.MaxPostSize()); err != nil { 911 return err 912 } 913 914 // If this is a Dry Run, do not continue any further. 915 if dryRun { 916 return nil 917 } 918 919 result := <-a.Srv.Store.Team().GetByName(*data.Team) 920 if result.Err != nil { 921 return model.NewAppError("BulkImport", "app.import.import_post.team_not_found.error", map[string]interface{}{"TeamName": *data.Team}, result.Err.Error(), http.StatusBadRequest) 922 } 923 team := result.Data.(*model.Team) 924 925 result = <-a.Srv.Store.Channel().GetByName(team.Id, *data.Channel, false) 926 if result.Err != nil { 927 return model.NewAppError("BulkImport", "app.import.import_post.channel_not_found.error", map[string]interface{}{"ChannelName": *data.Channel}, result.Err.Error(), http.StatusBadRequest) 928 } 929 channel := result.Data.(*model.Channel) 930 931 result = <-a.Srv.Store.User().GetByUsername(*data.User) 932 if result.Err != nil { 933 return model.NewAppError("BulkImport", "app.import.import_post.user_not_found.error", map[string]interface{}{"Username": *data.User}, result.Err.Error(), http.StatusBadRequest) 934 } 935 user := result.Data.(*model.User) 936 937 // Check if this post already exists. 938 result = <-a.Srv.Store.Post().GetPostsCreatedAt(channel.Id, *data.CreateAt) 939 if result.Err != nil { 940 return result.Err 941 } 942 posts := result.Data.([]*model.Post) 943 944 var post *model.Post 945 for _, p := range posts { 946 if p.Message == *data.Message { 947 post = p 948 break 949 } 950 } 951 952 if post == nil { 953 post = &model.Post{} 954 } 955 956 post.ChannelId = channel.Id 957 post.Message = *data.Message 958 post.UserId = user.Id 959 post.CreateAt = *data.CreateAt 960 961 post.Hashtags, _ = model.ParseHashtags(post.Message) 962 963 if data.Attachments != nil { 964 fileIds, err := a.uploadAttachments(data.Attachments, post, team.Id, dryRun) 965 if err != nil { 966 return err 967 } 968 post.FileIds = append(post.FileIds, fileIds...) 969 } 970 971 if post.Id == "" { 972 if result := <-a.Srv.Store.Post().Save(post); result.Err != nil { 973 return result.Err 974 } 975 } else { 976 if result := <-a.Srv.Store.Post().Overwrite(post); result.Err != nil { 977 return result.Err 978 } 979 } 980 981 if data.FlaggedBy != nil { 982 var preferences model.Preferences 983 984 for _, username := range *data.FlaggedBy { 985 result := <-a.Srv.Store.User().GetByUsername(username) 986 if result.Err != nil { 987 return model.NewAppError("BulkImport", "app.import.import_post.user_not_found.error", map[string]interface{}{"Username": username}, result.Err.Error(), http.StatusBadRequest) 988 } 989 user := result.Data.(*model.User) 990 991 preferences = append(preferences, model.Preference{ 992 UserId: user.Id, 993 Category: model.PREFERENCE_CATEGORY_FLAGGED_POST, 994 Name: post.Id, 995 Value: "true", 996 }) 997 } 998 999 if len(preferences) > 0 { 1000 if result := <-a.Srv.Store.Preference().Save(&preferences); result.Err != nil { 1001 return model.NewAppError("BulkImport", "app.import.import_post.save_preferences.error", nil, result.Err.Error(), http.StatusInternalServerError) 1002 } 1003 } 1004 } 1005 1006 if data.Reactions != nil { 1007 for _, reaction := range *data.Reactions { 1008 if err := a.ImportReaction(&reaction, post, dryRun); err != nil { 1009 return err 1010 } 1011 } 1012 } 1013 1014 if data.Replies != nil { 1015 for _, reply := range *data.Replies { 1016 if err := a.ImportReply(&reply, post, team.Id, dryRun); err != nil { 1017 return err 1018 } 1019 } 1020 } 1021 1022 a.UpdateFileInfoWithPostId(post) 1023 return nil 1024 } 1025 1026 func (a *App) uploadAttachments(attachments *[]AttachmentImportData, post *model.Post, teamId string, dryRun bool) ([]string, *model.AppError) { 1027 fileIds := []string{} 1028 for _, attachment := range *attachments { 1029 fileInfo, err := a.ImportAttachment(&attachment, post, teamId, dryRun) 1030 if err != nil { 1031 return nil, err 1032 } 1033 fileIds = append(fileIds, fileInfo.Id) 1034 } 1035 return fileIds, nil 1036 } 1037 1038 func (a *App) UpdateFileInfoWithPostId(post *model.Post) { 1039 for _, fileId := range post.FileIds { 1040 if result := <-a.Srv.Store.FileInfo().AttachToPost(fileId, post.Id, post.UserId); result.Err != nil { 1041 mlog.Error(fmt.Sprintf("Error attaching files to post. postId=%v, fileIds=%v, message=%v", post.Id, post.FileIds, result.Err), mlog.String("post_id", post.Id)) 1042 } 1043 } 1044 } 1045 func (a *App) ImportDirectChannel(data *DirectChannelImportData, dryRun bool) *model.AppError { 1046 if err := validateDirectChannelImportData(data); err != nil { 1047 return err 1048 } 1049 1050 // If this is a Dry Run, do not continue any further. 1051 if dryRun { 1052 return nil 1053 } 1054 1055 var userIds []string 1056 userMap := make(map[string]string) 1057 for _, username := range *data.Members { 1058 result := <-a.Srv.Store.User().GetByUsername(username) 1059 if result.Err != nil { 1060 return model.NewAppError("BulkImport", "app.import.import_direct_channel.member_not_found.error", nil, result.Err.Error(), http.StatusBadRequest) 1061 } 1062 user := result.Data.(*model.User) 1063 userIds = append(userIds, user.Id) 1064 userMap[username] = user.Id 1065 } 1066 1067 var channel *model.Channel 1068 1069 if len(userIds) == 2 { 1070 ch, err := a.createDirectChannel(userIds[0], userIds[1]) 1071 if err != nil && err.Id != store.CHANNEL_EXISTS_ERROR { 1072 return model.NewAppError("BulkImport", "app.import.import_direct_channel.create_direct_channel.error", nil, err.Error(), http.StatusBadRequest) 1073 } 1074 channel = ch 1075 } else { 1076 ch, err := a.createGroupChannel(userIds, userIds[0]) 1077 if err != nil && err.Id != store.CHANNEL_EXISTS_ERROR { 1078 return model.NewAppError("BulkImport", "app.import.import_direct_channel.create_group_channel.error", nil, err.Error(), http.StatusBadRequest) 1079 } 1080 channel = ch 1081 } 1082 1083 var preferences model.Preferences 1084 1085 for _, userId := range userIds { 1086 preferences = append(preferences, model.Preference{ 1087 UserId: userId, 1088 Category: model.PREFERENCE_CATEGORY_DIRECT_CHANNEL_SHOW, 1089 Name: channel.Id, 1090 Value: "true", 1091 }) 1092 } 1093 1094 if data.FavoritedBy != nil { 1095 for _, favoriter := range *data.FavoritedBy { 1096 preferences = append(preferences, model.Preference{ 1097 UserId: userMap[favoriter], 1098 Category: model.PREFERENCE_CATEGORY_FAVORITE_CHANNEL, 1099 Name: channel.Id, 1100 Value: "true", 1101 }) 1102 } 1103 } 1104 1105 if result := <-a.Srv.Store.Preference().Save(&preferences); result.Err != nil { 1106 result.Err.StatusCode = http.StatusBadRequest 1107 return result.Err 1108 } 1109 1110 if data.Header != nil { 1111 channel.Header = *data.Header 1112 if result := <-a.Srv.Store.Channel().Update(channel); result.Err != nil { 1113 return model.NewAppError("BulkImport", "app.import.import_direct_channel.update_header_failed.error", nil, result.Err.Error(), http.StatusBadRequest) 1114 } 1115 } 1116 1117 return nil 1118 } 1119 1120 func (a *App) ImportDirectPost(data *DirectPostImportData, dryRun bool) *model.AppError { 1121 if err := validateDirectPostImportData(data, a.MaxPostSize()); err != nil { 1122 return err 1123 } 1124 1125 // If this is a Dry Run, do not continue any further. 1126 if dryRun { 1127 return nil 1128 } 1129 1130 var userIds []string 1131 for _, username := range *data.ChannelMembers { 1132 result := <-a.Srv.Store.User().GetByUsername(username) 1133 if result.Err != nil { 1134 return model.NewAppError("BulkImport", "app.import.import_direct_post.channel_member_not_found.error", nil, result.Err.Error(), http.StatusBadRequest) 1135 } 1136 user := result.Data.(*model.User) 1137 userIds = append(userIds, user.Id) 1138 } 1139 1140 var channel *model.Channel 1141 if len(userIds) == 2 { 1142 ch, err := a.createDirectChannel(userIds[0], userIds[1]) 1143 if err != nil && err.Id != store.CHANNEL_EXISTS_ERROR { 1144 return model.NewAppError("BulkImport", "app.import.import_direct_post.create_direct_channel.error", nil, err.Error(), http.StatusBadRequest) 1145 } 1146 channel = ch 1147 } else { 1148 ch, err := a.createGroupChannel(userIds, userIds[0]) 1149 if err != nil && err.Id != store.CHANNEL_EXISTS_ERROR { 1150 return model.NewAppError("BulkImport", "app.import.import_direct_post.create_group_channel.error", nil, err.Error(), http.StatusBadRequest) 1151 } 1152 channel = ch 1153 } 1154 1155 result := <-a.Srv.Store.User().GetByUsername(*data.User) 1156 if result.Err != nil { 1157 return model.NewAppError("BulkImport", "app.import.import_direct_post.user_not_found.error", map[string]interface{}{"Username": *data.User}, "", http.StatusBadRequest) 1158 } 1159 user := result.Data.(*model.User) 1160 1161 // Check if this post already exists. 1162 result = <-a.Srv.Store.Post().GetPostsCreatedAt(channel.Id, *data.CreateAt) 1163 if result.Err != nil { 1164 return result.Err 1165 } 1166 posts := result.Data.([]*model.Post) 1167 1168 var post *model.Post 1169 for _, p := range posts { 1170 if p.Message == *data.Message { 1171 post = p 1172 break 1173 } 1174 } 1175 1176 if post == nil { 1177 post = &model.Post{} 1178 } 1179 1180 post.ChannelId = channel.Id 1181 post.Message = *data.Message 1182 post.UserId = user.Id 1183 post.CreateAt = *data.CreateAt 1184 1185 post.Hashtags, _ = model.ParseHashtags(post.Message) 1186 1187 if data.Attachments != nil { 1188 fileIds, err := a.uploadAttachments(data.Attachments, post, "noteam", dryRun) 1189 if err != nil { 1190 return err 1191 } 1192 post.FileIds = append(post.FileIds, fileIds...) 1193 } 1194 1195 if post.Id == "" { 1196 if result := <-a.Srv.Store.Post().Save(post); result.Err != nil { 1197 return result.Err 1198 } 1199 } else { 1200 if result := <-a.Srv.Store.Post().Overwrite(post); result.Err != nil { 1201 return result.Err 1202 } 1203 } 1204 1205 if data.FlaggedBy != nil { 1206 var preferences model.Preferences 1207 1208 for _, username := range *data.FlaggedBy { 1209 result := <-a.Srv.Store.User().GetByUsername(username) 1210 if result.Err != nil { 1211 return model.NewAppError("BulkImport", "app.import.import_direct_post.user_not_found.error", map[string]interface{}{"Username": username}, "", http.StatusBadRequest) 1212 } 1213 user := result.Data.(*model.User) 1214 1215 preferences = append(preferences, model.Preference{ 1216 UserId: user.Id, 1217 Category: model.PREFERENCE_CATEGORY_FLAGGED_POST, 1218 Name: post.Id, 1219 Value: "true", 1220 }) 1221 } 1222 1223 if len(preferences) > 0 { 1224 if result := <-a.Srv.Store.Preference().Save(&preferences); result.Err != nil { 1225 return model.NewAppError("BulkImport", "app.import.import_direct_post.save_preferences.error", nil, result.Err.Error(), http.StatusInternalServerError) 1226 } 1227 } 1228 } 1229 1230 if data.Reactions != nil { 1231 for _, reaction := range *data.Reactions { 1232 if err := a.ImportReaction(&reaction, post, dryRun); err != nil { 1233 return err 1234 } 1235 } 1236 } 1237 1238 if data.Replies != nil { 1239 for _, reply := range *data.Replies { 1240 if err := a.ImportReply(&reply, post, "noteam", dryRun); err != nil { 1241 return err 1242 } 1243 } 1244 } 1245 1246 a.UpdateFileInfoWithPostId(post) 1247 return nil 1248 } 1249 1250 func (a *App) ImportEmoji(data *EmojiImportData, dryRun bool) *model.AppError { 1251 if err := validateEmojiImportData(data); err != nil { 1252 return err 1253 } 1254 1255 // If this is a Dry Run, do not continue any further. 1256 if dryRun { 1257 return nil 1258 } 1259 1260 var emoji *model.Emoji 1261 1262 result := <-a.Srv.Store.Emoji().GetByName(*data.Name) 1263 if result.Err != nil && result.Err.StatusCode != http.StatusNotFound { 1264 return result.Err 1265 } 1266 1267 if result.Data != nil { 1268 emoji = result.Data.(*model.Emoji) 1269 } 1270 1271 alreadyExists := emoji != nil 1272 1273 if !alreadyExists { 1274 emoji = &model.Emoji{ 1275 Name: *data.Name, 1276 } 1277 emoji.PreSave() 1278 } 1279 1280 file, err := os.Open(*data.Image) 1281 if err != nil { 1282 return model.NewAppError("BulkImport", "app.import.emoji.bad_file.error", map[string]interface{}{"EmojiName": *data.Name}, "", http.StatusBadRequest) 1283 } 1284 1285 if _, err := a.WriteFile(file, getEmojiImagePath(emoji.Id)); err != nil { 1286 return err 1287 } 1288 1289 if !alreadyExists { 1290 if result := <-a.Srv.Store.Emoji().Save(emoji); result.Err != nil { 1291 return result.Err 1292 } 1293 } 1294 1295 return nil 1296 }