/* * RESTHeart - the Web API for MongoDB * Copyright (C) SoftInstigate Srl * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.restheart.security.impl; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.List; import java.util.Map; import java.util.function.Consumer; import org.slf4j.LoggerFactory; import org.yaml.snakeyaml.Yaml; /** * * @author Maurizio Turatti {@literal <maurizio@softinstigate.com>} */ abstract class AbstractSimpleSecurityManager { private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(AbstractSimpleSecurityManager.class); AbstractSimpleSecurityManager() { } abstract Consumer<? super Map<String, Object>> consumeConfiguration(); @SuppressWarnings("unchecked") final void init(Map<String, Object> arguments, String type) throws FileNotFoundException { InputStream is = null; try { final String confFilePath = extractConfigFilePath(arguments); is = new FileInputStream(new File(confFilePath)); final Map<String, Object> conf = (Map<String, Object>) new Yaml().load(is); List<Map<String, Object>> confItems = extractConfItems(conf, type); confItems.stream().forEach(consumeConfiguration()); } catch(FileNotFoundException fnfe) { LOGGER.error("*** cannot find the file {} specified in the configuration.", extractConfigFilePath(arguments)); LOGGER.error("*** note that the path must be either absolute or relative to the directory containing the RESTHeart jar file."); throw fnfe; } finally { try { if (is != null) { is.close(); } } catch (IOException ex) { LOGGER.warn("Can't close the InputStream", ex); } } } final String extractConfigFilePath(Map<String, Object> arguments) throws IllegalArgumentException { if (arguments == null) { throw new IllegalArgumentException("missing required arguments conf-file"); } Object _confFilePath = arguments.getOrDefault("conf-file", "security.yml"); if (_confFilePath == null || !(_confFilePath instanceof String)) { throw new IllegalArgumentException("missing required arguments conf-file"); } String confFilePath = (String) _confFilePath; if (!confFilePath.startsWith("/")) { // this is to allow specifying the configuration file path relative to the jar (also working when running from classes) URL location = this.getClass().getProtectionDomain().getCodeSource().getLocation(); File locationFile = new File(location.getPath()); confFilePath = locationFile.getParent() + File.separator + confFilePath; } return confFilePath; } @SuppressWarnings("unchecked") final List<Map<String, Object>> extractConfItems(final Map<String, Object> conf, String type) throws IllegalArgumentException { Object _users = conf.get(type); if (_users == null || !(_users instanceof List)) { throw new IllegalArgumentException("wrong configuration file format. missing mandatory '" + type + "' section."); } List<Map<String, Object>> users = (List<Map<String, Object>>) _users; return users; } }