diff --git a/www/web/templates/two_factor/_base.html b/www/web/templates/two_factor/_base.html
new file mode 100644
index 0000000000000000000000000000000000000000..c4c0b0f2a5d27acad17254fe5b5d49d17b08ba08
--- /dev/null
+++ b/www/web/templates/two_factor/_base.html
@@ -0,0 +1,2 @@
+{% extends "base.html" %}
+{% load i18n %}
diff --git a/www/web/templates/two_factor/_wizard_forms.html b/www/web/templates/two_factor/_wizard_forms.html
new file mode 100644
index 0000000000000000000000000000000000000000..d4ebc122e173c0ad73ac3f3329cc488016ebaaaa
--- /dev/null
+++ b/www/web/templates/two_factor/_wizard_forms.html
@@ -0,0 +1,5 @@
+{% load bootstrap %}
+<table>
+  {{ wizard.management_form|bootstrap }}
+  {{ wizard.form|bootstrap}}
+</table>
\ No newline at end of file
diff --git a/www/web/templates/two_factor/core/login.html b/www/web/templates/two_factor/core/login.html
new file mode 100644
index 0000000000000000000000000000000000000000..736e633de8d937f555b55be16fe6125393d6d6ac
--- /dev/null
+++ b/www/web/templates/two_factor/core/login.html
@@ -0,0 +1,54 @@
+{% extends "two_factor/_base_focus.html" %}
+{% load i18n two_factor %}
+
+{% block content %}
+  <h1>{% block title %}{% trans "Login" %}{% endblock %}</h1>
+
+  {% if wizard.steps.current == 'auth' %}
+    <p>{% blocktrans %}Enter your credentials.{% endblocktrans %}</p>
+  {% elif wizard.steps.current == 'token' %}
+    {% if device.method == 'call' %}
+      <p>{% blocktrans %}We are calling your phone right now, please enter the
+        digits you hear.{% endblocktrans %}</p>
+    {% elif device.method == 'sms' %}
+      <p>{% blocktrans %}We sent you a text message, please enter the tokens we
+        sent.{% endblocktrans %}</p>
+    {% else %}
+      <p>{% blocktrans %}Please enter the tokens generated by your token
+        generator.{% endblocktrans %}</p>
+    {% endif %}
+  {% elif wizard.steps.current == 'backup' %}
+    <p>{% blocktrans %}Use this form for entering backup tokens for logging in.
+      These tokens have been generated for you to print and keep safe. Please
+      enter one of these backup tokens to login to your account.{% endblocktrans %}</p>
+  {% endif %}
+<div style="width:600px;">
+  <form action="" method="post">{% csrf_token %}
+    
+    {% include "two_factor/_wizard_forms.html" %}
+
+    {# hidden submit button to enable [enter] key #}
+    <div style="margin-left: -9999px"><input type="submit" value=""/></div>
+
+    {% if other_devices %}
+      <p>{% trans "Or, alternatively, use one of your backup phones:" %}</p>
+      <p>
+        {% for other in other_devices %}
+        <button name="challenge_device" value="{{ other.persistent_id }}"
+                class="btn btn-default btn-block" type="submit">
+          {{ other|device_action }}
+        </button>
+      {% endfor %}</p>
+    {% endif %}
+    {% if backup_tokens %}
+      <p>{% trans "As a last resort, you can use a backup token:" %}</p>
+      <p>
+        <button name="wizard_goto_step" type="submit" value="backup"
+                class="btn btn-default btn-block">{% trans "Use Backup Token" %}</button>
+      </p>
+    {% endif %}
+
+    {% include "two_factor/_wizard_actions.html" %}
+  </form>
+  </div>
+{% endblock %}
\ No newline at end of file
diff --git a/www/web/templates/two_factor/profile/disable.html b/www/web/templates/two_factor/profile/disable.html
new file mode 100644
index 0000000000000000000000000000000000000000..55c9ba8b799fd1f72321fbbfb1daa3b580d24873
--- /dev/null
+++ b/www/web/templates/two_factor/profile/disable.html
@@ -0,0 +1,14 @@
+{% extends "two_factor/_base_focus.html" %}
+{% load i18n %}
+{% load bootstrap %}
+{% block content %}
+  <h1>{% block title %}{% trans "Disable Two-factor Authentication" %}{% endblock %}</h1>
+  <p>{% blocktrans %}You are about to disable two-factor authentication. This
+    compromises your account security, are you sure?{% endblocktrans %}</p>
+  <form method="post">
+    {% csrf_token %}
+    <table>{{ form|bootstrap }}</table>
+    <button class="btn btn-danger"
+            type="submit">{% trans "Disable" %}</button>
+  </form>
+{% endblock %}
\ No newline at end of file
diff --git a/www/web/templates/two_factor/profile/profile.html b/www/web/templates/two_factor/profile/profile.html
new file mode 100644
index 0000000000000000000000000000000000000000..b5d59255409c4ae0b4a27cec6baee70bda911dad
--- /dev/null
+++ b/www/web/templates/two_factor/profile/profile.html
@@ -0,0 +1,42 @@
+{% extends "two_factor/_base.html" %}
+{% load i18n two_factor %}
+
+{% block content %}
+  <h1>{% block title %}{% trans "Account Security" %}{% endblock %}</h1>
+
+  {% if default_device %}
+    {% if default_device_type == 'TOTPDevice' %}
+      <p>{% trans "Tokens will be generated by your token generator." %}</p>
+    {% elif default_device_type == 'PhoneDevice' %}
+      <p>{% blocktrans with primary=default_device|device_action %}Primary method: {{ primary }}{% endblocktrans %}</p>
+    {% elif default_device_type == 'RemoteYubikeyDevice' %}
+      <p>{% blocktrans %}Tokens will be generated by your YubiKey.{% endblocktrans %}</p>
+    {% endif %}
+
+    <h2>{% trans "Backup Tokens" %}</h2>
+    <p>
+      {% blocktrans %}If you don't have any device with you, you can access
+        your account using backup tokens.{% endblocktrans %}
+      {% blocktrans count counter=backup_tokens %}
+        You have only one backup token remaining.
+      {% plural %}
+        You have {{ counter }} backup tokens remaining.
+      {% endblocktrans %}
+    </p>
+    <p><a href="{% url 'two_factor:backup_tokens' %}"
+          class="btn btn-info">{% trans "Show Codes" %}</a></p>
+
+    <h3>{% trans "Disable Two-Factor Authentication" %}</h3>
+    <p>{% blocktrans %}However we strongly discourage you to do so, you can
+      also disable two-factor authentication for your account.{% endblocktrans %}</p>
+    <p><a class="btn btn-default" href="{% url 'two_factor:disable' %}">
+      {% trans "Disable Two-Factor Authentication" %}</a></p>
+  {% else %}
+    <p>{% blocktrans %}Two-factor authentication is not enabled for your
+      account. Enable two-factor authentication for enhanced account
+      security.{% endblocktrans %}</p>
+    <p><a href="{% url 'two_factor:setup' %}" class="btn btn-primary">
+      {% trans "Enable Two-Factor Authentication" %}</a>
+    </p>
+  {% endif %}
+{% endblock %}
\ No newline at end of file
diff --git a/www/web/warpauth/templates/warpauth/profile.html b/www/web/warpauth/templates/warpauth/profile.html
index 7d35d14b6c49725e3e3cfc552d4da2fc15bb06ff..5235e4acd07a307cb4524984ed5f2960bdcc4a3f 100644
--- a/www/web/warpauth/templates/warpauth/profile.html
+++ b/www/web/warpauth/templates/warpauth/profile.html
@@ -15,6 +15,9 @@
         <li role="presentation">
             <a href="#change_passwd" aria-controls="change_passwd" role="tab" data-toggle="tab">{% trans "Change Password" %}</a>
         </li>
+        <li role="presentation">
+            <a href="/account/two_factor/">{% trans "Two Factor Authentication" %}</a>
+        </li>
     </ul>
 
     <div class="tab-content">
@@ -28,5 +31,6 @@
 </div>
 <script>
 $('a[href="{{ selected_tab }}"]').tab('show');
+
 </script>
 {% endblock %}
\ No newline at end of file
diff --git a/www/web/warpauth/urls.py b/www/web/warpauth/urls.py
index 1bec8cad1af8cb8bdb0f001a4e1ab77503667f19..2e38924105deaacac97628aa30395f110d255fdf 100644
--- a/www/web/warpauth/urls.py
+++ b/www/web/warpauth/urls.py
@@ -1,4 +1,4 @@
-from django.conf.urls import url
+from django.conf.urls import include, url
 from warpauth.views import login, reset_password, profile, register
 
 #
@@ -8,10 +8,10 @@ from warpauth.views import login, reset_password, profile, register
 
 urlpatterns = [
     # Authentication Pages
-    url(r'^login/$', login.login_view, name='index'),
-    url(r'^logout/$', login.logout_view, name='index'),
-    url(r'^register/$', register.register, name='index'),
-    url(r'^reset_password/$', reset_password.gen_token, name='index'),
+    url(r'', include('two_factor.urls', 'two_factor')),
+    url(r'^logout/$', login.logout_view, name='logout'),
+    url(r'^register/$', register.register, name='register'),
+    url(r'^reset_password/$', reset_password.gen_token, name='reset_password'),
 
     url(r'^reset_password/(?P<reset_hash>\w+)/$', reset_password.change_password, name='index'),
 
diff --git a/www/web/warpauth/views/login.py b/www/web/warpauth/views/login.py
index d084429cd70220f8fe3ae0192f15ba5bfa8f927c..c59977db8d57229e08abe4764ab7cb37069d8fbb 100644
--- a/www/web/warpauth/views/login.py
+++ b/www/web/warpauth/views/login.py
@@ -32,7 +32,7 @@ def login_view(request):
 
     return HttpResponse(render(request, 'warpauth/login.html', pages))
 
-@login_required(login_url='/login/', redirect_field_name=None)
+@login_required(login_url='/account/login/', redirect_field_name=None)
 def logout_view(request):
     logout(request)
-    return redirect('/login/')
+    return redirect('/account/login/')
diff --git a/www/web/warpauth/views/profile.py b/www/web/warpauth/views/profile.py
index a7ec28d4ad0a611e2d4ad242f66a2aa642ef839f..82bc95bb3ab5a3a986dbb17269fd65477e54e925 100644
--- a/www/web/warpauth/views/profile.py
+++ b/www/web/warpauth/views/profile.py
@@ -26,7 +26,7 @@ def clear_error_messages():
     pages["success_passwd"] = False
     pages["selected_tab"]=""
     
-@login_required(login_url='/login/', redirect_field_name=None)
+@login_required(login_url='/account/login/', redirect_field_name=None)
 def index(request):
     clear_error_messages()
     pages['ldap_groups'] = request.user.ldap_user.group_names
@@ -34,7 +34,7 @@ def index(request):
     return HttpResponse(render(request, 'warpauth/profile.html', pages))
 
 
-@login_required(login_url='/login/', redirect_field_name=None)
+@login_required(login_url='/account/login/', redirect_field_name=None)
 def change_information(request):
     clear_error_messages()
     setUserObject(request)
@@ -73,7 +73,7 @@ def change_information(request):
     return HttpResponse(render(request, 'warpauth/profile.html', pages))
 
 
-@login_required(login_url='/login/', redirect_field_name=None)
+@login_required(login_url='/account/login/', redirect_field_name=None)
 def change_password(request):
     clear_error_messages()
     pages["selected_tab"]="#change_passwd"
diff --git a/www/web/warpzone/settings.py b/www/web/warpzone/settings.py
index aabdc17f8d2f9b783358cef5e58ac74c3035a718..82d9c3fdf8ef3a2c00030d07e29709aaa752a061 100644
--- a/www/web/warpzone/settings.py
+++ b/www/web/warpzone/settings.py
@@ -3,6 +3,7 @@ import ldap
 import logging
 import configparser
 from django_auth_ldap.config import LDAPSearch, GroupOfNamesType, PosixGroupType
+from django.core.urlresolvers import reverse_lazy
 
 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
 
@@ -41,6 +42,9 @@ SECRET_KEY = config.get('security','SECRET_KEY')
 # DEBUG
 DEBUG = config.getboolean('debug','DEBUG')
 
+LOGIN_URL = 'two_factor:login'
+LOGOUT_URL = 'logout'
+LOGIN_REDIRECT_URL = '/'
 
 MEDIA_ROOT = 'templates/media/'
 MEDIA_URL = '/media/'
@@ -57,12 +61,16 @@ INSTALLED_APPS = (
     'django.contrib.humanize',
     'bootstrapform',
     'bootstrap3_datetime',
+    'django_otp',
+    'django_otp.plugins.otp_static',
+    'django_otp.plugins.otp_totp',
+    'two_factor',
     'warpmain',
     'warpauth',
     'warpfood',
     # WARPPAY
-    'rest_framework',
-    'rest_framework.authtoken',
+#    'rest_framework',
+#    'rest_framework.authtoken',
 #    'warppay'
 )
 
@@ -72,6 +80,7 @@ MIDDLEWARE_CLASSES = (
     'django.middleware.csrf.CsrfViewMiddleware',
     'django.contrib.auth.middleware.AuthenticationMiddleware',
     'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
+    'django_otp.middleware.OTPMiddleware',
     'django.contrib.messages.middleware.MessageMiddleware',
     'django.middleware.clickjacking.XFrameOptionsMiddleware',
     'django.middleware.security.SecurityMiddleware',
@@ -107,7 +116,7 @@ LOCALE_PATHS = (
 DATABASES = {
     'default': {
         'ENGINE': 'django.db.backends.sqlite3',
-        'NAME': '/opt/database/warpzone.db'
+        'NAME': 'warpzone.db'
     },
     'ldap': {
         'ENGINE': 'ldapdb.backends.ldap',