Fixed OTP recognition

Added balance check to SMS providers
This commit is contained in:
Kumi 2020-05-23 11:12:48 +02:00
parent 6a1b3843df
commit f4aab6ee57
13 changed files with 109 additions and 15 deletions

View file

@ -21,7 +21,11 @@ class BaseSMSProvider:
@property @property
def get_edit_url(self): def get_edit_url(self):
return return False
@property
def get_balance(self):
return False
def sendSMS(self, recipients: Union[str, list], message: str): def sendSMS(self, recipients: Union[str, list], message: str):
'''Send an SMS message to one or more recipients '''Send an SMS message to one or more recipients

View file

@ -18,20 +18,21 @@ for module in settings.EXPEPHALON_MODULES:
except (AttributeError, ModuleNotFoundError): except (AttributeError, ModuleNotFoundError):
continue continue
def get_sms_provider_by_name(name): def get_sms_provider_by_name(name, active=False):
for provider in providers: for provider in providers:
if provider.name == name: if provider.get_name == name and (provider.is_active or not active):
return provider return provider
def get_default_sms_provider_name(): def get_default_sms_provider_name():
return getValue("core.sms.default", False) return getValue("core.sms.default", False)
def get_default_sms_provider(): def get_default_sms_provider():
name = get_default_sms_provider_name() provider = get_sms_provider_by_name(get_default_sms_provider_name(), True)
if name: if provider:
for provider in providers: return provider
if provider.name == name and provider.is_active:
return provider
for provider in providers: for provider in providers:
if provider.is_active: if provider.is_active:
return provider return provider
raise RuntimeError("No SMS provider is currently active")

0
kumisms/__init__.py Normal file
View file

3
kumisms/admin.py Normal file
View file

@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

5
kumisms/apps.py Normal file
View file

@ -0,0 +1,5 @@
from django.apps import AppConfig
class KumismsConfig(AppConfig):
name = 'kumisms'

3
kumisms/models.py Normal file
View file

@ -0,0 +1,3 @@
from django.db import models
# Create your models here.

70
kumisms/sms.py Normal file
View file

@ -0,0 +1,70 @@
from core.classes.sms import BaseSMSProvider, SMSNotSent
from dbsettings.functions import getValue
from urllib.parse import urlencode
from urllib.request import urlopen, Request
from typing import Union
import json
# Create your models here.
class KumiSMSServer(BaseSMSProvider):
@property
def is_active(self):
return bool(self.get_balance)
@property
def get_name(self):
return "Kumi SMS"
@property
def get_key(self):
return getValue("kumisms.apikey")
@staticmethod
def getError(status):
if "error" in status.keys():
return status["error"]
def sendSMS(self, recipients: Union[str, list], message: str):
'''Send an SMS message to one or more recipients
:param recipients: Recipient phone number as a string, or a list of multiple phone number strings
:param message: Message to be sent as a string
'''
if isinstance(recipients, str):
recipients = [recipients]
url = 'https://kumisms.com/api/v1/send/'
for recipient in recipients:
vars = {"key": self.get_key, "text": message, "recipient": recipient}
request = Request(url, urlencode(vars).encode())
response = urlopen(request)
status = json.loads(response.read().decode())
error = KumiSMSServer.getError(status)
if error:
raise SMSNotSent(f'An error occurred trying to send the SMS: {error}')
@property
def get_balance(self):
url = 'https://kumisms.com/api/v1/balance/'
vars = {"key": self.get_key}
request = Request(url, urlencode(vars).encode())
response = urlopen(request)
status = json.loads(response.read().decode())
if not KumiSMSServer.getError(status):
return status["balance"]
SMSPROVIDERS = [KumiSMSServer()]

3
kumisms/tests.py Normal file
View file

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

3
kumisms/views.py Normal file
View file

@ -0,0 +1,3 @@
from django.shortcuts import render
# Create your views here.

View file

@ -12,7 +12,7 @@ import json
# Create your models here. # Create your models here.
class PlaySMSServer(Model, BaseSMSProvider): class PlaySMSServer(Model, BaseSMSProvider):
name = CharField(max_length=255) name = CharField(max_length=255, unique=True)
logo = CharField(max_length=255) logo = CharField(max_length=255)
https = BooleanField(default=True) https = BooleanField(default=True)
host = CharField(max_length=255) host = CharField(max_length=255)
@ -23,6 +23,10 @@ class PlaySMSServer(Model, BaseSMSProvider):
def is_active(self): def is_active(self):
return True return True
@property
def get_name(self):
return self.name
@staticmethod @staticmethod
def getError(status): def getError(status):
if status["error_string"]: if status["error_string"]:
@ -45,11 +49,9 @@ class PlaySMSServer(Model, BaseSMSProvider):
url = 'http%s://%s/index.php?app=ws&u=%s&h=%s&op=pv&to=%s&msg=%s' % ("s" if self.https else "", self.host, self.username, self.token, recipients, quote_plus(message)) url = 'http%s://%s/index.php?app=ws&u=%s&h=%s&op=pv&to=%s&msg=%s' % ("s" if self.https else "", self.host, self.username, self.token, recipients, quote_plus(message))
print(url)
response = urlopen(url) response = urlopen(url)
status = json.loads(response.read().decode()) status = json.loads(response.read().decode())
print(status)
error = PlaySMSServer.getError(status) error = PlaySMSServer.getError(status)

View file

@ -23,4 +23,4 @@ class OTPToken(Model):
provider = get_default_sms_provider() provider = get_default_sms_provider()
provider.sendSMS(number, text) provider.sendSMS(str(number), text)

View file

@ -4,7 +4,7 @@
<div class="mx-auto app-login-box col-sm-12 col-md-10 col-lg-9"> <div class="mx-auto app-login-box col-sm-12 col-md-10 col-lg-9">
<div class="app-logo"></div> <div class="app-logo"></div>
<h4 class="mb-0"> <h4 class="mb-0">
<span class="d-block">Welcome back,</span> <span class="d-block">Welcome back {{ request.user.first_name }},</span>
<span>Please select your Two-Factor Authentication provider</span></h4> <span>Please select your Two-Factor Authentication provider</span></h4>
{% bootstrap_messages %} {% bootstrap_messages %}
<div class="divider row"></div> <div class="divider row"></div>

View file

@ -4,7 +4,7 @@
<div class="mx-auto app-login-box col-sm-12 col-md-10 col-lg-9"> <div class="mx-auto app-login-box col-sm-12 col-md-10 col-lg-9">
<div class="app-logo"></div> <div class="app-logo"></div>
<h4 class="mb-0"> <h4 class="mb-0">
<span class="d-block">Welcome back,</span> <span class="d-block">Welcome back {{ request.user.first_name }},</span>
<span>Please enter your OTP Token</span></h4> <span>Please enter your OTP Token</span></h4>
{% bootstrap_messages %} {% bootstrap_messages %}
<div class="divider row"></div> <div class="divider row"></div>