Base SMS integration

This commit is contained in:
Kumi 2021-05-26 14:07:52 +02:00
parent c75e3c56eb
commit 4edbf8a922
10 changed files with 105 additions and 3 deletions

View file

@ -3,6 +3,9 @@ from django.conf import settings
from geopy.geocoders import Nominatim
import uuid
import string
from random import SystemRandom
def name_to_coords(name):
geocoder = Nominatim(user_agent="JourneyJoker.at")
@ -15,4 +18,8 @@ def profile_to_coords(profile):
return name_to_coords("%s, %s, %s, %s" % (profile.street, profile.city, profile.zip, profile.country))
def upload_path(instance, filename):
return f'userfiles/{instance.user.id}/{uuid.uuid4()}/{filename}'
return f'userfiles/{instance.user.id}/{uuid.uuid4()}/{filename}'
def generate_token(length=6, characters=string.digits):
return "".join([SystemRandom().choice(characters) for _ in range(length)])

View file

@ -6,6 +6,7 @@ from django.utils import timezone
from django_countries.fields import CountryField
from phonenumber_field.modelfields import PhoneNumberField
from polymorphic.models import PolymorphicModel
from .helpers import profile_to_coords, upload_path
@ -62,6 +63,16 @@ class User(AbstractBaseUser):
has_module_perms = has_permission
has_perm = has_permission
@property
def phone(self):
try:
return self.clientprofile.phone
except:
try:
return self.partnerprofile.phone
except:
return None
class AddressMixin(models.Model):
street = models.CharField("Straße", max_length=64)
city = models.CharField("Stadt", max_length=64)
@ -110,7 +121,7 @@ class PersonMixin(models.Model):
abstract = True
class Profile(PersonMixin, AddressMixin, PhoneMixin):
user = models.OneToOneField(User, models.CASCADE)
user = models.OneToOneField(get_user_model(), models.CASCADE)
verified = models.BooleanField(default=False)
enabled = models.BooleanField(default=True)
@ -124,4 +135,17 @@ class Profile(PersonMixin, AddressMixin, PhoneMixin):
return name
class Meta:
abstract = True
abstract = True
class TwoFactor(PolymorphicModel):
user = models.ForeignKey(User, models.CASCADE)
@classmethod
def initiate(cls, user):
raise NotImplementedError("%s does not implement initiate()" % cls.__name__)
def send_token(self, description=""):
return True
def validate_token(self, token):
raise NotImplementedError("%s does not implement validate_token()" % cls.__name__)

View file

@ -19,4 +19,5 @@ staticmap
django-mathfilters
fast-luhn
kumisms
django-filtersignals
git+https://kumig.it/kumisystems/PyInvoice

0
sms/__init__.py Normal file
View file

3
sms/admin.py Normal file
View file

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

6
sms/apps.py Normal file
View file

@ -0,0 +1,6 @@
from django.apps import AppConfig
class SmsConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'sms'

14
sms/functions.py Normal file
View file

@ -0,0 +1,14 @@
import kumisms
from dbsettings.functions import getValue
def sendMessage(recipients: list, content: str, api_key=None):
api_key = api_key or getValue("kumisms.api.key")
gateway = kumisms.KumiSMS(api_key)
for recipient in recipients:
gateway.send(recipient, content)
def sendMessageToUsers(users: list, content: str, api_key=None):
recipients = [user.phone for user in users]
return sendMessage(recipients, content, api_key)

41
sms/models.py Normal file
View file

@ -0,0 +1,41 @@
from django.db import models
from django.utils import timezone
from datetime import timedelta
from localauth.models import TwoFactor
from localauth.helpers import generate_token
from dbsettings.functions import getValue
from .functions import sendMessage
class SMSTwoFactor(TwoFactor):
@classmethod
def initiate(cls, user):
if user.phone:
cls.objects.get_or_create(user=user)
def send_token(self, description="%s"):
token = SMSTwoFactorToken.objects.create(user=self)
sendMessageToUsers([user], description % token)
def validate_token(self, token):
tokens = SMSTwoFactorToken.objects.filter(
user=self,
token=token,
used=False,
created__gte=timezone.now() - timedelta(seconds=getValue("sms.token.maxage", 300))
).all()
if tokens:
tokens.update(used=True)
return True
return False
class SMSTwoFactorToken(models.Model):
user = models.ForeignKey(SMSTwoFactor, models.CASCADE)
token = models.CharField(max_length=256, default=generate_token)
created = models.DateTimeField(auto_now_add=True)
used = models.BooleanField(default=False)

3
sms/tests.py Normal file
View file

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

3
sms/views.py Normal file
View file

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