001/*
002 * This library is part of OpenCms -
003 * the Open Source Content Management System
004 *
005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com)
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * For further information about Alkacon Software, please see the
018 * company website: http://www.alkacon.com
019 *
020 * For further information about OpenCms, please see the
021 * project website: http://www.opencms.org
022 *
023 * You should have received a copy of the GNU Lesser General Public
024 * License along with this library; if not, write to the Free Software
025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
026 */
027
028package org.opencms.letsencrypt;
029
030import org.opencms.configuration.CmsElementWithAttrsParamConfigHelper;
031import org.opencms.configuration.CmsParameterConfiguration;
032import org.opencms.configuration.I_CmsConfigurationParameterHandler;
033import org.opencms.main.CmsLog;
034import org.opencms.util.CmsStringUtil;
035
036import org.apache.commons.logging.Log;
037
038/**
039 * Configuration class containing the LetsEncrypt configuration settings OpenCms needed by OpenCms.
040 */
041public class CmsLetsEncryptConfiguration implements I_CmsConfigurationParameterHandler {
042
043    /** Enum which represents different modes that control which domains OpenCms puts into the certificate configuration. */
044    public static enum Mode {
045
046        /** Use both site domains and workplace domains in certificate configuration. */
047        all,
048
049        /** Do not generate the certificate configuration. */
050        disabled,
051
052        /** Only use site domains in certificate configuration. */
053        sites,
054
055        /** Only use workplace domains in certificate configuration. */
056        workplace
057    }
058
059    /**
060     * Enum which represents the different types of events that LetsEncrypt updates should be triggered by.
061     */
062    public static enum Trigger {
063        /** Triggered when webserver config is updated. */
064        siteConfig,
065
066        /** Triggered when the webserver thread is run. */
067        webserverThread
068    }
069
070    /** Attribute name for the certificate configuration path. */
071    public static final String ATTR_CERTCONFIG = "certconfig";
072
073    /** Attribute name for the host. */
074    public static final String ATTR_HOST = "host";
075
076    /** Attribute name for the mode. */
077    public static final String ATTR_MODE = "mode";
078
079    /** Attribute name for the port. */
080    public static final String ATTR_PORT = "port";
081
082    /** Attribute name for the trigger mode. */
083    public static final String ATTR_TRIGGER = "trigger";
084
085    /** Node name. */
086    public static final String N_LETSENCRYPT = "letsencrypt";
087
088    /**
089     * Helper for parsing / generating the configuration.<p>
090     **/
091    public static final CmsElementWithAttrsParamConfigHelper CONFIG_HELPER = new CmsElementWithAttrsParamConfigHelper(
092        "*/system",
093        N_LETSENCRYPT,
094        CmsLetsEncryptConfiguration.class,
095        ATTR_HOST,
096        ATTR_PORT,
097        ATTR_MODE,
098        ATTR_CERTCONFIG,
099        ATTR_TRIGGER);
100
101    /** Logger instance for this class. */
102    private static final Log LOG = CmsLog.getLog(CmsLetsEncryptConfiguration.class);
103
104    /** The default trigger mode. */
105    public static final Trigger DEFAULT_TRIGGER = Trigger.siteConfig;
106
107    /** The internal configuration object. */
108    private CmsParameterConfiguration m_config = new CmsParameterConfiguration();
109
110    /**
111     * @see org.opencms.configuration.I_CmsConfigurationParameterHandler#addConfigurationParameter(java.lang.String, java.lang.String)
112     */
113    public void addConfigurationParameter(String paramName, String paramValue) {
114
115        m_config.put(paramName, paramValue);
116    }
117
118    /**
119     * Gets the path where the certificate configuration should be written to.<p>
120     *
121     * @return the certificate configuration target path
122     */
123    public String getCertConfigPath() {
124
125        return m_config.get(ATTR_CERTCONFIG);
126    }
127
128    /**
129     * @see org.opencms.configuration.I_CmsConfigurationParameterHandler#getConfiguration()
130     */
131    public CmsParameterConfiguration getConfiguration() {
132
133        return CmsParameterConfiguration.unmodifiableVersion(m_config);
134
135    }
136
137    /**
138     * Gets the host name for the LetsEncrypt docker container.<p>
139     *
140     * The host name is used to signal to the LetsEncrypt container that the configuration has been updated.
141     *
142     * @return the host name of the LetsEncrypt container
143     */
144    public String getHost() {
145
146        return m_config.get(ATTR_HOST);
147    }
148
149    /**
150     * Gets the configured mode, or null if no mode or an invalid mode have been configured.<p>
151     *
152     * @return the mode
153     */
154    public Mode getMode() {
155
156        try {
157            return Mode.valueOf(m_config.get(ATTR_MODE));
158        } catch (Exception e) {
159            LOG.error("Error getting letsencrypt mode: " + e.getLocalizedMessage(), e);
160            return null;
161        }
162    }
163
164    /**
165     * Gets the configured port, or -1 if the port is not set or has an invalid value.<p>
166     *
167     * The port is used to signal to the LetsEncrypt docker container that the certificate configuration has changed.
168     *
169     * @return the configured port
170     */
171    public int getPort() {
172
173        try {
174            String portStr = m_config.get(ATTR_PORT);
175            return Integer.valueOf(portStr).intValue();
176        } catch (Exception e) {
177            LOG.error("Error getting letsencrypt port: " + e.getLocalizedMessage(), e);
178            return -1;
179        }
180    }
181
182    /**
183     * Gets the trigger mode.<p>
184     *
185     * @return the trigger mode
186     */
187    public Trigger getTrigger() {
188
189        try {
190            String triggerStr = m_config.get(ATTR_TRIGGER);
191            if (triggerStr == null) {
192                return DEFAULT_TRIGGER; // trigger is optional, don't log an error
193            }
194            Trigger trigger = Trigger.valueOf(triggerStr);
195            return trigger;
196        } catch (Exception e) {
197            LOG.error("Error getting configured letsencrypt trigger: " + e.getLocalizedMessage(), e);
198            return DEFAULT_TRIGGER;
199        }
200
201    }
202
203    /**
204     * @see org.opencms.configuration.I_CmsConfigurationParameterHandler#initConfiguration()
205     */
206    public void initConfiguration() {
207        // do nothing
208    }
209
210    /**
211     * Checks if the configuration is enabled and does not have missing settings.<p>
212     *
213     * @return true if the configuration is enabled and does not have missing settings
214     */
215    public boolean isValidAndEnabled() {
216
217        return (getMode() != null)
218            && (getMode() != Mode.disabled)
219            && (getPort() > -1)
220            && !CmsStringUtil.isEmptyOrWhitespaceOnly(getCertConfigPath())
221            && !CmsStringUtil.isEmptyOrWhitespaceOnly(getHost());
222    }
223
224}