
package net.sourceforge.guacamole.net.basic;

/*
 *  Guacamole - Clientless Remote Desktop
 *  Copyright (C) 2010  Michael Jumper
 *
 *  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/>.
 */

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import org.glyptodon.guacamole.GuacamoleException;
import org.glyptodon.guacamole.net.auth.Credentials;
import org.glyptodon.guacamole.net.auth.simple.SimpleAuthenticationProvider;
import org.glyptodon.guacamole.net.basic.auth.Authorization;
import org.glyptodon.guacamole.net.basic.auth.UserMapping;
import org.glyptodon.guacamole.net.basic.xml.DocumentHandler;
import org.glyptodon.guacamole.net.basic.xml.user_mapping.UserMappingTagHandler;
import org.glyptodon.guacamole.properties.FileGuacamoleProperty;
import org.glyptodon.guacamole.properties.GuacamoleProperties;
import org.glyptodon.guacamole.protocol.GuacamoleConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;

/**
 * Authenticates users against a static list of username/password pairs.
 * Each username/password may be associated with multiple configurations.
 * This list is stored in an XML file which is reread if modified.
 *
 * @author Michael Jumper, Michal Kotas
 */
public class BasicFileAuthenticationProvider extends SimpleAuthenticationProvider {

    /**
     * Logger for this class.
     */
    private Logger logger = LoggerFactory.getLogger(BasicFileAuthenticationProvider.class);

    /**
     * The time the user mapping file was last modified.
     */
    private long mod_time;

    /**
     * The parsed UserMapping read when the user mapping file was last parsed.
     */
    private UserMapping user_mapping;

    /**
     * The filename of the XML file to read the user user_mapping from.
     */
    public static final FileGuacamoleProperty BASIC_USER_MAPPING = new FileGuacamoleProperty() {

        @Override
        public String getName() { return "basic-user-mapping"; }

    };

    /**
     * Returns a UserMapping containing all authorization data given within
     * the XML file specified by the "basic-user-mapping" property in
     * guacamole.properties. If the XML file has been modified or has not yet
     * been read, this function may reread the file.
     *
     * @return A UserMapping containing all authorization data within the
     *         user mapping XML file.
     * @throws GuacamoleException If the user mapping property is missing or
     *                            an error occurs while parsing the XML file.
     */
    private UserMapping getUserMapping() throws GuacamoleException {

        // Get user user_mapping file
        File user_mapping_file =
                GuacamoleProperties.getRequiredProperty(BASIC_USER_MAPPING);

        // If user_mapping not yet read, or user_mapping has been modified, reread
        if (user_mapping == null ||
                (user_mapping_file.exists()
                 && mod_time < user_mapping_file.lastModified())) {

            logger.info("Reading user mapping file: {}", user_mapping_file);

            // Parse document
            try {

                // Get handler for root element
                UserMappingTagHandler userMappingHandler =
                        new UserMappingTagHandler();

                // Set up document handler
                DocumentHandler contentHandler = new DocumentHandler(
                        "user-mapping", userMappingHandler);

                // Set up XML parser
                XMLReader parser = XMLReaderFactory.createXMLReader();
                parser.setContentHandler(contentHandler);

                // Read and parse file
                InputStream input = new BufferedInputStream(new FileInputStream(user_mapping_file));
                parser.parse(new InputSource(input));
                input.close();

                // Store mod time and user mapping
                mod_time = user_mapping_file.lastModified();
                user_mapping = userMappingHandler.asUserMapping();

            }
            catch (IOException e) {
                throw new GuacamoleException("Error reading basic user mapping file.", e);
            }
            catch (SAXException e) {
                throw new GuacamoleException("Error parsing basic user mapping XML.", e);
            }

        }

        // Return (possibly cached) user mapping
        return user_mapping;

    }

    @Override
    public Map<String, GuacamoleConfiguration>
            getAuthorizedConfigurations(Credentials credentials)
            throws GuacamoleException {

        // Validate and return info for given user and pass
        Authorization auth = getUserMapping().getAuthorization(credentials.getUsername());
        if (auth != null && auth.validate(credentials.getUsername(), credentials.getPassword()))
            return auth.getConfigurations();

        // Unauthorized
        return null;

    }

}
