001/*
002 * (C) Copyright 2006-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 *     Thomas Roger
018 */
019package org.nuxeo.ecm.automation.core.operations.users;
020
021import static org.nuxeo.ecm.platform.usermanager.UserConfig.COMPANY_COLUMN;
022import static org.nuxeo.ecm.platform.usermanager.UserConfig.EMAIL_COLUMN;
023import static org.nuxeo.ecm.platform.usermanager.UserConfig.FIRSTNAME_COLUMN;
024import static org.nuxeo.ecm.platform.usermanager.UserConfig.LASTNAME_COLUMN;
025import static org.nuxeo.ecm.platform.usermanager.UserConfig.SCHEMA_NAME;
026import static org.nuxeo.ecm.platform.usermanager.UserConfig.TENANT_ID_COLUMN;
027import static org.nuxeo.ecm.platform.usermanager.UserConfig.USERNAME_COLUMN;
028
029import java.io.Serializable;
030import java.util.ArrayList;
031import java.util.Arrays;
032import java.util.Collections;
033import java.util.HashMap;
034import java.util.HashSet;
035import java.util.List;
036import java.util.Map;
037import java.util.Set;
038
039import org.apache.commons.lang.StringUtils;
040import org.nuxeo.ecm.automation.core.Constants;
041import org.nuxeo.ecm.automation.core.annotations.Context;
042import org.nuxeo.ecm.automation.core.annotations.Operation;
043import org.nuxeo.ecm.automation.core.annotations.OperationMethod;
044import org.nuxeo.ecm.automation.core.annotations.Param;
045import org.nuxeo.ecm.core.api.Blob;
046import org.nuxeo.ecm.core.api.Blobs;
047import org.nuxeo.ecm.core.api.DocumentModel;
048import org.nuxeo.ecm.core.api.DocumentModelList;
049import org.nuxeo.ecm.platform.usermanager.UserManager;
050
051import net.sf.json.JSONArray;
052import net.sf.json.JSONObject;
053
054/**
055 * @since 5.6
056 */
057@Operation(id = QueryUsers.ID, //
058        category = Constants.CAT_USERS_GROUPS, //
059        aliases = { "Services.QueryUsers" }, //
060        label = "Query users", //
061        description = "Query users on a combination of their username, firstName and lastName fields, or on any of them (pattern).")
062public class QueryUsers {
063
064    public static final String ID = "User.Query";
065
066    public static final Set<String> FULLTEXT_FIELDS = new HashSet<>(
067            Arrays.asList(USERNAME_COLUMN, FIRSTNAME_COLUMN, LASTNAME_COLUMN));
068
069    public static final String JSON_USERNAME = USERNAME_COLUMN;
070
071    public static final String JSON_FIRSTNAME = FIRSTNAME_COLUMN;
072
073    public static final String JSON_LASTNAME = LASTNAME_COLUMN;
074
075    public static final String JSON_EMAIL = EMAIL_COLUMN;
076
077    public static final String JSON_COMPANY = COMPANY_COLUMN;
078
079    public static final String JSON_TENANT_ID = TENANT_ID_COLUMN;
080
081    @Context
082    protected UserManager userManager;
083
084    @Param(name = "username", required = false)
085    protected String username;
086
087    @Param(name = "firstName", required = false)
088    protected String firstName;
089
090    @Param(name = "lastName", required = false)
091    protected String lastName;
092
093    @Param(name = "pattern", required = false)
094    protected String pattern;
095
096    @Param(name = "tenantId", required = false)
097    protected String tenantId;
098
099    @OperationMethod
100    public Blob run() {
101        List<DocumentModel> users;
102        if (StringUtils.isBlank(pattern)) {
103            Map<String, Serializable> filter = new HashMap<>();
104            if (StringUtils.isNotBlank(username)) {
105                filter.put(USERNAME_COLUMN, username);
106            }
107            if (StringUtils.isNotBlank(firstName)) {
108                filter.put(FIRSTNAME_COLUMN, firstName);
109            }
110            if (StringUtils.isNotBlank(lastName)) {
111                filter.put(LASTNAME_COLUMN, lastName);
112            }
113            if (StringUtils.isNotBlank(tenantId)) {
114                filter.put(TENANT_ID_COLUMN, tenantId);
115            }
116            users = userManager.searchUsers(filter, FULLTEXT_FIELDS);
117        } else {
118            users = new ArrayList<>();
119            Set<String> userIds = new HashSet<>();
120            for (String field : FULLTEXT_FIELDS) {
121                Map<String, Serializable> filter = new HashMap<>();
122                filter.put(field, pattern);
123                if (StringUtils.isNotBlank(tenantId)) {
124                    filter.put(TENANT_ID_COLUMN, tenantId);
125                }
126                DocumentModelList userDocs = userManager.searchUsers(filter, Collections.singleton(field));
127                for (DocumentModel userDoc : userDocs) {
128                    if (userIds.add(userDoc.getId())) { // avoid duplicates
129                        users.add(userDoc);
130                    }
131                }
132            }
133        }
134        return buildResponse(users);
135    }
136
137    protected Blob buildResponse(List<DocumentModel> users) {
138        JSONArray array = new JSONArray();
139        for (DocumentModel user : users) {
140            JSONObject o = new JSONObject();
141            o.element(JSON_USERNAME, user.getProperty(SCHEMA_NAME, USERNAME_COLUMN));
142            o.element(JSON_FIRSTNAME, user.getProperty(SCHEMA_NAME, FIRSTNAME_COLUMN));
143            o.element(JSON_LASTNAME, user.getProperty(SCHEMA_NAME, LASTNAME_COLUMN));
144            o.element(JSON_EMAIL, user.getProperty(SCHEMA_NAME, EMAIL_COLUMN));
145            o.element(JSON_COMPANY, user.getProperty(SCHEMA_NAME, COMPANY_COLUMN));
146            o.element(JSON_TENANT_ID, user.getProperty(SCHEMA_NAME, TENANT_ID_COLUMN));
147            array.add(o);
148        }
149        JSONObject result = new JSONObject();
150        result.put("users", array);
151        return Blobs.createJSONBlob(result.toString());
152    }
153
154}