001/*
002 * (C) Copyright 2017 Nuxeo (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Gabriel Barata <gbarata@nuxeo.com>
018 */
019package org.nuxeo.ecm.platform.oauth2.providers;
020
021import org.nuxeo.ecm.core.api.DocumentModel;
022import org.nuxeo.ecm.core.api.NuxeoException;
023import org.nuxeo.ecm.core.api.NuxeoPrincipal;
024import org.nuxeo.ecm.core.io.marshallers.json.ExtensibleEntityJsonWriter;
025import org.nuxeo.ecm.core.io.registry.reflect.Setup;
026import org.nuxeo.ecm.platform.oauth2.tokens.NuxeoOAuth2Token;
027import org.nuxeo.ecm.platform.usermanager.UserManager;
028import org.nuxeo.runtime.api.Framework;
029
030import com.fasterxml.jackson.core.JsonGenerator;
031
032import java.io.IOException;
033import java.io.Serializable;
034import java.util.HashMap;
035import java.util.List;
036import java.util.Map;
037
038import static org.nuxeo.ecm.core.io.registry.reflect.Instantiations.SINGLETON;
039import static org.nuxeo.ecm.core.io.registry.reflect.Priorities.REFERENCE;
040
041/**
042 * @since 9.2
043 */
044@Setup(mode = SINGLETON, priority = REFERENCE)
045public class NuxeoOAuth2ServiceProviderWriter extends ExtensibleEntityJsonWriter<NuxeoOAuth2ServiceProvider> {
046
047    public static final String ENTITY_TYPE = "nuxeoOAuth2ServiceProvider";
048
049    public NuxeoOAuth2ServiceProviderWriter() {
050        super(ENTITY_TYPE, NuxeoOAuth2ServiceProvider.class);
051    }
052
053    @Override
054    protected void writeEntityBody(NuxeoOAuth2ServiceProvider provider, JsonGenerator jg) throws IOException {
055        UserManager userManager = Framework.getService(UserManager.class);
056        String principalName = ctx.getSession(null).getSession().getPrincipal().getName();
057        NuxeoPrincipal principal = userManager.getPrincipal(principalName);
058        jg.writeStringField("serviceName", provider.getServiceName());
059        jg.writeStringField("description", provider.getDescription());
060        jg.writeStringField("clientId", provider.getClientId());
061        jg.writeStringField("clientSecret", principal.isAdministrator() ? provider.getClientSecret() : null);
062        jg.writeStringField("authorizationServerURL", provider.getAuthorizationServerURL());
063        jg.writeStringField("tokenServerURL", provider.getTokenServerURL());
064        jg.writeStringField("userAuthorizationURL", provider.getUserAuthorizationURL());
065        jg.writeArrayFieldStart("scopes");
066        for (String scope : provider.getScopes()) {
067            jg.writeString(scope);
068        }
069        jg.writeEndArray();
070        jg.writeBooleanField("isEnabled", provider.isEnabled());
071
072        jg.writeBooleanField("isAvailable", provider.isProviderAvailable());
073        String authorizationURL = null;
074        if (provider.getClientId() != null) {
075            try {
076                authorizationURL = provider.getAuthorizationUrl(ctx.getBaseUrl());
077            } catch (IllegalArgumentException e) {
078                authorizationURL = null;
079            }
080        }
081        jg.writeStringField("authorizationURL", authorizationURL);
082        NuxeoOAuth2Token token = getToken(provider, principalName);
083        boolean isAuthorized = (token != null);
084        jg.writeBooleanField("isAuthorized", isAuthorized);
085        jg.writeStringField("userId", isAuthorized ? token.getServiceLogin() : null);
086    }
087
088    private NuxeoOAuth2Token getToken(NuxeoOAuth2ServiceProvider provider, String nxuser) {
089        Map<String, Serializable> filter = new HashMap<>();
090        filter.put("serviceName", provider.getId());
091        filter.put(NuxeoOAuth2Token.KEY_NUXEO_LOGIN, nxuser);
092        return Framework.doPrivileged(() -> {
093            List<DocumentModel> entries = provider.getCredentialDataStore().query(filter);
094            if (entries != null) {
095                if (entries.size() > 1) {
096                    throw new NuxeoException("Found multiple " + provider.getId() + " accounts for " + nxuser);
097                } else if (entries.size() == 1) {
098                    return new NuxeoOAuth2Token(entries.get(0));
099                }
100            }
101            return null;
102        });
103    }
104}