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        UserManager userManager = Framework.getService(UserManager.class);
056        DocumentModel user = userManager.getBareUserModel();
057        user.setPropertyValue(userManager.getUserIdField(), nuxeoLogin);
058        try {
059            userDoc = Framework.doPrivileged(() -> {
060                return userManager.createUser(user);
061            });
062        } catch (NuxeoException e) {
063            log.error("Error while creating user " + nuxeoLogin + "in UserManager", e);
064            return null;
065        }
066
067        return userDoc;
068    }
069
070    protected abstract DocumentModel updateUserInfo(DocumentModel user, OpenIDUserInfo userInfo);
071
072    public String findOrCreateNuxeoUser(OpenIDUserInfo userInfo) {
073        String user = findNuxeoUser(userInfo);
074        if (user == null) {
075            user = generateRandomUserId();
076            DocumentModel userDoc = createNuxeoUser(user);
077            updateUserInfo(userDoc, userInfo);
078        }
079        return user;
080    }
081
082    protected String generateRandomUserId() {
083        String userId = null;
084
085        try {
086            UserManager userManager = Framework.getService(UserManager.class);
087            List<String> userIds = userManager.getUserIds();
088
089            while (userId == null || userIds.contains(userId)) {
090                userId = "user_" + GENERATOR.generate(4);
091            }
092        } catch (NuxeoException e) {
093            log.error("Error while generating random user id", e);
094            return null;
095        }
096        return userId;
097    }
098}