package com.constellio.model.services.users; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; import org.apache.commons.collections.IteratorUtils; import org.jdom2.Document; import org.jdom2.Element; import org.jdom2.filter.Filter; import org.jdom2.filter.Filters; import org.jdom2.util.IteratorIterable; import org.joda.time.LocalDateTime; import com.constellio.data.utils.Factory; import com.constellio.model.entities.security.global.UserCredential; import com.constellio.model.services.encrypt.EncryptionServices; public class UserCredentialsWriter { private static final String GLOBAL_GROUP = "globalGroup"; private static final String GLOBAL_GROUPS = "globalGroups"; private static final String COLLECTIONS = "collections"; private static final String COLLECTION = "collection"; private static final String USERNAME = "username"; private static final String EMAIL = "email"; private static final String SERVICE_KEY = "serviceKey"; private static final String TOKENS = "tokens"; private static final String TOKEN = "token"; private static final String TOKEN_ID = "tokenId"; private static final String TOKEN_END_DATE = "tokenEndDate"; private static final String SYSTEM_ADMIN = "systemAdmin"; private static final String LAST_NAME = "lastName"; private static final String FIRST_NAME = "firstName"; private static final String USER_CREDENTIAL = "userCredential"; private static final String USERS_CREDENTIALS = "usersCredentials"; public static final String STATUS = "status"; public static final String DOMAIN = "domain"; private static final String MS_EXCH_DELEGATE_LIST_BL = "msExchDelegateListBL"; private static final String MS_EXCH_DELEGATE_BL = "msExchDelegateBL"; static final String DN = "ldapDN"; Document document; Factory<EncryptionServices> encryptionServicesFactory; public UserCredentialsWriter(Document document, Factory<EncryptionServices> encryptionServicesFactory) { this.document = document; this.encryptionServicesFactory = encryptionServicesFactory; } public void createEmptyUserCredentials() { Element usersCredentials = new Element(USERS_CREDENTIALS); document.setRootElement(usersCredentials); } public void addUpdate(UserCredential userCredential) { Element root = document.getRootElement(); removeIfExists(userCredential, root); add(userCredential); } public void removeCollection(String collection) { List<Element> elementsToRemove = getCollectionsElementsToRemove(collection); for (Element element : elementsToRemove) { element.detach(); } } public void removeToken(String token) { String encryptedToken = encryptionServicesFactory.get().encrypt(token); List<Element> elementsToRemove = getTokenElementsToRemove(encryptedToken); for (Element element : elementsToRemove) { element.detach(); } } public void removeUserFromCollection(UserCredential userCredential, String collection) { List<Element> elementsToRemove = getCollectionElementToRemoveFromUser(userCredential, collection); for (Element element : elementsToRemove) { element.detach(); } } public void removeGroup(String groupCode) { List<Element> elementsToRemove = getGroupElementToRemove(groupCode); for (Element element : elementsToRemove) { element.detach(); } } // private void removeIfExists(UserCredential userCredential, Element root) { Element elementToRemove = null; for (Element element : root.getChildren()) { if (element.getAttributeValue(USERNAME).equals(userCredential.getUsername())) { elementToRemove = element; break; } } if (elementToRemove != null) { elementToRemove.detach(); } } private List<Element> getTokenElementsToRemove(String token) { List<Element> elementsToRemove = new ArrayList<>(); Filter<Element> tokenFilter = Filters.element(TOKEN); IteratorIterable<Element> tokenElements = document.getRootElement().getDescendants(tokenFilter); List<Element> tokenElementsList = IteratorUtils.toList(tokenElements); for (Element tokenElement : tokenElementsList) { if (tokenElement.getChildText(TOKEN_ID).equals(token)) { elementsToRemove.add(tokenElement); } } return elementsToRemove; } private List<Element> getCollectionsElementsToRemove(String collection) { List<Element> elementsToRemove = new ArrayList<>(); Filter<Element> collectionFilter = Filters.element(COLLECTION); IteratorIterable<Element> collectionElements = document.getRootElement().getDescendants(collectionFilter); List<Element> collectionElementsList = IteratorUtils.toList(collectionElements); for (Element collectionElement : collectionElementsList) { if (collectionElement.getText().equals(collection)) { elementsToRemove.add(collectionElement); } } return elementsToRemove; } private List<Element> getCollectionElementToRemoveFromUser(UserCredential userCredential, String collection) { List<Element> elementsToRemove = new ArrayList<>(); Filter<Element> userCredentialFilter = Filters.element(USER_CREDENTIAL); IteratorIterable<Element> userCredentialElements = document.getRootElement().getDescendants(userCredentialFilter); List<Element> userCredentialElementsList = IteratorUtils.toList(userCredentialElements); for (Element userCredentialElement : userCredentialElementsList) { if (userCredentialElement.getAttributeValue(USERNAME).equals(userCredential.getUsername())) { for (Element collectionElement : userCredentialElement.getChild(COLLECTIONS).getChildren()) { if (collectionElement.getText().equals(collection)) { elementsToRemove.add(collectionElement); } } break; } } return elementsToRemove; } private List<Element> getGroupElementToRemove(String groupCode) { List<Element> elementsToRemove = new ArrayList<>(); Filter<Element> globalGroupFilter = Filters.element(GLOBAL_GROUP); IteratorIterable<Element> globalGroupElements = document.getRootElement().getDescendants(globalGroupFilter); List<Element> globalGroupElementsList = IteratorUtils.toList(globalGroupElements); for (Element globalGroupElement : globalGroupElementsList) { if (globalGroupElement.getText().equals(groupCode)) { elementsToRemove.add(globalGroupElement); } } return elementsToRemove; } private void add(UserCredential userCredential) { Element globalGroupsElement = new Element(GLOBAL_GROUPS); for (String group : userCredential.getGlobalGroups()) { Element globalGroupElement = new Element(GLOBAL_GROUP).setText(group); globalGroupsElement.addContent(globalGroupElement); } Element collectionsElement = new Element(COLLECTIONS); for (String collection : userCredential.getCollections()) { Element collectionElement = new Element(COLLECTION).setText(collection); collectionsElement.addContent(collectionElement); } Element tokensElement = new Element(TOKENS); if (userCredential.getAccessTokens() != null) { for (Map.Entry<String, LocalDateTime> token : userCredential.getAccessTokens().entrySet()) { String encryptedKey = encryptionServicesFactory.get().encrypt(token.getKey()); Element tokenElement = new Element(TOKEN); Element tokenIdElement = new Element(TOKEN_ID).setText(encryptedKey); Element tokenEndDateElement = new Element(TOKEN_END_DATE).setText(token.getValue().toString()); tokenElement.addContent(tokenIdElement); tokenElement.addContent(tokenEndDateElement); tokensElement.addContent(tokenElement); } } Element firstNameElement = new Element(FIRST_NAME).setText(userCredential.getFirstName()); Element lastNameElement = new Element(LAST_NAME).setText(userCredential.getLastName()); Element emailElement = new Element(EMAIL).setText(userCredential.getEmail()); String serviceKey = userCredential.getServiceKey() == null ? "null" : userCredential.getServiceKey(); Element serviceKeyElement = new Element(SERVICE_KEY).setText(serviceKey); Element statusElement = new Element(STATUS).setText(userCredential.getStatus().getCode()); Element domainElement = new Element(DOMAIN).setText(userCredential.getDomain()); Element msExchDelegateListBLElement = new Element(MS_EXCH_DELEGATE_LIST_BL); if (userCredential.getMsExchDelegateListBL() != null) { for (String msExchDelegateBL : userCredential.getMsExchDelegateListBL()) { Element msExchDelegateBLElement = new Element(MS_EXCH_DELEGATE_BL).setText(msExchDelegateBL); msExchDelegateListBLElement.addContent(msExchDelegateBLElement); } } String dn = userCredential.getDn() == null ? "null" : userCredential.getDn(); Element dnElement = new Element(DN).setText(dn); Element systemAdminPermissions = new Element(SYSTEM_ADMIN).setText(userCredential.isSystemAdmin() ? "true" : "false"); Element userCredentialElement = new Element(USER_CREDENTIAL).setAttribute(USERNAME, userCredential.getUsername()); userCredentialElement.addContent(firstNameElement); userCredentialElement.addContent(lastNameElement); userCredentialElement.addContent(emailElement); userCredentialElement.addContent(serviceKeyElement); userCredentialElement.addContent(tokensElement); userCredentialElement.addContent(systemAdminPermissions); userCredentialElement.addContent(globalGroupsElement); userCredentialElement.addContent(collectionsElement); userCredentialElement.addContent(statusElement); userCredentialElement.addContent(domainElement); userCredentialElement.addContent(msExchDelegateListBLElement); userCredentialElement.addContent(dnElement); document.getRootElement().addContent(userCredentialElement); } public void rewrite(Collection<UserCredential> userCredentials) { document.getRootElement().setAttribute("apiVersion", "2"); for (UserCredential userCredential : userCredentials) { addUpdate(userCredential); } } }