mirror of
https://github.com/Telecominfraproject/wlan-cloud-ucentralsec.git
synced 2026-01-27 02:23:03 +00:00
Adding Twilio SMS support. Refactored for multiple SMS providers.
This commit is contained in:
@@ -79,7 +79,7 @@ add_executable( owsec
|
||||
src/RESTAPI_GenericServer.h src/RESTAPI_GenericServer.cpp
|
||||
src/RESTAPI_errors.h
|
||||
src/Storage.h
|
||||
src/SMSSender.cpp src/SMSSender.h src/RESTAPI_sms_handler.cpp src/RESTAPI_sms_handler.h src/MFAServer.cpp src/MFAServer.h)
|
||||
src/SMSSender.cpp src/SMSSender.h src/RESTAPI_sms_handler.cpp src/RESTAPI_sms_handler.h src/MFAServer.cpp src/MFAServer.h src/SMS_provider_aws.cpp src/SMS_provider_aws.h src/SMS_provider.cpp src/SMS_provider.h src/SMS_provider_twilio.cpp src/SMS_provider_twilio.h)
|
||||
|
||||
if(NOT SMALL_BUILD)
|
||||
target_link_libraries(owsec PUBLIC
|
||||
|
||||
@@ -10,25 +10,20 @@
|
||||
#include <aws/sns/model/GetSMSAttributesRequest.h>
|
||||
#include "MFAServer.h"
|
||||
|
||||
#include "SMS_provider_aws.h"
|
||||
#include "SMS_provider_twilio.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class SMSSender * SMSSender::instance_ = nullptr;
|
||||
|
||||
int SMSSender::Start() {
|
||||
Provider_ = Daemon()->ConfigGetString("sms.provider","aws");
|
||||
if(Provider_=="aws") {
|
||||
SecretKey_ = Daemon()->ConfigGetString("smssender.aws.secretkey","");
|
||||
AccessKey_ = Daemon()->ConfigGetString("smssender.aws.accesskey","");
|
||||
Region_ = Daemon()->ConfigGetString("smssender.aws.region","");
|
||||
|
||||
if(SecretKey_.empty() || AccessKey_.empty() || Region_.empty()) {
|
||||
Logger_.debug("SMSSender is disabled. Please provide key, secret, and region.");
|
||||
return -1;
|
||||
}
|
||||
Enabled_=true;
|
||||
AwsConfig_.region = Region_;
|
||||
AwsCreds_.SetAWSAccessKeyId(AccessKey_.c_str());
|
||||
AwsCreds_.SetAWSSecretKey(SecretKey_.c_str());
|
||||
ProviderImpl_ = std::make_unique<SMS_provider_aws>(Logger_);
|
||||
} else if(Provider_=="twilio") {
|
||||
ProviderImpl_ = std::make_unique<SMS_provider_twilio>(Logger_);
|
||||
}
|
||||
Enabled_ = ProviderImpl_->Initialize();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -52,7 +47,7 @@ namespace OpenWifi {
|
||||
auto Challenge = MFAServer::MakeChallenge();
|
||||
Cache_.emplace_back(SMSValidationCacheEntry{.Number=Number, .Code=Challenge, .UserName=UserName, .Created=Now});
|
||||
std::string Message = "Please enter the following code on your login screen: " + Challenge;
|
||||
return Send(Number, Message);
|
||||
return ProviderImpl_->Send(Number, Message);
|
||||
}
|
||||
|
||||
bool SMSSender::IsNumberValid(const std::string &Number, const std::string &UserName) {
|
||||
@@ -77,30 +72,11 @@ namespace OpenWifi {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SMSSender::SendAWS(const std::string &PhoneNumber, const std::string &Message) {
|
||||
Aws::SNS::SNSClient sns(AwsCreds_,AwsConfig_);
|
||||
|
||||
Aws::SNS::Model::PublishRequest psms_req;
|
||||
psms_req.SetMessage(Message.c_str());
|
||||
psms_req.SetPhoneNumber(PhoneNumber.c_str());
|
||||
|
||||
auto psms_out = sns.Publish(psms_req);
|
||||
if (psms_out.IsSuccess()) {
|
||||
Logger_.debug(Poco::format("SMS sent to %s",PhoneNumber));
|
||||
return true;
|
||||
}
|
||||
std::string ErrMsg = psms_out.GetError().GetMessage().c_str();
|
||||
Logger_.debug(Poco::format("SMS NOT sent to %s: %s",PhoneNumber, ErrMsg));
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SMSSender::Send(const std::string &PhoneNumber, const std::string &Message) {
|
||||
if(!Enabled_) {
|
||||
Logger_.information("SMS has not been enabled. Messages cannot be sent.");
|
||||
return false;
|
||||
}
|
||||
if(Provider_=="aws")
|
||||
return SendAWS(PhoneNumber, Message);
|
||||
return false;
|
||||
return ProviderImpl_->Send(PhoneNumber,Message);
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <aws/core/Aws.h>
|
||||
#include <aws/s3/S3Client.h>
|
||||
#include <aws/core/auth/AWSCredentials.h>
|
||||
#include "SMS_provider.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
@@ -38,14 +39,10 @@ namespace OpenWifi {
|
||||
[[nodiscard]] bool Send(const std::string &PhoneNumber, const std::string &Message);
|
||||
private:
|
||||
static SMSSender * instance_;
|
||||
std::string SecretKey_;
|
||||
std::string AccessKey_;
|
||||
std::string Region_;
|
||||
std::string Provider_;
|
||||
Aws::Client::ClientConfiguration AwsConfig_;
|
||||
Aws::Auth::AWSCredentials AwsCreds_;
|
||||
bool Enabled_=false;
|
||||
std::vector<SMSValidationCacheEntry> Cache_;
|
||||
std::unique_ptr<SMS_provider> ProviderImpl_;
|
||||
|
||||
SMSSender() noexcept:
|
||||
SubSystemServer("SMSSender", "SMS-SVR", "smssender.aws")
|
||||
|
||||
5
src/SMS_provider.cpp
Normal file
5
src/SMS_provider.cpp
Normal file
@@ -0,0 +1,5 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-10-15.
|
||||
//
|
||||
|
||||
#include "SMS_provider.h"
|
||||
24
src/SMS_provider.h
Normal file
24
src/SMS_provider.h
Normal file
@@ -0,0 +1,24 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-10-15.
|
||||
//
|
||||
|
||||
#ifndef OWSEC_SMS_PROVIDER_H
|
||||
#define OWSEC_SMS_PROVIDER_H
|
||||
|
||||
#include "Poco/Logger.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class SMS_provider {
|
||||
public:
|
||||
virtual bool Initialize() = 0 ;
|
||||
virtual bool Start() = 0 ;
|
||||
virtual bool Stop() = 0 ;
|
||||
virtual bool Running() = 0 ;
|
||||
virtual bool Send(const std::string &Number, const std::string &Message) = 0;
|
||||
virtual ~SMS_provider() {};
|
||||
private:
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif //OWSEC_SMS_PROVIDER_H
|
||||
60
src/SMS_provider_aws.cpp
Normal file
60
src/SMS_provider_aws.cpp
Normal file
@@ -0,0 +1,60 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-10-15.
|
||||
//
|
||||
|
||||
#include "SMS_provider_aws.h"
|
||||
#include "Daemon.h"
|
||||
|
||||
#include <aws/sns/SNSClient.h>
|
||||
#include <aws/sns/model/PublishRequest.h>
|
||||
#include <aws/sns/model/PublishResult.h>
|
||||
|
||||
namespace OpenWifi {
|
||||
bool SMS_provider_aws::Initialize() {
|
||||
SecretKey_ = Daemon()->ConfigGetString("smssender.aws.secretkey","");
|
||||
AccessKey_ = Daemon()->ConfigGetString("smssender.aws.accesskey","");
|
||||
Region_ = Daemon()->ConfigGetString("smssender.aws.region","");
|
||||
|
||||
if(SecretKey_.empty() || AccessKey_.empty() || Region_.empty()) {
|
||||
Logger_.debug("SMSSender is disabled. Please provide key, secret, and region.");
|
||||
return false;
|
||||
}
|
||||
Running_=true;
|
||||
AwsConfig_.region = Region_;
|
||||
AwsCreds_.SetAWSAccessKeyId(AccessKey_.c_str());
|
||||
AwsCreds_.SetAWSSecretKey(SecretKey_.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SMS_provider_aws::Start() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SMS_provider_aws::Stop() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SMS_provider_aws::Running() {
|
||||
return Running_;
|
||||
}
|
||||
|
||||
bool SMS_provider_aws::Send(const std::string &PhoneNumber, const std::string &Message) {
|
||||
if(!Running_)
|
||||
return false;
|
||||
|
||||
Aws::SNS::SNSClient sns(AwsCreds_,AwsConfig_);
|
||||
Aws::SNS::Model::PublishRequest psms_req;
|
||||
psms_req.SetMessage(Message.c_str());
|
||||
psms_req.SetPhoneNumber(PhoneNumber.c_str());
|
||||
|
||||
auto psms_out = sns.Publish(psms_req);
|
||||
if (psms_out.IsSuccess()) {
|
||||
Logger_.debug(Poco::format("SMS sent to %s",PhoneNumber));
|
||||
return true;
|
||||
}
|
||||
std::string ErrMsg{psms_out.GetError().GetMessage()};
|
||||
Logger_.debug(Poco::format("SMS NOT sent to %s: %s",PhoneNumber, ErrMsg));
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
34
src/SMS_provider_aws.h
Normal file
34
src/SMS_provider_aws.h
Normal file
@@ -0,0 +1,34 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-10-15.
|
||||
//
|
||||
|
||||
#ifndef OWSEC_SMS_PROVIDER_AWS_H
|
||||
#define OWSEC_SMS_PROVIDER_AWS_H
|
||||
|
||||
#include "SMS_provider.h"
|
||||
#include <aws/core/Aws.h>
|
||||
#include <aws/s3/S3Client.h>
|
||||
#include <aws/core/auth/AWSCredentials.h>
|
||||
|
||||
namespace OpenWifi {
|
||||
class SMS_provider_aws : public SMS_provider {
|
||||
public:
|
||||
explicit SMS_provider_aws(Poco::Logger &L) : Logger_(L) {}
|
||||
~SMS_provider_aws() {};
|
||||
bool Initialize() final ;
|
||||
bool Start() final ;
|
||||
bool Stop() final ;
|
||||
bool Send(const std::string &Number, const std::string &Message) final;
|
||||
bool Running() final;
|
||||
private:
|
||||
bool Running_=false;
|
||||
Poco::Logger &Logger_;
|
||||
std::string SecretKey_;
|
||||
std::string AccessKey_;
|
||||
std::string Region_;
|
||||
Aws::Client::ClientConfiguration AwsConfig_;
|
||||
Aws::Auth::AWSCredentials AwsCreds_;
|
||||
};
|
||||
}
|
||||
|
||||
#endif //OWSEC_SMS_PROVIDER_AWS_H
|
||||
76
src/SMS_provider_twilio.cpp
Normal file
76
src/SMS_provider_twilio.cpp
Normal file
@@ -0,0 +1,76 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-10-15.
|
||||
//
|
||||
|
||||
#include "SMS_provider_twilio.h"
|
||||
|
||||
#include "Daemon.h"
|
||||
#include "Poco/Net/HTTPBasicCredentials.h"
|
||||
#include "Poco/URI.h"
|
||||
#include "Poco/Net/HTMLForm.h"
|
||||
#include "Poco/Net/HTTPSClientSession.h"
|
||||
#include "Poco/Net/HTTPResponse.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
bool SMS_provider_twilio::Initialize() {
|
||||
Sid_ = Daemon()->ConfigGetString("smssender.twilio.sid","");
|
||||
Token_ = Daemon()->ConfigGetString("smssender.twilio.token","");
|
||||
PhoneNumber_ = Daemon()->ConfigGetString("smssender.twilio.phonenumber","");
|
||||
|
||||
if(Sid_.empty() || Token_.empty() || PhoneNumber_.empty()) {
|
||||
Logger_.debug("SMSSender is disabled. Please provide SID, TOKEN, and PHONE NUMBER.");
|
||||
return false;
|
||||
}
|
||||
Running_=true;
|
||||
Uri_ = "https://api.twilio.com/2010-04-01/Accounts/" + Sid_ + "/Messages.json";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SMS_provider_twilio::Start() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SMS_provider_twilio::Stop() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SMS_provider_twilio::Running() {
|
||||
return Running_;
|
||||
}
|
||||
|
||||
bool SMS_provider_twilio::Send(const std::string &PhoneNumber, const std::string &Message) {
|
||||
if(!Running_)
|
||||
return false;
|
||||
|
||||
Poco::Net::HTTPBasicCredentials Creds(Sid_,Token_);
|
||||
Poco::URI uri(Uri_);
|
||||
Poco::Net::HTMLForm form;
|
||||
|
||||
Poco::Net::HTTPSClientSession session(uri.getHost(), uri.getPort());
|
||||
Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_POST, uri.getPath(), Poco::Net::HTTPMessage::HTTP_1_1);
|
||||
Creds.authenticate(req);
|
||||
|
||||
Poco::JSON::Object RObj;
|
||||
|
||||
form.add("To",PhoneNumber);
|
||||
form.add("From",PhoneNumber_);
|
||||
form.add("Body","This is from twillio");
|
||||
|
||||
form.prepareSubmit(req);
|
||||
std::ostream& ostr = session.sendRequest(req);
|
||||
form.write(ostr);
|
||||
|
||||
Poco::Net::HTTPResponse res;
|
||||
std::istream& rs = session.receiveResponse(res);
|
||||
|
||||
if(res.getStatus()==Poco::Net::HTTPResponse::HTTP_OK) {
|
||||
Logger_.information(Poco::format("Message sent to %s", PhoneNumber));
|
||||
return true;
|
||||
} else {
|
||||
std::ostringstream os;
|
||||
Poco::StreamCopier::copyStream(rs,os);
|
||||
Logger_.information(Poco::format("Message was not to %s: Error:%s", PhoneNumber, os.str()));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
30
src/SMS_provider_twilio.h
Normal file
30
src/SMS_provider_twilio.h
Normal file
@@ -0,0 +1,30 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-10-15.
|
||||
//
|
||||
|
||||
#ifndef OWSEC_SMS_PROVIDER_TWILIO_H
|
||||
#define OWSEC_SMS_PROVIDER_TWILIO_H
|
||||
|
||||
#include "SMS_provider.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class SMS_provider_twilio : public SMS_provider {
|
||||
public:
|
||||
explicit SMS_provider_twilio(Poco::Logger &L) : Logger_(L) {}
|
||||
~SMS_provider_twilio() {};
|
||||
bool Initialize() final ;
|
||||
bool Start() final ;
|
||||
bool Stop() final ;
|
||||
bool Send(const std::string &Number, const std::string &Message) final;
|
||||
bool Running() final;
|
||||
private:
|
||||
bool Running_=false;
|
||||
Poco::Logger &Logger_;
|
||||
std::string Sid_;
|
||||
std::string Token_;
|
||||
std::string PhoneNumber_;
|
||||
std::string Uri_;
|
||||
};
|
||||
}
|
||||
|
||||
#endif //OWSEC_SMS_PROVIDER_TWILIO_H
|
||||
Reference in New Issue
Block a user