From d905cee6acd8905abfae70ea543d98d1818c9783 Mon Sep 17 00:00:00 2001 From: rendurama Date: Fri, 5 Jul 2024 13:09:44 +0530 Subject: [PATCH] ZCS-15079 POC | Hide alias in GAL --- .../common/account/ZAttrProvisioning.java | 14 +++- store/conf/attrs/zimbra-attrs.xml | 5 +- .../zimbra/cs/account/MockProvisioning.java | 5 ++ .../com/zimbra/cs/account/Provisioning.java | 3 + .../cs/account/ldap/LdapProvisioning.java | 40 ++++++++++ .../cs/account/soap/SoapProvisioning.java | 4 + .../cs/mailbox/ContactAutoComplete.java | 77 ++++++++++++------- 7 files changed, 116 insertions(+), 32 deletions(-) diff --git a/common/src/java/com/zimbra/common/account/ZAttrProvisioning.java b/common/src/java/com/zimbra/common/account/ZAttrProvisioning.java index ae40ee826f7..313b05cc879 100644 --- a/common/src/java/com/zimbra/common/account/ZAttrProvisioning.java +++ b/common/src/java/com/zimbra/common/account/ZAttrProvisioning.java @@ -7508,9 +7508,9 @@ public static TwoFactorAuthSecretEncoding fromString(String s) throws ServiceExc public static final String A_zimbraFeatureSearchHistoryEnabled = "zimbraFeatureSearchHistoryEnabled"; /** - * Feature to enable/disable the mobile sync for shared folders. Default - * value is TRUE. The option to sync the shared folders to the Mobile - * will be enabled for the users in the webclient. The option will only + * Feature to enable/disable the mobile sync for shared folders. Default + * value is TRUE. The option to sync the shared folders to the Mobile + * will be enabled for the users in the webclient. The option will only * be enabled for shared folders having Admin or Manager permission * * @since ZCS 10.1.0 @@ -8586,6 +8586,14 @@ public static TwoFactorAuthSecretEncoding fromString(String s) throws ServiceExc @ZAttr(id=4116) public static final String A_zimbraHideAliasesInGal = "zimbraHideAliasesInGal"; + /** + * Option to hide/show alias in GAL + * + * @since ZCS 10.1.1 + */ + @ZAttr(id=4135) + public static final String A_zimbraHideAliasInGal = "zimbraHideAliasInGal"; + /** * hide entry in Global Address List */ diff --git a/store/conf/attrs/zimbra-attrs.xml b/store/conf/attrs/zimbra-attrs.xml index 6378766c6b6..0b926cf65ba 100644 --- a/store/conf/attrs/zimbra-attrs.xml +++ b/store/conf/attrs/zimbra-attrs.xml @@ -10556,7 +10556,8 @@ TODO: delete them permanently from here Feature to enable/disable the mobile sync for shared folders. Default value is TRUE. The option to sync the shared folders to the Mobile will be enabled for the users in the webclient. The option will only be enabled for shared folders having Admin or Manager permission - - Option to hide/show alias in GAL + + Option to hide/show alias in GAL + diff --git a/store/src/java-test/com/zimbra/cs/account/MockProvisioning.java b/store/src/java-test/com/zimbra/cs/account/MockProvisioning.java index bbf1bcaba03..750308fef6b 100644 --- a/store/src/java-test/com/zimbra/cs/account/MockProvisioning.java +++ b/store/src/java-test/com/zimbra/cs/account/MockProvisioning.java @@ -970,4 +970,9 @@ public void resetPassword(Account acct, String newPassword, boolean dryRun) thro public String sendMdmEmail(String status, String timeInterval) throws ServiceException { return null; } + + @Override + public void checkIsAliasToBeHidden(NamedEntry entry, List email) throws ServiceException { + //Not yet implemenmted + } } diff --git a/store/src/java/com/zimbra/cs/account/Provisioning.java b/store/src/java/com/zimbra/cs/account/Provisioning.java index 2055484c37c..b262bdef4eb 100644 --- a/store/src/java/com/zimbra/cs/account/Provisioning.java +++ b/store/src/java/com/zimbra/cs/account/Provisioning.java @@ -2795,4 +2795,7 @@ public String createAddressList(Domain domain, String name, String desc, Map email) throws ServiceException; + } diff --git a/store/src/java/com/zimbra/cs/account/ldap/LdapProvisioning.java b/store/src/java/com/zimbra/cs/account/ldap/LdapProvisioning.java index 81e3909e8ee..cb20ce6c0a9 100644 --- a/store/src/java/com/zimbra/cs/account/ldap/LdapProvisioning.java +++ b/store/src/java/com/zimbra/cs/account/ldap/LdapProvisioning.java @@ -11726,4 +11726,44 @@ public void modifyAddressList(AddressList addressList, String name, Map aliases) throws ServiceException { + ZimbraLog.mailbox.debug("checkIsAliasToBeHidden %s ", aliases); + + LdapUsage ldapUsage = LdapUsage.ADD_ALIAS_ACCOUNT; + + ZLdapContext zlc = LdapClient.getContext(LdapServerType.MASTER, ldapUsage); + + for (String alias : new ArrayList(aliases)) { + if (null != alias) { + String parts[] = alias.split("@"); + String aliasName = parts[0]; + String aliasDomain = parts[1]; + + ZimbraLog.mailbox.debug("checkIsAliasToBeHidden2 %s ", alias); + + String targetDomainName = ((Account) entry).getDomainName(); + + String aliasDn = mDIT.aliasDN(((LdapEntry) entry).getDN(), targetDomainName, aliasName, aliasDomain); + + ZAttributes attrs = helper.getAttributes(zlc, aliasDn); + + Alias aliasEntryLocal = makeAlias(aliasDn, attrs); + + NamedEntry targetEntry = searchAliasTarget(aliasEntryLocal, false); + + boolean isSame = (entry.getId().equals(targetEntry.getId())); + + if ("TRUE".equalsIgnoreCase(aliasEntryLocal.getAttr(Provisioning.A_zimbraHideAliasInGal))) { + aliases.remove(alias); + } + ZimbraLog.mailbox.info("alias attribute for %s is %s and isSame %s ", alias, + aliasEntryLocal.getAttr(Provisioning.A_zimbraHideAliasInGal), isSame); + } + } + + } } + diff --git a/store/src/java/com/zimbra/cs/account/soap/SoapProvisioning.java b/store/src/java/com/zimbra/cs/account/soap/SoapProvisioning.java index be7eec340bd..a1bc882c625 100644 --- a/store/src/java/com/zimbra/cs/account/soap/SoapProvisioning.java +++ b/store/src/java/com/zimbra/cs/account/soap/SoapProvisioning.java @@ -3312,4 +3312,8 @@ public String sendMdmEmail(String status, String timeInterval) throws ServiceExc return L10nUtil.getMessage(L10nUtil.MsgKey.sendMDMNotificationEmailSuccess); } + + @Override public void checkIsAliasToBeHidden(NamedEntry entry, List email) throws ServiceException { + + } } \ No newline at end of file diff --git a/store/src/java/com/zimbra/cs/mailbox/ContactAutoComplete.java b/store/src/java/com/zimbra/cs/mailbox/ContactAutoComplete.java index 9de314d3d3f..bfc063d6f70 100644 --- a/store/src/java/com/zimbra/cs/mailbox/ContactAutoComplete.java +++ b/store/src/java/com/zimbra/cs/mailbox/ContactAutoComplete.java @@ -46,6 +46,7 @@ import com.zimbra.cs.account.Account; import com.zimbra.cs.account.GalContact; import com.zimbra.cs.account.Provisioning; +import com.zimbra.cs.account.ldap.LdapProvisioning; import com.zimbra.cs.gal.GalGroup; import com.zimbra.cs.gal.GalGroupInfoProvider; import com.zimbra.cs.gal.GalSearchControl; @@ -397,17 +398,17 @@ public void setSearchType(GalSearchType type) { } public AutoCompleteResult resolveEmailAddr(String str) throws ServiceException { - AutoCompleteResult result = new AutoCompleteResult(1); - result.rankings = new ContactRankings(getRequestedAcctId()); - for (String addr : mRequestedAcct.getAllAddrsSet()) { - if (addr.equals(str)) { - ContactEntry entry = new ContactEntry(); - entry.mEmail = addr; - result.addEntry(entry); - break; - } - } - return result; + AutoCompleteResult result = new AutoCompleteResult(1); + result.rankings = new ContactRankings(getRequestedAcctId()); + for (String addr : mRequestedAcct.getAllAddrsSet()) { + if (addr.equals(str)) { + ContactEntry entry = new ContactEntry(); + entry.mEmail = addr; + result.addEntry(entry); + break; + } + } + return result; } public AutoCompleteResult query(String str, Collection folders, int limit) throws ServiceException { ZimbraLog.gal.debug("AutoComplete querying: %s", str); @@ -470,7 +471,7 @@ private void resolveGroupInfo(ContactEntry entry, String email) { } private void queryGal(String str, AutoCompleteResult result) { - ZimbraLog.gal.debug("querying gal"); + ZimbraLog.gal.info("querying gal"); GalSearchParams params = new GalSearchParams(mRequestedAcct, mZsc); params.setQuery(str); params.setType(mSearchType); @@ -504,7 +505,7 @@ public AutoCompleteCallback(String str, AutoCompleteResult result, GalSearchPara this.str = str; } - public void handleContactAttrs(Map attrs) { + public void handleContactAttrs(Map attrs) throws ServiceException { addMatchedContacts(str, attrs, FOLDER_ID_GAL, null, result); } @@ -600,8 +601,7 @@ private boolean matchesName(List tokens, Map a String fullName = getFieldAsString(attrs, ContactConstants.A_fullName); if (!Strings.isNullOrEmpty(fullName)) { for (String fullNameToken : TOKEN_SPLITTER.split(fullName)) { - if (!Strings.isNullOrEmpty(fullNameToken) && - fullNameToken.toLowerCase().startsWith(token)) { + if (!Strings.isNullOrEmpty(fullNameToken) && fullNameToken.toLowerCase().startsWith(token)) { return true; } } @@ -634,8 +634,8 @@ private boolean matchesName(List tokens, Map a if (pattern.matcher(Joiner.on(' ').skipNulls().join(lastName, firstName, middleName)).matches()) { return true; } - - + + String fullName = getFieldAsString(attrs, ContactConstants.A_fullName); if (!Strings.isNullOrEmpty(fullName) && pattern.matcher(fullName).matches()) { return true; @@ -669,7 +669,7 @@ private Pattern toPattern(List tokens) { } public void addMatchedContacts(String query, Map attrs, int folderId, ItemId id, - AutoCompleteResult result) { + AutoCompleteResult result) throws ServiceException { if (!result.canBeCached) { return; } @@ -680,10 +680,10 @@ public void addMatchedContacts(String query, Map attrs } if (!Contact.isGroup(attrs) || folderId == FOLDER_ID_GAL) { - // + // // either a GAL entry or a non-contact-group contact entry // - + boolean nameMatches = matchesName(tokens, attrs); // matching algorithm is slightly different between matching @@ -704,25 +704,47 @@ public void addMatchedContacts(String query, Map attrs String company = getFieldAsString(attrs, ContactConstants.A_company); String fileas = getFieldAsString(attrs, ContactConstants.A_fileAs); String displayName = fullName; + Account account = Provisioning.getInstance().get(Key.AccountBy.name, fullName); + if (Strings.isNullOrEmpty(displayName)) { displayName = Joiner.on(' ').skipNulls().join(first, middle, last); } - for (String emailKey : mEmailKeys) { - String email = getFieldAsString(attrs, emailKey); + List allowedEmailsList = new ArrayList<>(); + for(String emailKey: mEmailKeys) { + if (!emailKey.equals("email")) { + if (account.isHideAliasesInGal()) { + //condition for allowing primary email address only + break; + } + } + allowedEmailsList.add(getFieldAsString(attrs, emailKey)); + } + ZimbraLog.mailbox.info("allowed list 1 is %s", allowedEmailsList); + + try { + Provisioning.getInstance().checkIsAliasToBeHidden(account, allowedEmailsList.subList( 1, allowedEmailsList.size())); + } catch (ServiceException e) { + throw new RuntimeException(e); + } + + ZimbraLog.mailbox.info("allowed list 2 is %s", allowedEmailsList); + + + for (String email : allowedEmailsList) { if (email != null && (nameMatches || matchesEmail(tokens, email))) { ContactEntry entry = new ContactEntry(); entry.mEmail = email; entry.setName(displayName); entry.mId = id; entry.mFolderId = folderId; - entry.mFirstName = first; + entry.mFirstName = first; entry.mMiddleName = middle; entry.mLastName = last; entry.mFullName = fullName; entry.mNickname = nick; - entry.mCompany = company; - entry.mFileAs = fileas; + entry.mCompany = company; + entry.mFileAs = fileas; if (Contact.isGroup(attrs)) { entry.setIsGalGroup(email, attrs, mAuthedAcct, mNeedCanExpand); } else if (entry.mFolderId != FOLDER_ID_GAL) { @@ -734,10 +756,11 @@ public void addMatchedContacts(String query, Map attrs if (returnFullContactData) { entry.mAttrs = attrs; } + addEntry(entry, result); ZimbraLog.gal.debug("adding %s", entry.getEmail()); /* - Previously stopped at first matching email address for GAL contact. + Previously stopped at first matching email address for GAL contact. See ZBUG-1838. */ } @@ -931,4 +954,4 @@ private void addExistingContactsFromRankingTable(String str, String folderBasicQ queryFolders(str, queryRanking, mountpoints, limit, result); } } -} +} \ No newline at end of file