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 *     Benoit Delbosc
018 */
019package org.nuxeo.elasticsearch.http.readonly.filter;
020
021import java.util.ArrayList;
022import java.util.HashMap;
023import java.util.HashSet;
024import java.util.List;
025import java.util.Map;
026import java.util.Set;
027
028import javax.validation.constraints.NotNull;
029
030import org.apache.commons.lang.StringUtils;
031import org.json.JSONArray;
032import org.json.JSONException;
033import org.json.JSONObject;
034import org.nuxeo.ecm.core.api.NuxeoPrincipal;
035import org.nuxeo.ecm.core.security.SecurityService;
036import org.nuxeo.elasticsearch.ElasticSearchConstants;
037import org.nuxeo.elasticsearch.api.ElasticSearchAdmin;
038import org.nuxeo.runtime.api.Framework;
039
040/**
041 * Validate request inputs.
042 *
043 * @since 7.3
044 */
045public class RequestValidator {
046    final private Map<String, List<String>> indexTypes;
047
048    public RequestValidator() {
049        ElasticSearchAdmin esa = Framework.getService(ElasticSearchAdmin.class);
050        indexTypes = new HashMap<>();
051        for (String name : esa.getRepositoryNames()) {
052            List<String> types = new ArrayList<>();
053            types.add(ElasticSearchConstants.DOC_TYPE);
054            indexTypes.put(esa.getIndexNameForRepository(name), types);
055        }
056    }
057
058    public void checkValidDocumentId(String documentId) {
059        if (documentId == null) {
060            throw new IllegalArgumentException("Invalid document id");
061        }
062    }
063
064    public @NotNull String getTypes(String indices, String types) {
065        Set<String> validTypes = new HashSet<>();
066        for (String index : indices.split(",")) {
067            validTypes.addAll(indexTypes.get(index));
068        }
069        if (types == null || "*".equals(types) || "_all".equals(types)) {
070            return StringUtils.join(validTypes, ',');
071        }
072        for (String type : types.split(",")) {
073            if (!validTypes.contains(type)) {
074                throw new IllegalArgumentException("Invalid index type: " + type);
075            }
076        }
077        return types;
078    }
079
080    public @NotNull String getIndices(String indices) {
081        if (indices == null || "*".equals(indices) || "_all".equals(indices)) {
082            return StringUtils.join(indexTypes.keySet(), ',');
083        }
084
085        for (String index : indices.split(",")) {
086            if (!indexTypes.containsKey(index)) {
087                throw new IllegalArgumentException("Invalid index submitted: " + index);
088            }
089        }
090        return indices;
091    }
092
093    public void checkAccess(NuxeoPrincipal principal, String docAcl) {
094        try {
095            JSONObject docAclJson = new JSONObject(docAcl);
096            JSONArray acl = docAclJson.getJSONObject("fields").getJSONArray("ecm:acl");
097            String[] principals = SecurityService.getPrincipalsToCheck(principal);
098            for (int i = 0; i < acl.length(); i++)
099                for (String name : principals) {
100                    if (name.equals(acl.getString(i))) {
101                        return;
102                    }
103                }
104        } catch (JSONException e) {
105            // throw a securityException
106        }
107        throw new SecurityException("Unauthorized access");
108    }
109}