From 9e3e1edbaeb4182e58fd00b4f305c4101aaaca54 Mon Sep 17 00:00:00 2001 From: azikdev Date: Mon, 1 May 2023 19:55:58 +0500 Subject: [PATCH 1/5] feat: custom sms provider using config --- sydent/config/sms.py | 14 +++++++++++++- sydent/validators/msisdnvalidator.py | 5 ++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/sydent/config/sms.py b/sydent/config/sms.py index 404a10a8..4db71ee6 100644 --- a/sydent/config/sms.py +++ b/sydent/config/sms.py @@ -11,12 +11,14 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - +import configparser from configparser import ConfigParser from typing import Dict, List +import sydent.sms.openmarket from sydent.config._base import BaseConfig from sydent.config.exceptions import ConfigError +from pydoc import locate class SMSConfig(BaseConfig): @@ -33,6 +35,16 @@ def parse_config(self, cfg: "ConfigParser") -> bool: self.api_username = cfg.get("sms", "username").encode("UTF-8") self.api_password = cfg.get("sms", "password").encode("UTF-8") + self.provider_class = sydent.sms.openmarket.OpenMarketSMS + try: + sms_provider = cfg.get("sms", "provider") + except configparser.NoOptionError: + pass + else: + if sms_provider: + self.provider_class = locate(sms_provider) + assert self.provider_class is not None, "Invalid SMS provider class: %s" % sms_provider + self.originators: Dict[str, List[Dict[str, str]]] = {} self.smsRules = {} diff --git a/sydent/validators/msisdnvalidator.py b/sydent/validators/msisdnvalidator.py index 478298bd..70364009 100644 --- a/sydent/validators/msisdnvalidator.py +++ b/sydent/validators/msisdnvalidator.py @@ -19,7 +19,6 @@ import phonenumbers from sydent.db.valsession import ThreePidValSessionStore -from sydent.sms.openmarket import OpenMarketSMS from sydent.util import time_msec from sydent.validators import DestinationRejectedException, common @@ -32,7 +31,7 @@ class MsisdnValidator: def __init__(self, sydent: "Sydent") -> None: self.sydent = sydent - self.omSms = OpenMarketSMS(sydent) + self.Sms = sydent.config.sms.provider_class(sydent) # cache originators & sms rules from config file self.originators = self.sydent.config.sms.originators @@ -94,7 +93,7 @@ async def requestToken( smsBody = smsBodyTemplate.format(token=token_info.token) - await self.omSms.sendTextSMS(smsBody, msisdn, originator) + await self.Sms.sendTextSMS(smsBody, msisdn, originator) valSessionStore.setSendAttemptNumber(valSession.id, send_attempt) From 234063e166bc145902be7684457b7ccb12191ed7 Mon Sep 17 00:00:00 2001 From: azikdev Date: Tue, 2 May 2023 16:07:33 +0500 Subject: [PATCH 2/5] ref: remove dependency on pydoc --- sydent/config/sms.py | 5 ++--- sydent/util/loader.py | 13 +++++++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) create mode 100644 sydent/util/loader.py diff --git a/sydent/config/sms.py b/sydent/config/sms.py index 4db71ee6..7ca6d4b2 100644 --- a/sydent/config/sms.py +++ b/sydent/config/sms.py @@ -18,7 +18,7 @@ import sydent.sms.openmarket from sydent.config._base import BaseConfig from sydent.config.exceptions import ConfigError -from pydoc import locate +from sydent.util.loader import load_class class SMSConfig(BaseConfig): @@ -42,8 +42,7 @@ def parse_config(self, cfg: "ConfigParser") -> bool: pass else: if sms_provider: - self.provider_class = locate(sms_provider) - assert self.provider_class is not None, "Invalid SMS provider class: %s" % sms_provider + self.provider_class = load_class(sms_provider) self.originators: Dict[str, List[Dict[str, str]]] = {} self.smsRules = {} diff --git a/sydent/util/loader.py b/sydent/util/loader.py new file mode 100644 index 00000000..6defdb9a --- /dev/null +++ b/sydent/util/loader.py @@ -0,0 +1,13 @@ +import importlib +from typing import Type + +from sydent.config.exceptions import ConfigError + + +def load_class(full_path: str) -> Type: + try: + _module, class_name = full_path.rsplit(".", 1) + module = importlib.import_module(_module) + return getattr(module, class_name) + except (AttributeError, ModuleNotFoundError): + raise ConfigError("Cannot load: %s" % full_path) From 6b27800a4bea134b8b44d21c4efd9d66a058dbeb Mon Sep 17 00:00:00 2001 From: azikdev Date: Tue, 2 May 2023 16:47:10 +0500 Subject: [PATCH 3/5] feat: provider config --- sydent/config/sms.py | 1 + 1 file changed, 1 insertion(+) diff --git a/sydent/config/sms.py b/sydent/config/sms.py index 7ca6d4b2..6a0b2247 100644 --- a/sydent/config/sms.py +++ b/sydent/config/sms.py @@ -43,6 +43,7 @@ def parse_config(self, cfg: "ConfigParser") -> bool: else: if sms_provider: self.provider_class = load_class(sms_provider) + self.provider_config = self.provider_class.parse_config(cfg.get("sms", "provider_config")) self.originators: Dict[str, List[Dict[str, str]]] = {} self.smsRules = {} From 2f1e52778ea8f9648c0d6872cb177e79e95904b5 Mon Sep 17 00:00:00 2001 From: azikdev Date: Tue, 2 May 2023 16:52:53 +0500 Subject: [PATCH 4/5] feat: provider config --- sydent/config/sms.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sydent/config/sms.py b/sydent/config/sms.py index 6a0b2247..9a0df2f6 100644 --- a/sydent/config/sms.py +++ b/sydent/config/sms.py @@ -43,7 +43,10 @@ def parse_config(self, cfg: "ConfigParser") -> bool: else: if sms_provider: self.provider_class = load_class(sms_provider) - self.provider_config = self.provider_class.parse_config(cfg.get("sms", "provider_config")) + if self.provider_class != sydent.sms.openmarket.OpenMarketSMS: + self.provider_config = self.provider_class.parse_config( + cfg.get("sms", "provider_config", fallback={}) + ) self.originators: Dict[str, List[Dict[str, str]]] = {} self.smsRules = {} From 5886bf64235c9c2dc6f858b351b0876cb9186745 Mon Sep 17 00:00:00 2001 From: azikdev Date: Tue, 2 May 2023 16:56:13 +0500 Subject: [PATCH 5/5] feat: provider config --- sydent/config/sms.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/sydent/config/sms.py b/sydent/config/sms.py index 9a0df2f6..cde8b6fa 100644 --- a/sydent/config/sms.py +++ b/sydent/config/sms.py @@ -43,10 +43,7 @@ def parse_config(self, cfg: "ConfigParser") -> bool: else: if sms_provider: self.provider_class = load_class(sms_provider) - if self.provider_class != sydent.sms.openmarket.OpenMarketSMS: - self.provider_config = self.provider_class.parse_config( - cfg.get("sms", "provider_config", fallback={}) - ) + self.provider_config = cfg.get("sms", "provider_config", fallback={}) self.originators: Dict[str, List[Dict[str, str]]] = {} self.smsRules = {}