📄 ldapvcardprovider.java
字号:
if (currentElement != null) { vcard.remove(currentElement); } vcard.add(photoElement); return vcard; } /** * Loads the avatar element from the user's DB stored vcard. * * @param username User whose vcard/avatar element we are loading. * @return Loaded avatar element or null if not found. */ private Element loadAvatarFromDatabase(String username) { Element vcardElement = defaultProvider.loadVCard(username); Element avatarElement = null; if (vcardElement != null && vcardElement.element("PHOTO") != null) { avatarElement = vcardElement.element("PHOTO").createCopy(); } return avatarElement; } /** * Handles when a user creates a new vcard. * * @param username User that created a new vcard. * @param vCardElement vCard element containing the new vcard. * @throws UnsupportedOperationException If an invalid field is changed or we are in readonly mode. */ public Element createVCard(String username, Element vCardElement) throws UnsupportedOperationException, AlreadyExistsException { throw new UnsupportedOperationException("LdapVCardProvider: VCard changes not allowed."); } /** * Handles when a user updates their vcard. * * @param username User that updated their vcard. * @param vCardElement vCard element containing the new vcard. * @throws UnsupportedOperationException If an invalid field is changed or we are in readonly mode. */ public Element updateVCard(String username, Element vCardElement) throws UnsupportedOperationException { if (dbStorageEnabled && defaultProvider != null) { if (isValidVCardChange(username, vCardElement)) { Element mergedVCard = getMergedVCard(username, vCardElement); try { defaultProvider.updateVCard(username, mergedVCard); } catch (NotFoundException e) { try { defaultProvider.createVCard(username, mergedVCard); } catch (AlreadyExistsException e1) { // Ignore } } return mergedVCard; } else { throw new UnsupportedOperationException("LdapVCardProvider: Invalid vcard changes."); } } else { throw new UnsupportedOperationException("LdapVCardProvider: VCard changes not allowed."); } } /** * Handles when a user deletes their vcard. * * @param username User that deketed their vcard. * @throws UnsupportedOperationException If an invalid field is changed or we are in readonly mode. */ public void deleteVCard(String username) throws UnsupportedOperationException { throw new UnsupportedOperationException("LdapVCardProvider: Attempted to delete vcard in read-only mode."); } /** * Returns true or false if the change to the existing vcard is valid (only to PHOTO element) * * @param username User who's LDAP-based vcard we will compare with. * @param newvCard New vCard Element we will compare against. * @return True or false if the changes made were valid (only to PHOTO element) */ private Boolean isValidVCardChange(String username, Element newvCard) { if (newvCard == null) { // Well if there's nothing to change, of course it's valid. Log.debug("LdapVCardProvider: No new vcard provided (no changes), accepting."); return true; } // Un-escape username. username = JID.unescapeNode(username); Map<String, String> map = getLdapAttributes(username); // Retrieve LDAP created vcard for comparison Element ldapvCard = new VCard(template).getVCard(map); if (ldapvCard == null) { // This person has no vcard at all, may not change it! Log.debug("LdapVCardProvider: User has no LDAP vcard, nothing they can change, rejecting."); return false; } // If the LDAP vcard has a non-empty PHOTO element set, then there is literally no way this will be accepted. Element ldapPhotoElem = ldapvCard.element("PHOTO"); if (ldapPhotoElem != null) { Element ldapBinvalElem = ldapPhotoElem.element("BINVAL"); if (ldapBinvalElem != null && !ldapBinvalElem.getTextTrim().matches("\\s*")) { // LDAP is providing a valid PHOTO element, byebye! Log.debug("LdapVCardProvider: LDAP has a PHOTO element set, no way to override, rejecting."); return false; } } // Retrieve database vcard, if it exists Element dbvCard = defaultProvider.loadVCard(username); if (dbvCard != null) { Element dbPhotoElem = dbvCard.element("PHOTO"); if (dbPhotoElem == null) { // DB has no photo, lets accept what we got. Log.debug("LdapVCardProvider: Database has no PHOTO element, accepting update."); return true; } else { Element newPhotoElem = newvCard.element("PHOTO"); if (newPhotoElem == null) { Log.debug("LdapVCardProvider: Photo element was removed, accepting update."); return true; } // Note: NodeComparator never seems to consider these equal, even if they are? if (!dbPhotoElem.asXML().equals(newPhotoElem.asXML())) { // Photo element was changed. Ignore all other changes and accept this. Log.debug("LdapVCardProvider: PHOTO element changed, accepting update."); return true; } } } else { // No vcard exists in database Log.debug("LdapVCardProvider: Database has no vCard stored, accepting update."); return true; } // Ok, either something bad changed or nothing changed. Either way, user either: // 1. should not have tried to change something 'readonly' // 2. shouldn't have bothered submitting no changes // So we'll consider this a bad return. Log.debug("LdapVCardProvider: PHOTO element didn't change, no reason to accept this, rejecting."); return false; } public boolean isReadOnly() { return !dbStorageEnabled; } public void propertySet(String property, Map params) { if ("ldap.override.avatar".equals(property)) { dbStorageEnabled = Boolean.parseBoolean((String)params.get("value")); } } public void propertyDeleted(String property, Map params) { if ("ldap.override.avatar".equals(property)) { dbStorageEnabled = false; } } public void xmlPropertySet(String property, Map params) { if ("ldap.vcard-mapping".equals(property)) { initTemplate(); // Reset cache of vCards VCardManager.getInstance().reset(); } } public void xmlPropertyDeleted(String property, Map params) { //Ignore } /** * Class to hold a <code>Document</code> representation of a vcard mapping * and unique attribute placeholders. Used by <code>VCard</code> to apply * a <code>Map</code> of ldap attributes to ldap values via * <code>MessageFormat</code> * * @author rkelly */ private static class VCardTemplate { private Document document; private String[] attributes; public VCardTemplate(Document document) { Set<String> set = new HashSet<String>(); this.document = document; treeWalk(this.document.getRootElement(), set); attributes = set.toArray(new String[set.size()]); } public String[] getAttributes() { return attributes; } public Document getDocument() { return document; } private void treeWalk(Element element, Set<String> set) { for (int i = 0, size = element.nodeCount(); i < size; i++) { Node node = element.node(i); if (node instanceof Element) { Element emement = (Element) node; StringTokenizer st = new StringTokenizer(emement.getTextTrim(), ", //{}"); while (st.hasMoreTokens()) { // Remove enclosing {} String string = st.nextToken().replaceAll("(\\{)([\\d\\D&&[^}]]+)(})", "$2"); Log.debug("VCardTemplate: found attribute " + string); set.add(string); } treeWalk(emement, set); } } } } /** * vCard class that converts vcard data using a template. */ private static class VCard { private VCardTemplate template; public VCard(VCardTemplate template) { this.template = template; } public Element getVCard(Map<String, String> map) { Document document = (Document) template.getDocument().clone(); Element element = document.getRootElement(); return treeWalk(element, map); } private Element treeWalk(Element element, Map<String, String> map) { for (int i = 0, size = element.nodeCount(); i < size; i++) { Node node = element.node(i); if (node instanceof Element) { Element emement = (Element) node; String elementText = emement.getTextTrim(); if (elementText != null && !"".equals(elementText)) { String format = emement.getStringValue(); StringTokenizer st = new StringTokenizer(elementText, ", //{}"); while (st.hasMoreTokens()) { // Remove enclosing {} String field = st.nextToken(); String attrib = field.replaceAll("(\\{)(" + field + ")(})", "$2"); String value = map.get(attrib); format = format.replaceFirst("(\\{)(" + field + ")(})", value); } emement.setText(format); } treeWalk(emement, map); } } return element; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -