001/*
002 * (C) Copyright 2006-2018 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 *     Nelson Silva <nelson.silva@inevo.pt> - initial API and implementation
018 *     Nuxeo
019 */
020package org.nuxeo.ecm.platform.oauth2.openid.auth;
021
022import java.util.List;
023
024import org.apache.commons.logging.Log;
025import org.apache.commons.logging.LogFactory;
026import org.apache.commons.text.CharacterPredicates;
027import org.apache.commons.text.RandomStringGenerator;
028import org.nuxeo.ecm.core.api.DocumentModel;
029import org.nuxeo.ecm.core.api.NuxeoException;
030import org.nuxeo.ecm.platform.oauth2.openid.OpenIDConnectProvider;
031import org.nuxeo.ecm.platform.usermanager.UserManager;
032import org.nuxeo.runtime.api.Framework;
033
034public abstract class UserResolver {
035
036    private static final Log log = LogFactory.getLog(UserResolver.class);
037
038    private static final RandomStringGenerator GENERATOR = new RandomStringGenerator.Builder().filteredBy(
039            CharacterPredicates.DIGITS).build();
040
041    private OpenIDConnectProvider provider;
042
043    public UserResolver(OpenIDConnectProvider provider) {
044        this.provider = provider;
045    }
046
047    public OpenIDConnectProvider getProvider() {
048        return provider;
049    }
050
051    protected abstract String findNuxeoUser(OpenIDUserInfo userInfo);
052
053    protected DocumentModel createNuxeoUser(String nuxeoLogin) {
054        DocumentModel userDoc;
055
056        try {
057            UserManager userManager = Framework.getService(UserManager.class);
058
059            userDoc = userManager.getBareUserModel();
060            userDoc.setPropertyValue(userManager.getUserIdField(), nuxeoLogin);
061
062            userDoc = userManager.createUser(userDoc);
063
064        } catch (NuxeoException e) {
065            log.error("Error while creating user " + nuxeoLogin + "in UserManager", e);
066            return null;
067        }
068
069        return userDoc;
070    }
071
072    protected abstract DocumentModel updateUserInfo(DocumentModel user, OpenIDUserInfo userInfo);
073
074    public String findOrCreateNuxeoUser(OpenIDUserInfo userInfo) {
075        String user = findNuxeoUser(userInfo);
076        if (user == null) {
077            user = generateRandomUserId();
078            DocumentModel userDoc = createNuxeoUser(user);
079            updateUserInfo(userDoc, userInfo);
080        }
081        return user;
082    }
083
084    protected String generateRandomUserId() {
085        String userId = null;
086
087        try {
088            UserManager userManager = Framework.getService(UserManager.class);
089            List<String> userIds = userManager.getUserIds();
090
091            while (userId == null || userIds.contains(userId)) {
092                userId = "user_" + GENERATOR.generate(4);
093            }
094        } catch (NuxeoException e) {
095            log.error("Error while generating random user id", e);
096            return null;
097        }
098        return userId;
099    }
100}