Moved external HttpServer to hal-core and added SSL possibility through LestEncrypt
This commit is contained in:
parent
2dc35e212b
commit
e8270d4027
6 changed files with 113 additions and 22 deletions
|
|
@ -4,4 +4,6 @@
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation 'org.xerial:sqlite-jdbc:3.32.3.2'
|
implementation 'org.xerial:sqlite-jdbc:3.32.3.2'
|
||||||
|
implementation 'org.shredzone.acme4j:acme4j-client:2.12'
|
||||||
|
implementation 'org.shredzone.acme4j:acme4j-utils:2.12'
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,8 @@ public class HalContext {
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
public static final String CONFIG_HTTP_PORT = "hal_core.http_port";
|
public static final String CONFIG_HTTP_PORT = "hal_core.http_port";
|
||||||
|
public static final String CONFIG_HTTP_EXTERNAL_PORT = "hal_core.http_external_port";
|
||||||
|
public static final String CONFIG_HTTP_EXTERNAL_DOMAIN = "hal_core.http_external_domain";
|
||||||
public static final String CONFIG_MAP_BACKGROUND_IMAGE = "hal_core.map_bgimage";
|
public static final String CONFIG_MAP_BACKGROUND_IMAGE = "hal_core.map_bgimage";
|
||||||
|
|
||||||
public static final String RESOURCE_ROOT;
|
public static final String RESOURCE_ROOT;
|
||||||
|
|
|
||||||
|
|
@ -4,15 +4,19 @@ package se.hal;
|
||||||
import se.hal.intf.*;
|
import se.hal.intf.*;
|
||||||
import se.hal.page.HalAlertManager;
|
import se.hal.page.HalAlertManager;
|
||||||
import se.hal.struct.PluginConfig;
|
import se.hal.struct.PluginConfig;
|
||||||
|
import se.hal.util.HalAcmeDataStore;
|
||||||
import zutil.db.DBConnection;
|
import zutil.db.DBConnection;
|
||||||
import zutil.io.file.FileUtil;
|
import zutil.io.file.FileUtil;
|
||||||
import zutil.log.LogUtil;
|
import zutil.log.LogUtil;
|
||||||
|
import zutil.net.acme.AcmeClient;
|
||||||
|
import zutil.net.http.HttpPage;
|
||||||
import zutil.net.http.HttpServer;
|
import zutil.net.http.HttpServer;
|
||||||
import zutil.net.http.page.HttpFilePage;
|
import zutil.net.http.page.HttpFilePage;
|
||||||
import zutil.net.http.page.HttpRedirectPage;
|
import zutil.net.http.page.HttpRedirectPage;
|
||||||
import zutil.plugin.PluginData;
|
import zutil.plugin.PluginData;
|
||||||
import zutil.plugin.PluginManager;
|
import zutil.plugin.PluginManager;
|
||||||
|
|
||||||
|
import java.security.cert.Certificate;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
@ -22,6 +26,9 @@ import java.util.concurrent.ScheduledExecutorService;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import static se.hal.HalContext.CONFIG_HTTP_EXTERNAL_DOMAIN;
|
||||||
|
import static se.hal.HalContext.CONFIG_HTTP_EXTERNAL_PORT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main class for Hal
|
* Main class for Hal
|
||||||
*/
|
*/
|
||||||
|
|
@ -34,7 +41,7 @@ public class HalServer {
|
||||||
private static List<HalDaemon> daemons = new ArrayList<>();
|
private static List<HalDaemon> daemons = new ArrayList<>();
|
||||||
|
|
||||||
private static HttpServer http;
|
private static HttpServer http;
|
||||||
private static List<HalWebPage> pages = new ArrayList<>();
|
private static HttpServer httpExternal;
|
||||||
|
|
||||||
private static PluginManager pluginManager;
|
private static PluginManager pluginManager;
|
||||||
|
|
||||||
|
|
@ -51,8 +58,9 @@ public class HalServer {
|
||||||
|
|
||||||
// init variables
|
// init variables
|
||||||
pluginManager = new PluginManager();
|
pluginManager = new PluginManager();
|
||||||
daemonExecutor = Executors.newScheduledThreadPool(1); // We set only one thread for easier troubleshooting
|
daemonExecutor = Executors.newScheduledThreadPool(1); // We set only one thread for easier troubleshooting for now
|
||||||
http = new HttpServer(HalContext.getIntegerProperty(HalContext.CONFIG_HTTP_PORT));
|
http = new HttpServer(HalContext.getIntegerProperty(HalContext.CONFIG_HTTP_PORT));
|
||||||
|
http.start();
|
||||||
|
|
||||||
// Upgrade database
|
// Upgrade database
|
||||||
HalDatabaseUpgradeManager.initialize(pluginManager);
|
HalDatabaseUpgradeManager.initialize(pluginManager);
|
||||||
|
|
@ -65,6 +73,27 @@ public class HalServer {
|
||||||
|
|
||||||
logger.info("Working directory: " + FileUtil.find(".").getAbsolutePath());
|
logger.info("Working directory: " + FileUtil.find(".").getAbsolutePath());
|
||||||
|
|
||||||
|
// ------------------------------------
|
||||||
|
// Initialize External HttpServer
|
||||||
|
// ------------------------------------
|
||||||
|
|
||||||
|
if (HalContext.containsProperty(CONFIG_HTTP_EXTERNAL_PORT) &&
|
||||||
|
HalContext.containsProperty(CONFIG_HTTP_EXTERNAL_DOMAIN)) {
|
||||||
|
// Start a non secure server to retrieve handle the ACME protocol challenge
|
||||||
|
HttpServer tmpHttpExternal = new HttpServer(HalContext.getIntegerProperty(CONFIG_HTTP_EXTERNAL_PORT));
|
||||||
|
tmpHttpExternal.start();
|
||||||
|
|
||||||
|
AcmeClient acme = new AcmeClient(new HalAcmeDataStore());
|
||||||
|
Certificate certificate = acme.fetchCertificate(tmpHttpExternal, HalContext.getStringProperty(CONFIG_HTTP_EXTERNAL_DOMAIN));
|
||||||
|
|
||||||
|
tmpHttpExternal.close();
|
||||||
|
httpExternal = new HttpServer(HalContext.getIntegerProperty(CONFIG_HTTP_EXTERNAL_PORT));
|
||||||
|
httpExternal.start();
|
||||||
|
} else {
|
||||||
|
logger.warning("Missing '" + CONFIG_HTTP_EXTERNAL_PORT + "' and '" + CONFIG_HTTP_EXTERNAL_DOMAIN + "' configuration, will not setup external http server.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------
|
// ------------------------------------
|
||||||
// Initialize Plugins
|
// Initialize Plugins
|
||||||
// ------------------------------------
|
// ------------------------------------
|
||||||
|
|
@ -124,7 +153,6 @@ public class HalServer {
|
||||||
registerPage(it.next());
|
registerPage(it.next());
|
||||||
for (Iterator<HalWebPage> it = pluginManager.getSingletonIterator(HalWebPage.class); it.hasNext(); )
|
for (Iterator<HalWebPage> it = pluginManager.getSingletonIterator(HalWebPage.class); it.hasNext(); )
|
||||||
registerPage(it.next());
|
registerPage(it.next());
|
||||||
http.start();
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.log(Level.SEVERE, "Startup failed.", e);
|
logger.log(Level.SEVERE, "Startup failed.", e);
|
||||||
|
|
@ -172,11 +200,45 @@ public class HalServer {
|
||||||
daemon.initiate(daemonExecutor);
|
daemon.initiate(daemonExecutor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param page registers the given page with the intranet Hal web server.
|
* Registers the given page with the intranet Hal web server.
|
||||||
|
*
|
||||||
|
* @param url is the web path to the page.
|
||||||
|
* @param page is the page to register with the server.
|
||||||
|
*/
|
||||||
|
public static void registerPage(String url, HttpPage page){
|
||||||
|
http.setPage(url, page);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers the given page with the intranet Hal web server.
|
||||||
|
*
|
||||||
|
* @param page is the page to register with the server.
|
||||||
*/
|
*/
|
||||||
public static void registerPage(HalWebPage page){
|
public static void registerPage(HalWebPage page){
|
||||||
pages.add(page);
|
registerPage(page.getId(), page);
|
||||||
http.setPage(page.getId(), page);
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers the given page with the external Hal web server.
|
||||||
|
* Note: as this page will most likely be accessible trough the internet it needs to be robust and secure.
|
||||||
|
*
|
||||||
|
* @param url is the web path to the page.
|
||||||
|
* @param page is the page to register with the server.
|
||||||
|
*/
|
||||||
|
public static void registerExternalPage(String url, HttpPage page){
|
||||||
|
if (httpExternal != null)
|
||||||
|
httpExternal.setPage(url, page);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers the given page with the external Hal web server.
|
||||||
|
* Note: as this page will most likely be accessible trough the internet it needs to be robust and secure.
|
||||||
|
*
|
||||||
|
* @param page is the page to register with the server.
|
||||||
|
*/
|
||||||
|
public static void registerExternalPage(HalWebPage page){
|
||||||
|
registerExternalPage(page.getId(), page);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
30
hal-core/src/se/hal/util/HalAcmeDataStore.java
Normal file
30
hal-core/src/se/hal/util/HalAcmeDataStore.java
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
package se.hal.util;
|
||||||
|
|
||||||
|
import zutil.net.acme.AcmeDataStore;
|
||||||
|
|
||||||
|
import java.security.KeyPair;
|
||||||
|
|
||||||
|
public class HalAcmeDataStore implements AcmeDataStore {
|
||||||
|
private static final String CONFIG_HTTP_EXTERNAL_USER_KEY = "hal_core.http_external_user_key";
|
||||||
|
private static final String CONFIG_HTTP_EXTERNAL_DOMAIN_KEY = "hal_core.http_external_domain_key";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public KeyPair loadUserKeyPair() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void storeUserKeyPair(KeyPair keyPair) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public KeyPair loadDomainKeyPair() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void storeDomainKeyPair(KeyPair keyPair) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,6 +3,8 @@
|
||||||
# ------------------------------------
|
# ------------------------------------
|
||||||
|
|
||||||
hal_core.http_port=8080
|
hal_core.http_port=8080
|
||||||
|
hal_core.http_external_port=8081
|
||||||
|
#hal_core.http_external_domain=example.com
|
||||||
|
|
||||||
# ------------------------------------------------------------------------
|
# ------------------------------------------------------------------------
|
||||||
# Plugin configurations
|
# Plugin configurations
|
||||||
|
|
@ -13,16 +15,15 @@ hal_core.http_port=8080
|
||||||
# ------------------------------------
|
# ------------------------------------
|
||||||
|
|
||||||
## Tellstick plugin
|
## Tellstick plugin
|
||||||
#hal_tellstick.com_port=COM5
|
#hal_tellstick.com_port=COM5|/dev/serial/by-id/usb-Telldus_TellStick_Duo_A6XNNE6Z-if00-port0
|
||||||
#hal_tellstick.com_port=/dev/serial/by-id/usb-Telldus_TellStick_Duo_A6XNNE6Z-if00-port0
|
|
||||||
|
|
||||||
## NetUPS plugin
|
## NetUPS plugin
|
||||||
#hal_nutups.host=
|
#hal_nutups.host=
|
||||||
#hal_nutups.port=
|
#hal_nutups.port=
|
||||||
|
|
||||||
## NetScan plugin
|
## NetScan plugin
|
||||||
# Network scanning should probably be disabled in some networks (default on)
|
# Network scanning should probably be disabled in some networks
|
||||||
#hal_netscan.ipscan=false
|
#hal_netscan.ipscan=true
|
||||||
|
|
||||||
## Zigbee plugin
|
## Zigbee plugin
|
||||||
#hal_zigbee.com_port=COM4
|
#hal_zigbee.com_port=COM4
|
||||||
|
|
@ -39,5 +40,4 @@ hal_powerchallenge.sync_port=6666
|
||||||
# ------------------------------------
|
# ------------------------------------
|
||||||
|
|
||||||
## Google Assistant
|
## Google Assistant
|
||||||
hal_assistant.google.port=8081
|
|
||||||
hal_assistant.google.client_id=https://oauth-redirect.googleusercontent.com/r/optimal-comfort-XXXXX
|
hal_assistant.google.client_id=https://oauth-redirect.googleusercontent.com/r/optimal-comfort-XXXXX
|
||||||
|
|
|
||||||
|
|
@ -25,9 +25,9 @@
|
||||||
package se.hal.plugin.assistant.google;
|
package se.hal.plugin.assistant.google;
|
||||||
|
|
||||||
import se.hal.HalContext;
|
import se.hal.HalContext;
|
||||||
|
import se.hal.HalServer;
|
||||||
import se.hal.intf.HalDaemon;
|
import se.hal.intf.HalDaemon;
|
||||||
import zutil.log.LogUtil;
|
import zutil.log.LogUtil;
|
||||||
import zutil.net.http.HttpServer;
|
|
||||||
import zutil.net.http.page.oauth.OAuth2AuthorizationPage;
|
import zutil.net.http.page.oauth.OAuth2AuthorizationPage;
|
||||||
import zutil.net.http.page.oauth.OAuth2Registry;
|
import zutil.net.http.page.oauth.OAuth2Registry;
|
||||||
import zutil.net.http.page.oauth.OAuth2TokenPage;
|
import zutil.net.http.page.oauth.OAuth2TokenPage;
|
||||||
|
|
@ -43,19 +43,16 @@ public class SmartHomeDaemon implements HalDaemon {
|
||||||
public static final String ENDPOINT_TOKEN = "api/assistant/google/auth/token";
|
public static final String ENDPOINT_TOKEN = "api/assistant/google/auth/token";
|
||||||
public static final String ENDPOINT_SMARTHOME = "api/assistant/google/smarthome";
|
public static final String ENDPOINT_SMARTHOME = "api/assistant/google/smarthome";
|
||||||
|
|
||||||
private static final String CONFIG_PORT = "hal_assistant.google.port";
|
|
||||||
private static final String CONFIG_CLIENT_ID = "hal_assistant.google.client_id";
|
private static final String CONFIG_CLIENT_ID = "hal_assistant.google.client_id";
|
||||||
|
|
||||||
private SmartHomeImpl smartHome;
|
private SmartHomeImpl smartHome;
|
||||||
private OAuth2Registry oAuth2Registry;
|
private OAuth2Registry oAuth2Registry;
|
||||||
private HttpServer httpServer;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initiate(ScheduledExecutorService executor) {
|
public void initiate(ScheduledExecutorService executor) {
|
||||||
if (smartHome == null) {
|
if (smartHome == null) {
|
||||||
if (!HalContext.containsProperty(CONFIG_PORT) ||
|
if (!HalContext.containsProperty(CONFIG_CLIENT_ID)) {
|
||||||
!HalContext.containsProperty(CONFIG_CLIENT_ID)) {
|
logger.severe("Missing configuration, aborting initializations.");
|
||||||
logger.severe("Missing configuration, abort initializations.");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -65,11 +62,9 @@ public class SmartHomeDaemon implements HalDaemon {
|
||||||
oAuth2Registry.addWhitelist(HalContext.getStringProperty(CONFIG_CLIENT_ID));
|
oAuth2Registry.addWhitelist(HalContext.getStringProperty(CONFIG_CLIENT_ID));
|
||||||
oAuth2Registry.setTokenListener(smartHome);
|
oAuth2Registry.setTokenListener(smartHome);
|
||||||
|
|
||||||
httpServer = new HttpServer(HalContext.getIntegerProperty(CONFIG_PORT));
|
HalServer.registerExternalPage(ENDPOINT_AUTH, new OAuth2AuthorizationPage(oAuth2Registry));
|
||||||
httpServer.setPage(ENDPOINT_AUTH, new OAuth2AuthorizationPage(oAuth2Registry));
|
HalServer.registerExternalPage(ENDPOINT_TOKEN, new OAuth2TokenPage(oAuth2Registry));
|
||||||
httpServer.setPage(ENDPOINT_TOKEN, new OAuth2TokenPage(oAuth2Registry));
|
HalServer.registerExternalPage(ENDPOINT_SMARTHOME, new SmartHomePage(smartHome));
|
||||||
httpServer.setPage(ENDPOINT_SMARTHOME, new SmartHomePage(smartHome));
|
|
||||||
httpServer.start();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue