com.adito.activedirectory.ActiveDirectoryPropertyManager.java Source code

Java tutorial

Introduction

Here is the source code for com.adito.activedirectory.ActiveDirectoryPropertyManager.java

Source

/*
*  Adito
*
*  Copyright (C) 2003-2006 3SP LTD. All Rights Reserved
*
*  This program is free software; you can redistribute it and/or
*  modify it under the terms of the GNU General Public License
*  as published by the Free Software Foundation; either version 2 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 General Public License for more details.
*
*  You should have received a copy of the GNU General Public
*  License along with this program; if not, write to the Free Software
*  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

package com.adito.activedirectory;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.adito.boot.ContextHolder;
import com.adito.boot.PropertyList;
import com.adito.properties.Property;
import com.adito.properties.impl.realms.RealmKey;
import com.adito.realms.Realm;

final class ActiveDirectoryPropertyManager {

    private static final Log log = LogFactory.getLog(ActiveDirectoryPropertyManager.class);
    private static final String TEMPLATE_FILE = "krb5.template";
    private static final String CONF_DIRECTORY = "activedirectory";
    private static final String CONF_FILE = "krb5.conf";

    private static final String PORT_SEPARATOR = ":";
    private static final String START_REPLACEMENT = "${";
    private static final String END_REPLACEMENT = "}";

    private static final String DOMAIN = "DOMAIN";
    private static final String KDC_TIMEOUT = "KDC_TIMEOUT";
    private static final String KDC_MAX_TRIES = "KDC_MAX_RETRIES";
    private static final String HOST_REALMS = "HOST_REALMS";
    private static final String HOST_NAME = "HOST_NAME";
    private static final String HOST_REALM_REPLACEMENT = "kdc = " + START_REPLACEMENT + HOST_NAME + END_REPLACEMENT;
    private static final String DOMAIN_REALMS = "DOMAIN_REALMS";
    private static final String DOMAIN_REALM_REPLACEMENT = "." + START_REPLACEMENT + HOST_NAME + END_REPLACEMENT
            + " = " + START_REPLACEMENT + DOMAIN + END_REPLACEMENT;

    private final Properties propertyNames;
    private final Realm realm;

    ActiveDirectoryPropertyManager(Realm realm, Properties propertyNames) {
        this.propertyNames = propertyNames;
        this.realm = realm;
        System.setProperty("java.security.krb5.conf", getConfFile());
    }

    private static String getConfFile() {
        File tempDirectory = ContextHolder.getContext().getTempDirectory();
        File configurationFile = new File(tempDirectory, CONF_FILE);
        return configurationFile.getAbsolutePath();
    }

    void refresh() {
        refresh(Collections.<String, String>emptyMap());
    }

    void refresh(Map<String, String> alternativeValues) {
        try {
            doFileReplacement(alternativeValues);
        } catch (IOException e) {
            log.error("Failed to update Active Directory configuration " + CONF_FILE, e);
        }
    }

    private void doFileReplacement(Map<String, String> alternativeValues) throws IOException {
        File confDirectory = ContextHolder.getContext().getConfDirectory();
        File templateFile = new File(confDirectory, CONF_DIRECTORY + getFileSeparator() + TEMPLATE_FILE);
        String readFile = readFile(templateFile);

        File tempDirectory = ContextHolder.getContext().getTempDirectory();
        File configurationFile = new File(tempDirectory, CONF_FILE);
        if (!configurationFile.exists() && !configurationFile.createNewFile()) {
            log.error("Failed to create file " + CONF_FILE + ".");
        } else {
            String replacement = getReplacement(readFile, alternativeValues);
            writeFile(configurationFile, replacement);
        }
    }

    private String getReplacement(String fileContents, Map<String, String> alternativeValues) {
        Map<String, String> replacements = buildReplacements(alternativeValues);
        for (Map.Entry<String, String> entry : replacements.entrySet()) {
            fileContents = replaceValue(fileContents, entry.getKey(), entry.getValue());
        }
        return fileContents;
    }

    private Map<String, String> buildReplacements(Map<String, String> alternativeValues) {
        Map<String, String> replacements = new HashMap<String, String>();

        String dbDomain = Property.getProperty(getRealmKey("activeDirectory.domain")).toUpperCase().trim();
        String domain = getRealValue(alternativeValues, DOMAIN, dbDomain);
        replacements.put(DOMAIN, domain);

        String dbControllerHost = Property.getProperty(getRealmKey("activeDirectory.controllerHost"));
        String controllerHost = getRealValue(alternativeValues, "activeDirectory.controllerHost", dbControllerHost);

        String dbTimeout = String
                .valueOf(Property.getPropertyInt(getRealmKey("activeDirectory.kdcTimeout")) * 1000);
        String timeout = getRealValue(alternativeValues, "activeDirectory.kdcTimeout", dbTimeout);
        replacements.put(KDC_TIMEOUT, timeout);

        String dbMaxTries = String.valueOf(Property.getPropertyInt(getRealmKey("activeDirectory.kdcMaxTries")));
        String maxTries = getRealValue(alternativeValues, "activeDirectory.kdcMaxTries", dbMaxTries);
        replacements.put(KDC_MAX_TRIES, maxTries);

        PropertyList dbActiveDirectryUris = new PropertyList();
        dbActiveDirectryUris.add(controllerHost);
        dbActiveDirectryUris.addAll(Property.getPropertyList(getRealmKey("activeDirectory.backupControllerHosts")));
        PropertyList activeDirectryUris = getRealValue(alternativeValues, "activeDirectory.backupControllerHosts",
                dbActiveDirectryUris);
        replacements.put(HOST_REALMS, buildBackupHostRealms(activeDirectryUris));
        replacements.put(DOMAIN_REALMS, buildBackupDomainRealms(domain, activeDirectryUris));
        return replacements;
    }

    private static String getRealValue(Map<String, String> alternativeValues, String key, String value) {
        return alternativeValues.containsKey(key) ? alternativeValues.get(key) : value;
    }

    private static PropertyList getRealValue(Map<String, String> alternativeValues, String key,
            PropertyList values) {
        return alternativeValues.containsKey(key) ? new PropertyList(alternativeValues.get(key)) : values;
    }

    private static String replaceValue(String contents, String key, String value) {
        key = START_REPLACEMENT + key + END_REPLACEMENT;
        return contents.replace(key, value);
    }

    private static String buildBackupHostRealms(PropertyList activeDirectryUris) {
        StringBuffer buffer = new StringBuffer();
        for (String uri : activeDirectryUris) {
            uri = uri.contains(PORT_SEPARATOR) ? uri.substring(0, uri.lastIndexOf(PORT_SEPARATOR)) : uri;
            String replace = replaceValue(HOST_REALM_REPLACEMENT, HOST_NAME, uri);
            buffer.append(replace).append(getLineSeparator());
        }
        return buffer.toString();
    }

    private static String buildBackupDomainRealms(String domain, PropertyList activeDirectryUris) {
        StringBuffer buffer = new StringBuffer();
        for (String uri : activeDirectryUris) {
            uri = uri.contains(PORT_SEPARATOR) ? uri.substring(0, uri.lastIndexOf(PORT_SEPARATOR)) : uri;
            String replace = replaceValue(DOMAIN_REALM_REPLACEMENT, HOST_NAME, uri);
            replace = replaceValue(replace, DOMAIN, domain);
            buffer.append(replace).append(getLineSeparator());
        }
        return buffer.toString();
    }

    private RealmKey getRealmKey(String key) {
        String propertyOrDefault = propertyNames.getProperty(key, key);
        return new RealmKey(propertyOrDefault, realm);
    }

    private static void writeFile(File file, String contents) throws IOException {
        BufferedWriter output = null;
        try {
            output = new BufferedWriter(new FileWriter(file));
            output.write(contents);
        } finally {
            close(output);
        }
    }

    private static void close(BufferedWriter writer) {
        try {
            if (writer != null) {
                writer.close();
            }
        } catch (IOException e) {
            // ignore
        }
    }

    private static String readFile(File file) throws IOException {
        StringBuffer contents = new StringBuffer();
        BufferedReader input = null;
        try {
            input = new BufferedReader(new FileReader(file));
            String line = null;
            while ((line = input.readLine()) != null) {
                contents.append(line);
                contents.append(getLineSeparator());
            }
        } finally {
            close(input);
        }
        return contents.toString();
    }

    private static String getFileSeparator() {
        return System.getProperty("file.separator");
    }

    private static String getLineSeparator() {
        return System.getProperty("line.separator");
    }

    private static void close(BufferedReader reader) {
        try {
            if (reader != null) {
                reader.close();
            }
        } catch (IOException e) {
            // ignore
        }
    }
}