From 8a4fda127db7c4630f1a44330616f75f5760ae5a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Valentin=20Grou=C3=A8s?= <valentin.groues@uni.lu>
Date: Mon, 10 Jul 2017 09:20:38 +0200
Subject: [PATCH] add token verification via sms

---
 readme.md                              |  7 ++++++
 requirements.txt                       |  1 +
 smash/smash/local_settings.py.template |  4 +++
 smash/web/nexmo_gateway.py             | 34 ++++++++++++++++++++++++++
 smash/web/views/__init__.py            |  4 +--
 smash/web/views/auth.py                |  9 ++++---
 6 files changed, 54 insertions(+), 5 deletions(-)
 create mode 100644 smash/web/nexmo_gateway.py

diff --git a/readme.md b/readme.md
index ccf5b24c..22d11dd3 100644
--- a/readme.md
+++ b/readme.md
@@ -187,6 +187,13 @@ SHELL=/bin/bash
 
 ## Operations
 
+### Disable two steps authentication for a specific user
+
+
+```
+./manage.py two_factor_disable ${USERNAME}
+```
+
 ### Public holidays
 
 to import public holidays run:
diff --git a/requirements.txt b/requirements.txt
index 42af6653..e7d3b4c1 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -8,3 +8,4 @@ python-docx==0.8.6
 django-cleanup==0.4.2
 django_cron==0.5.0
 django-two-factor-auth==1.6.1
+nexmo==2.0.0-alpha1
\ No newline at end of file
diff --git a/smash/smash/local_settings.py.template b/smash/smash/local_settings.py.template
index a2411b28..bb8abb8c 100644
--- a/smash/smash/local_settings.py.template
+++ b/smash/smash/local_settings.py.template
@@ -39,3 +39,7 @@ STATIC_ROOT = '/tmp/static'  # Warning! `/tmp` directory can be flushed in any m
 MEDIA_ROOT = '/tmp/media'  # Warning! `/tmp` directory can be flushed in any moment; use a persistent one, e.g. ~/tmp/media
 
 STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.StaticFilesStorage'
+
+NEXMO_API_KEY = 'API_KEY'
+NEXMO_API_SECRET = 'API_SECRET'
+NEXMO_DEFAULT_FROM = 'Scheduling'  # the sender of the message (phone number or text)
diff --git a/smash/web/nexmo_gateway.py b/smash/web/nexmo_gateway.py
new file mode 100644
index 00000000..0515c732
--- /dev/null
+++ b/smash/web/nexmo_gateway.py
@@ -0,0 +1,34 @@
+import nexmo
+from django.conf import settings
+
+
+class Nexmo:
+    """
+    Gateway for sending text messages and making phone calls using Nexmo_.
+
+    All you need is your Nexmo Account API and Secret, as shown in your Nexmo
+    account dashboard.
+
+    ``NEXMO_API_KEY``
+      Should be set to your account's API Key.
+
+    ``NEXMO_API_SECRET``
+      Should be set to your account's secret.
+
+    ``NEXMO_DEFAULT_FROM``
+      Should be set to a phone number or name.
+
+    .. _Nexmo: http://www.nexmo.com/
+    """
+
+    def __init__(self):
+        self.client = nexmo.Client(key=getattr(settings, 'NEXMO_API_KEY'), secret=getattr(settings, 'NEXMO_API_SECRET'))
+        self.default_from = getattr(settings, 'NEXMO_DEFAULT_FROM')
+
+    def make_call(self, device, token):
+        pass
+
+    def send_sms(self, device, token):
+        body = 'Your authentication token is %s' % token
+        phone_number = device.number.as_e164
+        self.client.send_message({'to': phone_number, 'from': self.default_from, 'text': body})
diff --git a/smash/web/views/__init__.py b/smash/web/views/__init__.py
index 4322cb37..49fc1dce 100644
--- a/smash/web/views/__init__.py
+++ b/smash/web/views/__init__.py
@@ -1,5 +1,5 @@
 # coding=utf-8
-
+from django.conf import settings
 from django.contrib.auth.decorators import login_required
 from django.shortcuts import redirect, render
 from django.views.generic.base import ContextMixin
@@ -16,7 +16,7 @@ handler400 = 'web.views.e400_bad_request'
 def index(request):
     if request.user.is_authenticated():
         return redirect('web.views.appointments')
-    return redirect('web.views.login')
+    return redirect(getattr(settings, "LOGIN_URL"))
 
 
 def e404_page_not_found(request, context=None):
diff --git a/smash/web/views/auth.py b/smash/web/views/auth.py
index 2e095773..1a293f4a 100644
--- a/smash/web/views/auth.py
+++ b/smash/web/views/auth.py
@@ -1,8 +1,11 @@
 # coding=utf-8
+from django.conf import settings
 from django.shortcuts import redirect, render
 
 from ..auth import do_login, do_logout
 
+login_url = getattr(settings, "LOGIN_URL")
+
 
 def login(request):
     context = {
@@ -22,9 +25,9 @@ def login(request):
                 # FIXME: risk of phishing attacks
                 #  see https://www.owasp.org/index.php/Unvalidated_Redirects_and_Forwards_Cheat_Sheet
             else:
-                return redirect('web.views.appointments')
+                return redirect(login_url)
         else:
-            response = redirect('web.views.login')
+            response = redirect(login_url)
             response['Location'] += "?error={}".format(message)
             return response
     return render(request, "login.html", context)
@@ -32,6 +35,6 @@ def login(request):
 
 def logout(request):
     state, message = do_logout(request)
-    response = redirect('web.views.login')
+    response = redirect(login_url)
     response['Location'] += "?error={}".format(message)
     return response
-- 
GitLab