001package org.nuxeo.ecm.platform.oauth2.clients;
002
003import java.io.Serializable;
004import java.util.HashMap;
005import java.util.List;
006import java.util.Map;
007
008import org.apache.commons.logging.Log;
009import org.apache.commons.logging.LogFactory;
010import org.nuxeo.ecm.core.api.DocumentModel;
011import org.nuxeo.ecm.core.api.DocumentModelList;
012import org.nuxeo.ecm.directory.DirectoryException;
013import org.nuxeo.ecm.directory.Session;
014import org.nuxeo.ecm.directory.api.DirectoryService;
015import org.nuxeo.runtime.api.Framework;
016import org.nuxeo.runtime.model.ComponentInstance;
017import org.nuxeo.runtime.model.DefaultComponent;
018
019/**
020 * OAuth2 Client registry component
021 *
022 * @author <a href="mailto:ak@nuxeo.com">Arnaud Kervern</a>
023 * @since 5.9.2
024 */
025public class ClientRegistryImpl extends DefaultComponent implements ClientRegistry {
026
027    private static final Log log = LogFactory.getLog(ClientRegistry.class);
028
029    @Override
030    public void registerContribution(Object contribution, String extensionPoint, ComponentInstance contributor) {
031        switch (extensionPoint) {
032        case "clients":
033            OAuth2Client client = (OAuth2Client) contribution;
034            registerClient(client);
035            break;
036        default:
037            break;
038        }
039    }
040
041    @Override
042    public boolean hasClient(String clientId) {
043        DirectoryService service = getService();
044        try (Session session = service.open(OAUTH2CLIENT_DIRECTORY_NAME)) {
045            Map<String, Serializable> filter = new HashMap<>();
046            filter.put("clientId", clientId);
047            DocumentModelList docs = session.query(filter);
048            if (docs.size() == 0) {
049                return false;
050            }
051
052            DocumentModel entry = docs.get(0);
053            return OAuth2Client.fromDocumentModel(entry).isEnabled();
054        }
055    }
056
057    @Override
058    public boolean isValidClient(String clientId, String clientSecret) {
059        DocumentModel docClient = getClientModel(clientId);
060        if (docClient != null) {
061            OAuth2Client client = OAuth2Client.fromDocumentModel(docClient);
062            return client.isValidWith(clientId, clientSecret);
063        }
064        return false;
065    }
066
067    @Override
068    public boolean registerClient(OAuth2Client client) {
069        DocumentModel doc = getClientModel(client.getId());
070        if (doc != null) {
071            log.info("Trying to register an exisiting client");
072            return false;
073        }
074
075        DirectoryService service = getService();
076        try (Session session = service.open(OAUTH2CLIENT_DIRECTORY_NAME)) {
077            if (session.hasEntry(client.getId())) {
078                log.debug(String.format("ClientId is already registered: %s", client.getId()));
079                return false;
080            }
081            session.createEntry(client.toMap());
082        }
083        return true;
084    }
085
086    @Override
087    public boolean deleteClient(String clientId) {
088        DirectoryService service = getService();
089        try (Session session = service.open(OAUTH2CLIENT_DIRECTORY_NAME)) {
090            session.deleteEntry(clientId);
091            return true;
092        } catch (DirectoryException e) {
093            return false;
094        }
095    }
096
097    @Override
098    public List<DocumentModel> listClients() {
099        DirectoryService service = getService();
100        try (Session session = service.open(OAUTH2CLIENT_DIRECTORY_NAME)) {
101            return session.getEntries();
102        }
103    }
104
105    public OAuth2Client getClient(String clientId) {
106        DocumentModel doc = getClientModel(clientId);
107        return doc != null ? OAuth2Client.fromDocumentModel(doc) : null;
108    }
109
110    protected DocumentModel getClientModel(String clientId) {
111        DirectoryService service = getService();
112        try (Session session = service.open(OAUTH2CLIENT_DIRECTORY_NAME)) {
113            Map<String, Serializable> filter = new HashMap<>();
114            filter.put("clientId", clientId);
115            DocumentModelList docs = session.query(filter);
116            if (docs.size() > 0) {
117                return docs.get(0);
118            }
119        }
120        return null;
121    }
122
123    protected DirectoryService getService() {
124        return Framework.getLocalService(DirectoryService.class);
125    }
126}