From ba4af36df0a5ee84cbfaf6ef6fbea46bc28a31f1 Mon Sep 17 00:00:00 2001 From: lukas Date: Thu, 7 May 2020 14:54:40 +0200 Subject: [PATCH] * new class for IP utils * method to check telegram support out of config * getters in Config.cpp * lots of reformatings and cdoc --- CMakeLists.txt | 3 +- inc/Config.h | 77 ++++++++++++++++++++++++++++++++++------- inc/IPRefresher.h | 2 +- inc/IpHelper.h | 22 ++++++++++++ inc/api/API.h | 5 ++- inc/api/DynuAPI.h | 7 ++-- inc/api/IPAPI.h | 2 +- inc/api/TelegramAPI.h | 2 +- src/Config.cpp | 49 ++++++++++++++++++++++---- src/FileLogger.cpp | 6 ++-- src/IPRefresher.cpp | 19 +++++----- src/IpHelper.cpp | 11 ++++++ src/api/DynuAPI.cpp | 16 ++++----- src/api/IPAPI.cpp | 2 +- src/api/TelegramAPI.cpp | 2 +- src/main.cpp | 8 ++--- 16 files changed, 175 insertions(+), 58 deletions(-) create mode 100644 inc/IpHelper.h create mode 100644 src/IpHelper.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 4a2b241..9d3ddad 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -146,7 +146,8 @@ add_library(logger ${LIB_METHOD} SET(SOURCE src/main.cpp src/IPRefresher.cpp - src/Config.cpp) + src/Config.cpp + src/IpHelper.cpp) add_executable(iprefresher ${SOURCE}) diff --git a/inc/Config.h b/inc/Config.h index 1107e14..2c6c835 100644 --- a/inc/Config.h +++ b/inc/Config.h @@ -6,22 +6,17 @@ #include +/** + * A static class to manage the configuration file, read/write parameters to it. + */ class Config { public: - static std::string dynuapikey; - - static std::string domainid; //id of the dynu domain - static std::string domainname; - - static std::string telegramApiKey; - static std::string chatId; - /** - * read configuration out of config file - * - * @return success of config read - */ - static bool readCredentials(); + * read configuration out of config file + * + * @return success of config read + */ + static bool readConfig(); /** * validate config file @@ -30,5 +25,61 @@ public: */ static bool validateConfig(); + /** + * check if telegram credentials in config are set + * @return is supported? + */ + static bool isTelegramSupported(); + + /** Getters **/ + + /** + * encapsulated getter for DynuApiKey + * @return api key + */ + static const std::string &getDynuapikey(); + + /** + * encapsulated getter for DomainId + * @return DomainId + */ + static const std::string &getDomainid(); + + /** + * encapsulated getter for Domainname + * @return Domainname + */ + static const std::string &getDomainname(); + + /** + * encapsulated getter for TelegramApiKey + * @return TelegramApiKey + */ + static const std::string &getTelegramApiKey(); + + /** + * encapsulated getter for ChatId + * @return ChatId + */ + static const std::string &getChatId(); + + private: + /** + * private constructor --> don't allow instance of this class + */ + Config(); + + /** + * helper variable for managing telegram Support + */ + static bool telegramSupport; + + static std::string dynuapikey; + + static std::string domainid; //id of the dynu domain + static std::string domainname; + + static std::string telegramApiKey; + static std::string chatId; }; \ No newline at end of file diff --git a/inc/IPRefresher.h b/inc/IPRefresher.h index 7220adf..a930ffe 100644 --- a/inc/IPRefresher.h +++ b/inc/IPRefresher.h @@ -14,7 +14,7 @@ public: /** * default constructor */ - IPRefresher(); + IPRefresher() = default; /** * start the service in loop mode diff --git a/inc/IpHelper.h b/inc/IpHelper.h new file mode 100644 index 0000000..d239463 --- /dev/null +++ b/inc/IpHelper.h @@ -0,0 +1,22 @@ +// +// Created by lukas on 07.05.20. +// + +#pragma once + +#include + +/** + * General helper class for IP actions + */ +class IpHelper { +public: + /** + * check if ip is valid + * @param ip ip address to test + * @return validity + */ + static bool isIpValid(std::string ip); + +private: +}; diff --git a/inc/api/API.h b/inc/api/API.h index d2f4f75..9ac9edb 100644 --- a/inc/api/API.h +++ b/inc/api/API.h @@ -25,7 +25,10 @@ public: * @param headers header fields * @return return string of server */ - std::string request(std::string myurl, bool post, Hashmap &map, std::vector &headers); + std::string request(std::string myurl, + bool post, + Hashmap &map, + std::vector &headers); private: static size_t write_data(void *buffer, size_t size, size_t buffersize, FILE *stream); diff --git a/inc/api/DynuAPI.h b/inc/api/DynuAPI.h index 3d169fc..77c891c 100644 --- a/inc/api/DynuAPI.h +++ b/inc/api/DynuAPI.h @@ -6,14 +6,14 @@ #include "API.h" -class DynuAPI : API{ +class DynuAPI : API { public: /** * refresh the ip of domain on Dynu server * @param ip new ip * @return request status */ - int refreshIp(std::string ip); + bool refreshIp(std::string ip); /** * init Telegram api with apikey and chatid @@ -21,7 +21,8 @@ public: * @param domainId ID of domain received by Dynu * @param domainName domainname to refresh */ - void init(const std::string& dynuApiKey, const std::string& domainId, const std::string& domainName); + void init(const std::string &dynuApiKey, const std::string &domainId, const std::string &domainName); + private: std::string dynuapikey; // Dynu API key diff --git a/inc/api/IPAPI.h b/inc/api/IPAPI.h index ed67133..c442b4b 100644 --- a/inc/api/IPAPI.h +++ b/inc/api/IPAPI.h @@ -8,7 +8,7 @@ #include -class IPAPI : API{ +class IPAPI : API { public: /** * get global ip of current internet connection diff --git a/inc/api/TelegramAPI.h b/inc/api/TelegramAPI.h index 676cfd5..c28aa85 100644 --- a/inc/api/TelegramAPI.h +++ b/inc/api/TelegramAPI.h @@ -14,7 +14,7 @@ public: * send telegram Message to predefined destination * @param text message */ - int sendMessage(const std::string& text); + int sendMessage(const std::string &text); /** * init Telegram api with apikey and chatid diff --git a/src/Config.cpp b/src/Config.cpp index 50052ac..849be48 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -18,10 +18,11 @@ std::string Config::domainname; std::string Config::telegramApiKey; std::string Config::chatId; -bool Config::readCredentials() { +bool Config::telegramSupport; + +bool Config::readConfig() { libconfig::Config cfg; try { - // todo make dynamic here cfg.readFile(Version::ConfigDir.c_str()); } catch (const libconfig::FileIOException &fioex) { @@ -33,7 +34,7 @@ bool Config::readCredentials() { myfile << Version::SAMPLECONFIG; myfile.close(); } else { - std::cout << "error creating file" << std::endl; + Logger::error("error creating file"); } return false; @@ -52,11 +53,15 @@ bool Config::readCredentials() { // optional parameters telegramApiKey = (std::string) cfg.lookup("telegramApiKey"); chatId = (std::string) cfg.lookup("chatId"); + telegramSupport = true; } catch (const libconfig::SettingNotFoundException &nfex) { // triggered if setting is missing in config if (!(std::strcmp("telegramApiKey", nfex.getPath()) == 0 || std::strcmp("chatId", nfex.getPath()) == 0)) { std::cerr << "No '" << nfex.getPath() << "' setting in configuration file." << std::endl; + } else { + Logger::message("no Telegram support - fields in config not set"); + telegramSupport = false; } } // check if needed values aren't empty @@ -83,27 +88,57 @@ bool Config::validateConfig() { try { // needed parameters if (((std::string) cfg.lookup("dynuapikey")).empty()) { - Logger::warning("required parameter dynuapikey seems to be empty."); + Logger::warning("required parameter \"dynuapikey\" seems to be empty."); return false; } if (((std::string) cfg.lookup("domainid")).empty()) { - Logger::warning("required parameter domainid seems to be empty."); + Logger::warning("required parameter \"domainid\" seems to be empty."); return false; } if (((std::string) cfg.lookup("domainname")).empty()) { - Logger::warning("required parameter domainname seems to be empty."); + Logger::warning("required parameter \"domainname\" seems to be empty."); return false; } // optional parameters cfg.lookup("telegramApiKey"); cfg.lookup("chatId"); + telegramSupport = true; } catch (const libconfig::SettingNotFoundException &nfex) { // triggered if setting is missing in config if (!(std::strcmp("telegramApiKey", nfex.getPath()) == 0 || std::strcmp("chatId", nfex.getPath()) == 0)) { std::cerr << "No '" << nfex.getPath() << "' setting in configuration file." << std::endl; return false; + } else { + Logger::message("no Telegram support - fields in config not set"); + telegramSupport = false; } } return true; -} \ No newline at end of file +} + +bool Config::isTelegramSupported() { + return telegramSupport; +} + +const std::string &Config::getDynuapikey() { + return dynuapikey; +} + +const std::string &Config::getDomainid() { + return domainid; +} + +const std::string &Config::getDomainname() { + return domainname; +} + +const std::string &Config::getTelegramApiKey() { + return telegramApiKey; +} + +const std::string &Config::getChatId() { + return chatId; +} + +Config::Config() = default; diff --git a/src/FileLogger.cpp b/src/FileLogger.cpp index 4468e09..aa0f450 100644 --- a/src/FileLogger.cpp +++ b/src/FileLogger.cpp @@ -3,10 +3,10 @@ // #include "FileLogger.h" +#include "IpHelper.h" #include #include -#include void FileLogger::safeip(std::string ip) { std::ofstream out; @@ -25,8 +25,8 @@ std::string FileLogger::readip() { in >> ip; - // when received ip has no : return 0.0.0.0 - if (ip.find(':') == ULONG_MAX) + // when received ip has no . return 0.0.0.0 + if (!IpHelper::isIpValid(ip)) return "0.0.0.0"; else return ip; diff --git a/src/IPRefresher.cpp b/src/IPRefresher.cpp index 41347f3..34c9ec1 100644 --- a/src/IPRefresher.cpp +++ b/src/IPRefresher.cpp @@ -9,12 +9,11 @@ #include "api/TelegramAPI.h" #include "Config.h" #include "Version.h" +#include "IpHelper.h" -#include #include #include #include -#include void IPRefresher::checkIPAdress(bool force) { FileLogger logger; @@ -25,7 +24,7 @@ void IPRefresher::checkIPAdress(bool force) { if (ip.empty()) { //no internet connection (or other error) Logger::warning("no internet connection"); - } else if (ip.find(':') == ULONG_MAX) { + } else if (!IpHelper::isIpValid(ip)) { // error when ip doesn't contain a : Logger::warning("an error occured when getting the global ip"); } else { @@ -37,13 +36,15 @@ void IPRefresher::checkIPAdress(bool force) { Logger::message("ip changed! -- from :" + oldip + "to: " + ip); DynuAPI dynu; - dynu.init(Config::dynuapikey, Config::domainid, Config::domainname); + dynu.init(Config::getDynuapikey(), Config::getDomainid(), Config::getDomainname()); + // actual refresh of IP in api - here + bool result = dynu.refreshIp(ip); - if (dynu.refreshIp(ip)) { + if (result && Config::isTelegramSupported()) { TelegramAPI tele; - tele.init(Config::telegramApiKey, Config::chatId); + tele.init(Config::getTelegramApiKey(), Config::getChatId()); tele.sendMessage(oldip + " moved to " + ip); - } else { + } else if (!result) { //error Logger::error("failed to write ip to dynu api!"); } @@ -53,13 +54,11 @@ void IPRefresher::checkIPAdress(bool force) { } } -IPRefresher::IPRefresher() = default; - IPRefresher::IPRefresher(bool loop) { if (loop) { Logger::message("startup of service"); Logger::message("Version: " + Version::VERSION); - if (Config::readCredentials()) { + if (Config::readConfig()) { while (true) { Logger::message("starting check"); checkIPAdress(false); diff --git a/src/IpHelper.cpp b/src/IpHelper.cpp new file mode 100644 index 0000000..4a5c40a --- /dev/null +++ b/src/IpHelper.cpp @@ -0,0 +1,11 @@ +// +// Created by lukas on 07.05.20. +// + +#include "IpHelper.h" + +#include + +bool IpHelper::isIpValid(std::string ip) { + return (ip.find('.') != ULONG_MAX); +} diff --git a/src/api/DynuAPI.cpp b/src/api/DynuAPI.cpp index e91bad4..b711600 100644 --- a/src/api/DynuAPI.cpp +++ b/src/api/DynuAPI.cpp @@ -4,7 +4,7 @@ #include "api/DynuAPI.h" -int DynuAPI::refreshIp(std:: string ip) { +bool DynuAPI::refreshIp(std::string ip) { Hashmap args; args.add("name", domainname); args.add("ipv4Address", ip); @@ -16,15 +16,11 @@ int DynuAPI::refreshIp(std:: string ip) { const std::string dynurepl = request("https://api.dynu.com/v2/dns/" + domainid, true, args, headers); - if (dynurepl != "{\"statusCode\":200}") { - return -1; - } else { - return 1; - } + return (dynurepl == "{\"statusCode\":200}"); } -void DynuAPI::init(const std::string& dynuApiKey, const std::string& domainId, const std::string& domainName) { - this->dynuapikey=dynuApiKey; - this->domainid=domainId; - this->domainname=domainName; +void DynuAPI::init(const std::string &dynuApiKey, const std::string &domainId, const std::string &domainName) { + this->dynuapikey = dynuApiKey; + this->domainid = domainId; + this->domainname = domainName; } diff --git a/src/api/IPAPI.cpp b/src/api/IPAPI.cpp index f2c9ca5..4bde56c 100644 --- a/src/api/IPAPI.cpp +++ b/src/api/IPAPI.cpp @@ -6,4 +6,4 @@ std::string IPAPI::getGlobalIp() { return request("https://api.ipify.org"); -} +} \ No newline at end of file diff --git a/src/api/TelegramAPI.cpp b/src/api/TelegramAPI.cpp index 0c26a34..1967c82 100644 --- a/src/api/TelegramAPI.cpp +++ b/src/api/TelegramAPI.cpp @@ -7,7 +7,7 @@ #include -int TelegramAPI::sendMessage(const std::string& text) { +int TelegramAPI::sendMessage(const std::string &text) { Hashmap args; args.add("chat_id", chatid); args.add("text", text); diff --git a/src/main.cpp b/src/main.cpp index 141e5f5..0bbd879 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -8,8 +8,6 @@ #include "Config.h" #include "api/IPAPI.h" -#include - /** * application entry point */ @@ -28,7 +26,7 @@ int main(int argc, char *argv[]) { std::cout << "Version " << Version::VERSION << std::endl; } else if (firstarg == "-f" || firstarg == "--force") { IPRefresher ipr; - if (Config::readCredentials()) { + if (Config::readConfig()) { ipr.checkIPAdress(true); } else { std::cout << "incorrect credentials!" << std::endl; @@ -40,7 +38,7 @@ int main(int argc, char *argv[]) { if (Config::validateConfig()) { Logger::message("Config file is OK"); } else { - Logger::warning("There are errors in config file!"); + Logger::error("There are errors in config file!"); return -1; } } else if (firstarg == "-ip" || firstarg == "--currentip") { @@ -52,7 +50,7 @@ int main(int argc, char *argv[]) { } else { IPRefresher ipr; Logger::message("starting check"); - if (Config::readCredentials()) { + if (Config::readConfig()) { ipr.checkIPAdress(false); } else { std::cout << "incorrect credentials!" << std::endl;