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.codehaus.jackson.JsonGenerator;
022import org.nuxeo.ecm.core.api.DocumentModel;
023import org.nuxeo.ecm.core.api.NuxeoException;
024import org.nuxeo.ecm.core.api.NuxeoPrincipal;
025import org.nuxeo.ecm.core.io.marshallers.json.ExtensibleEntityJsonWriter;
026import org.nuxeo.ecm.core.io.registry.reflect.Setup;
027import org.nuxeo.ecm.platform.oauth2.tokens.NuxeoOAuth2Token;
028import org.nuxeo.ecm.platform.usermanager.UserManager;
029import org.nuxeo.runtime.api.Framework;
030
031import java.io.IOException;
032import java.io.Serializable;
033import java.util.HashMap;
034import java.util.List;
035import java.util.Map;
036
037import static org.nuxeo.ecm.core.io.registry.reflect.Instantiations.SINGLETON;
038import static org.nuxeo.ecm.core.io.registry.reflect.Priorities.REFERENCE;
039
040/**
041 * @since 9.2
042 */
043@Setup(mode = SINGLETON, priority = REFERENCE)
044public class NuxeoOAuth2ServiceProviderWriter extends ExtensibleEntityJsonWriter<NuxeoOAuth2ServiceProvider> {
045
046    public static final String ENTITY_TYPE = "nuxeoOAuth2ServiceProvider";
047
048    public NuxeoOAuth2ServiceProviderWriter() {
049        super(ENTITY_TYPE, NuxeoOAuth2ServiceProvider.class);
050    }
051
052    @Override
053    protected void writeEntityBody(NuxeoOAuth2ServiceProvider provider, JsonGenerator jg) throws IOException {
054        UserManager userManager = Framework.getService(UserManager.class);
055        String principalName = ctx.getSession(null).getSession().getPrincipal().getName();
056        NuxeoPrincipal principal = userManager.getPrincipal(principalName);
057        jg.writeStringField("serviceName", provider.getServiceName());
058        jg.writeStringField("description", provider.getDescription());
059        jg.writeStringField("clientId", provider.getClientId());
060        jg.writeStringField("clientSecret", principal.isAdministrator() ? provider.getClientSecret() : null);
061        jg.writeStringField("authorizationServerURL", provider.getAuthorizationServerURL());
062        jg.writeStringField("tokenServerURL", provider.getTokenServerURL());
063        jg.writeStringField("userAuthorizationURL", provider.getUserAuthorizationURL());
064        jg.writeArrayFieldStart("scopes");
065        for (String scope : provider.getScopes()) {
066            jg.writeString(scope);
067        }
068        jg.writeEndArray();
069        jg.writeBooleanField("isEnabled", provider.isEnabled());
070
071        jg.writeBooleanField("isAvailable", provider.isProviderAvailable());
072        String authorizationURL = null;
073        if (provider.getClientId() != null) {
074            try {
075                authorizationURL = provider.getAuthorizationUrl(ctx.getBaseUrl());
076            } catch (IllegalArgumentException e) {
077                authorizationURL = null;
078            }
079        }
080        jg.writeStringField("authorizationURL", authorizationURL);
081        NuxeoOAuth2Token token = getToken(provider, principalName);
082        boolean isAuthorized = (token != null);
083        jg.writeBooleanField("isAuthorized", isAuthorized);
084        jg.writeStringField("userId", isAuthorized ? token.getServiceLogin() : null);
085    }
086
087    private NuxeoOAuth2Token getToken(NuxeoOAuth2ServiceProvider provider, String nxuser) {
088        Map<String, Serializable> filter = new HashMap<>();
089        filter.put("serviceName", provider.getId());
090        filter.put(NuxeoOAuth2Token.KEY_NUXEO_LOGIN, nxuser);
091        return Framework.doPrivileged(() -> {
092            List<DocumentModel> entries = provider.getCredentialDataStore().query(filter);
093            if (entries != null) {
094                if (entries.size() > 1) {
095                    throw new NuxeoException("Found multiple " + provider.getId() + " accounts for " + nxuser);
096                } else if (entries.size() == 1) {
097                    return new NuxeoOAuth2Token(entries.get(0));
098                }
099            }
100            return null;
101        });
102    }
103}