001/*
002 * (C) Copyright 2015 Nuxeo SA (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 *     Nicolas Chapurlat <nchapurlat@nuxeo.com>
018 */
019
020package org.nuxeo.ecm.platform.usermanager.io;
021
022import static org.nuxeo.ecm.core.io.marshallers.json.document.DocumentPropertiesJsonReader.DEFAULT_SCHEMA_NAME;
023import static org.nuxeo.ecm.core.io.registry.reflect.Instantiations.SINGLETON;
024import static org.nuxeo.ecm.core.io.registry.reflect.Priorities.REFERENCE;
025import static org.nuxeo.ecm.platform.usermanager.io.NuxeoPrincipalJsonWriter.ENTITY_TYPE;
026
027import java.io.Closeable;
028import java.io.IOException;
029import java.lang.reflect.ParameterizedType;
030import java.util.List;
031
032import javax.inject.Inject;
033
034import org.apache.commons.lang3.reflect.TypeUtils;
035import org.nuxeo.ecm.core.api.DocumentModel;
036import org.nuxeo.ecm.core.api.NuxeoPrincipal;
037import org.nuxeo.ecm.core.api.model.Property;
038import org.nuxeo.ecm.core.io.marshallers.json.EntityJsonReader;
039import org.nuxeo.ecm.core.io.marshallers.json.document.DocumentPropertiesJsonReader;
040import org.nuxeo.ecm.core.io.registry.reflect.Setup;
041import org.nuxeo.ecm.platform.usermanager.NuxeoPrincipalImpl;
042import org.nuxeo.ecm.platform.usermanager.UserManager;
043
044import com.fasterxml.jackson.databind.JsonNode;
045
046/**
047 * Convert Json as {@link NuxeoPrincipal}.
048 * <p>
049 * Format is (any additional json property is ignored):
050 *
051 * <pre>
052 * {
053 *   "entity-type":"user",
054 *   "id":"USERNAME",
055 *   "properties":{   <- depending on the user schema / format is managed by {@link DocumentPropertiesJsonReader}
056 *     "firstName":"FIRSTNAME",
057 *     "lastName":"LASTNAME",
058 *     "username":"USERNAME",
059 *     "email":"user@mail.com",
060 *     "company":"COMPANY",
061 *     "password":"", <- ALWAYS EMPTY
062 *     "groups":[
063 *       "GROUP1 NAME OF THE USER",
064 *       "GROUP2 NAME OF THE USER",
065 *       ...
066 *     ]
067 *   }
068 * }
069 * </pre>
070 *
071 * </p>
072 *
073 * @since 7.2
074 */
075@Setup(mode = SINGLETON, priority = REFERENCE)
076public class NuxeoPrincipalJsonReader extends EntityJsonReader<NuxeoPrincipal> {
077
078    @Inject
079    private UserManager userManager;
080
081    public NuxeoPrincipalJsonReader() {
082        super(ENTITY_TYPE);
083    }
084
085    @Override
086    protected NuxeoPrincipal readEntity(JsonNode jn) throws IOException {
087        String id = getStringField(jn, "id");
088        DocumentModel userDoc = null;
089        if (id != null) {
090            NuxeoPrincipal principal = userManager.getPrincipal(id);
091            if (principal != null) {
092                userDoc = principal.getModel();
093            }
094        }
095        if (userDoc == null) {
096            userDoc = userManager.getBareUserModel();
097        }
098        JsonNode propsNode = jn.get("properties");
099        if (propsNode != null && !propsNode.isNull() && propsNode.isObject()) {
100            ParameterizedType genericType = TypeUtils.parameterize(List.class, Property.class);
101            String schema = userManager.getUserSchemaName();
102            try (Closeable resource = ctx.wrap().with(DEFAULT_SCHEMA_NAME, schema).open()) {
103                List<Property> properties = readEntity(List.class, genericType, propsNode);
104                for (Property property : properties) {
105                    userDoc.setPropertyValue(property.getName(), property.getValue());
106                }
107            }
108        }
109        NuxeoPrincipal principal = new NuxeoPrincipalImpl(id);
110        principal.setModel(userDoc);
111        return principal;
112    }
113
114}