/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.storm.daemon.logviewer.utils;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Sets;

import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.Validate;
import org.apache.storm.Config;
import org.apache.storm.DaemonConfig;
import org.apache.storm.security.auth.ClientAuthUtils;
import org.apache.storm.security.auth.IGroupMappingServiceProvider;
import org.apache.storm.security.auth.IPrincipalToLocal;
import org.apache.storm.utils.ObjectReader;
import org.apache.storm.utils.ServerConfigUtils;
import org.apache.storm.utils.Utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ResourceAuthorizer {

    private static final Logger LOG = LoggerFactory.getLogger(ResourceAuthorizer.class);
    
    private final Map<String, Object> stormConf;
    private final IGroupMappingServiceProvider groupMappingServiceProvider;
    private final IPrincipalToLocal principalToLocal;

    /**
     * Constuctor.
     *
     * @param stormConf storm configuration
     */
    public ResourceAuthorizer(Map<String, Object> stormConf) {
        this.stormConf = stormConf;
        this.groupMappingServiceProvider = ClientAuthUtils.getGroupMappingServiceProviderPlugin(stormConf);
        this.principalToLocal = ClientAuthUtils.getPrincipalToLocalPlugin(stormConf);
    }

    /**
     * Checks whether user is allowed to access a Logviewer file via UI. Always true when the Logviewer filter is not configured.
     *
     * @param fileName file name to access. The file name must not contain upward path traversal sequences (e.g. "../").
     * @param user username
     */
    public boolean isUserAllowedToAccessFile(String user, String fileName) {
        return !isLogviewerFilterConfigured() || isAuthorizedLogUser(user, fileName);
    }

    /**
     * Checks whether user is authorized to access file. Checks regardless of UI filter.
     *
     * @param user username
     * @param fileName file name to access. The file name must not contain upward path traversal sequences (e.g. "../").
     */
    public boolean isAuthorizedLogUser(String user, String fileName) {
        Validate.isTrue(!fileName.contains(".." + FileSystems.getDefault().getSeparator()));
        if (StringUtils.isEmpty(user) || StringUtils.isEmpty(fileName)) {
            return false;
        }
        LogUserGroupWhitelist whitelist = getLogUserGroupWhitelist(fileName);

        List<String> logsUsers = new ArrayList<>();
        logsUsers.addAll(ObjectReader.getStrings(stormConf.get(DaemonConfig.LOGS_USERS)));
        logsUsers.addAll(ObjectReader.getStrings(stormConf.get(Config.NIMBUS_ADMINS)));
        if (whitelist != null) {
            logsUsers.addAll(whitelist.getUserWhitelist());
        }

        List<String> logsGroups = new ArrayList<>();
        logsGroups.addAll(ObjectReader.getStrings(stormConf.get(DaemonConfig.LOGS_GROUPS)));
        logsGroups.addAll(ObjectReader.getStrings(stormConf.get(Config.NIMBUS_ADMINS_GROUPS)));
        if (whitelist != null) {
            logsGroups.addAll(whitelist.getGroupWhitelist());
        }

        String userName = principalToLocal.toLocal(user);
        Set<String> groups = getUserGroups(userName);

        return logsUsers.stream().anyMatch(u -> u.equals(userName))
            || Sets.intersection(groups, new HashSet<>(logsGroups)).size() > 0;

    }

    /**
     * Get the whitelist of users and groups for given file.
     *
     * @param fileName file name to get the whitelist
     */
    public LogUserGroupWhitelist getLogUserGroupWhitelist(String fileName) {
        File wlFile = ServerConfigUtils.getLogMetaDataFile(fileName);
        Map<String, Object> map = (Map<String, Object>) Utils.readYamlFile(wlFile.getAbsolutePath());

        if (map == null) {
            return null;
        }

        List<String> logsUsers = ObjectReader.getStrings(map.get(DaemonConfig.LOGS_USERS));
        List<String> logsGroups = ObjectReader.getStrings(map.get(DaemonConfig.LOGS_GROUPS));
        return new LogUserGroupWhitelist(
                logsUsers.isEmpty() ? new HashSet<>() : new HashSet<>(logsUsers),
                logsGroups.isEmpty() ? new HashSet<>() : new HashSet<>(logsGroups)
        );
    }

    @VisibleForTesting
    Set<String> getUserGroups(String user) {
        try {
            if (StringUtils.isEmpty(user)) {
                return new HashSet<>();
            } else {
                return groupMappingServiceProvider.getGroups(user);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private boolean isLogviewerFilterConfigured() {
        return StringUtils.isNotBlank(ObjectReader.getString(stormConf.get(DaemonConfig.LOGVIEWER_FILTER), null))
                || StringUtils.isNotBlank(ObjectReader.getString(stormConf.get(DaemonConfig.UI_FILTER), null));
    }

    public static class LogUserGroupWhitelist {

        private Set<String> userWhitelist;
        private Set<String> groupWhitelist;

        public LogUserGroupWhitelist(Set<String> userWhitelist, Set<String> groupWhitelist) {
            this.userWhitelist = userWhitelist;
            this.groupWhitelist = groupWhitelist;
        }

        public Set<String> getUserWhitelist() {
            return userWhitelist;
        }

        public Set<String> getGroupWhitelist() {
            return groupWhitelist;
        }

    }
}
