|
4 | 4 | from marshmallow import EXCLUDE, ValidationError |
5 | 5 |
|
6 | 6 | from app.config.db import tables as tbl |
7 | | -from app.config.settings.UserSettings import get_all_user_settings_schema, user_settings_dict |
| 7 | +from app.config.settings.UserSettings import get_all_user_settings_schema, user_settings_dict, UserMailViewSettings, UserMailViewSettingsObj |
8 | 8 | from app.config.settings.SogoSchema import check_data_for_sogo_schemas |
9 | 9 | from app.config.settings.DomainSettings import UserModuleSettingsObj, UserModuleSettings |
10 | 10 | from app.utils import constants as cs |
|
19 | 19 |
|
20 | 20 | if TYPE_CHECKING: |
21 | 21 | from app.config.settings.ProcessSetting import ProcessSetting |
| 22 | + from app.config.settings.DomainSettings import MailSettingsObj |
22 | 23 | from app.manager.db.ClientSQL import ClientSQL |
23 | 24 | from app.auth.User import User |
24 | 25 |
|
@@ -642,6 +643,77 @@ def update_user_preferences(self, uid:str, new_data:dict, subparent:str|None = N |
642 | 643 | return new_data[real_subparent] |
643 | 644 | return new_data |
644 | 645 |
|
| 646 | + #Map a folder "type" to the domain setting (fixed by admin) and user setting (override by user) |
| 647 | + #that hold the actual name of the corresponding special folder. |
| 648 | + _SPECIAL_FOLDER_SETTINGS_MAP: dict[str, tuple[str, str]] = { |
| 649 | + cs.MAIL_FOLDER_SENT: ("SOGO_D_MAIL_SENT", "SOGO_U_SENT_FOLDER_NAME"), |
| 650 | + cs.MAIL_FOLDER_DRAFT: ("SOGO_D_MAIL_DRAFT", "SOGO_U_DRAFT_FOLDER_NAME"), |
| 651 | + cs.MAIL_FOLDER_JUNK: ("SOGO_D_MAIL_JUNK", "SOGO_U_JUNK_FOLDER_NAME"), |
| 652 | + cs.MAIL_FOLDER_TRASH: ("SOGO_D_MAIL_TRASH", "SOGO_U_TRASH_FOLDER_NAME"), |
| 653 | + cs.MAIL_FOLDER_TEMPLATE: ("SOGO_D_MAIL_TEMPLATE", "SOGO_U_TEMPLATE_FOLDER_NAME"), |
| 654 | + } |
| 655 | + |
| 656 | + def change_folder_type(self, user: User, mail_settings: MailSettingsObj, folder_path: str, new_type: str) -> dict[str, Any]: |
| 657 | + """Change the type of a mail folder. |
| 658 | +
|
| 659 | + Assigns the folder ``folder_path`` as the special folder for the given type (SENT, DRAFT, etc). |
| 660 | + This updates the user's preference to associate that folder name with the special type. |
| 661 | +
|
| 662 | + :param user: The current user |
| 663 | + :type user: User |
| 664 | + :param mail_settings: The domain mail settings (holds admin-fixed folder names) |
| 665 | + :type mail_settings: MailSettingsObj |
| 666 | + :param folder_path: The path/name of the folder to assign as the special folder |
| 667 | + :type folder_path: str |
| 668 | + :param new_type: The new type for the folder (SENT, DRAFT, JUNK, TRASH, TEMPLATE) |
| 669 | + :type new_type: str |
| 670 | + :return: The updated folder data |
| 671 | + :rtype: dict[str, Any] |
| 672 | + :raises RequestException: If the type is invalid or the folder is already assigned to another special type |
| 673 | + """ |
| 674 | + new_type_upper = new_type.upper() |
| 675 | + setting_names = self._SPECIAL_FOLDER_SETTINGS_MAP.get(new_type_upper) |
| 676 | + if setting_names is None: |
| 677 | + logger_user_profile.error("Invalid folder type requested in change_folder_type: %s", new_type) |
| 678 | + raise RequestException(err.ERROR_FOLDER_TYPE_INVALID.m, err.ERROR_FOLDER_TYPE_INVALID) |
| 679 | + _, user_setting_name = setting_names |
| 680 | + |
| 681 | + # Get the current user mail view settings |
| 682 | + user_mail_view_prefs: dict = user.profile.preferences.get(UserMailViewSettings.subparent, {}) |
| 683 | + # Create a UserMailViewSettingsObj to access the current special folder names |
| 684 | + user_mail_view_settings = UserMailViewSettingsObj(user_mail_view_prefs) |
| 685 | + |
| 686 | + # Check that this folder is not already assigned to another special type |
| 687 | + for other_type, (other_domain_setting, other_user_setting) in self._SPECIAL_FOLDER_SETTINGS_MAP.items(): |
| 688 | + if other_type == new_type_upper: |
| 689 | + continue # Skip the type we're trying to assign |
| 690 | + |
| 691 | + # Get the current name for this other type, either from user settings or domain settings |
| 692 | + other_current_name = getattr(user_mail_view_settings, other_user_setting) or getattr(mail_settings, other_domain_setting) |
| 693 | + |
| 694 | + # If folder_path is already assigned to another special type, reject it |
| 695 | + if folder_path == other_current_name: |
| 696 | + logger_user_profile.error( |
| 697 | + "Folder '%s' is already assigned as '%s' type, cannot assign it to '%s'", |
| 698 | + folder_path, other_type, new_type_upper |
| 699 | + ) |
| 700 | + raise RequestException(err.ERROR_FOLDER_TYPE_CANNOT_CHANGE.m, err.ERROR_FOLDER_TYPE_CANNOT_CHANGE) |
| 701 | + |
| 702 | + # Update user preference to assign this folder as the special type |
| 703 | + self.update_user_preferences( |
| 704 | + user.uid, |
| 705 | + {user_setting_name: folder_path}, |
| 706 | + subparent=UserMailViewSettings.subparent.lower() |
| 707 | + ) |
| 708 | + |
| 709 | + logger_user_profile.info("Changed folder '%s' type to '%s' for uid: %s", folder_path, new_type_upper, user.uid) |
| 710 | + |
| 711 | + return { |
| 712 | + "name": folder_path, |
| 713 | + "path": folder_path, |
| 714 | + "type": new_type_upper, |
| 715 | + } |
| 716 | + |
645 | 717 | def get_delegations_given(self, user: User) -> list[str]: |
646 | 718 | """ |
647 | 719 | Get all delegations given by the user |
|
0 commit comments