From 9086f474568c6a15d8ccf200de7bf8f517338c0b Mon Sep 17 00:00:00 2001 From: Mohamed ElKalioby Date: Wed, 16 Oct 2019 14:41:19 +0300 Subject: [PATCH] Setting Ownership of keys --- README.md | 8 +++++--- mfa/FIDO2.py | 1 + mfa/U2F.py | 1 + .../0009_user_keys_owned_by_enterprise.py | 20 +++++++++++++++++++ mfa/models.py | 2 ++ setup.py | 2 +- 6 files changed, 30 insertions(+), 4 deletions(-) create mode 100644 mfa/migrations/0009_user_keys_owned_by_enterprise.py diff --git a/README.md b/README.md index 3d97e13..4b4468e 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,8 @@ Depends on MFA_RECHECK_MIN=10 # Minimum interval in seconds MFA_RECHECK_MAX=30 # Maximum in seconds MFA_QUICKLOGIN=True # Allow quick login for returning users by provide only their 2FA - MFA_HIDE_DISABLE=('FIDO2',) # Can the user disable his key (Added in 1.2.0). + MFA_HIDE_DISABLE=('FIDO2',) # Can the user disable his key (Added in 1.2.0). + MFA_OWNED_BY_ENTERPRISE = FALSE # Who ownes security keys TOKEN_ISSUER_NAME="PROJECT_NAME" #TOTP Issuer name @@ -68,8 +69,9 @@ Depends on * Trusted_Devices * Email - **Note**: Starting version 1.1, ~~FIDO_LOGIN_URL~~ isn't required for FIDO2 anymore. - + **Notes**: + * Starting version 1.1, ~~FIDO_LOGIN_URL~~ isn't required for FIDO2 anymore. + * Starting version 1.6.0, Key owners can be specified. 1. Break your login function Usually your login function will check for username and password, log the user in if the username and password are correct and create the user session, to support mfa, this has to change diff --git a/mfa/FIDO2.py b/mfa/FIDO2.py index 32de73a..2b58eaf 100644 --- a/mfa/FIDO2.py +++ b/mfa/FIDO2.py @@ -52,6 +52,7 @@ def complete_reg(request): uk=User_Keys() uk.username = request.user.username uk.properties = {"device":encoded,"type":att_obj.fmt,} + uk.owned_by_enterprise=getattr(settings,"MFA_OWNED_BY_ENTERPRISE",False) uk.key_type = "FIDO2" uk.save() return HttpResponse(simplejson.dumps({'status': 'OK'})) diff --git a/mfa/U2F.py b/mfa/U2F.py index 68618d6..c78eea2 100644 --- a/mfa/U2F.py +++ b/mfa/U2F.py @@ -89,6 +89,7 @@ def bind(request): User_Keys.objects.filter(username=request.user.username,key_type="U2F").delete() uk = User_Keys() uk.username = request.user.username + uk.owned_by_enterprise = getattr(settings, "MFA_OWNED_BY_ENTERPRISE", False) uk.properties = {"device":simplejson.loads(device.json),"cert":cert_hash} uk.key_type = "U2F" uk.save() diff --git a/mfa/migrations/0009_user_keys_owned_by_enterprise.py b/mfa/migrations/0009_user_keys_owned_by_enterprise.py new file mode 100644 index 0000000..9132913 --- /dev/null +++ b/mfa/migrations/0009_user_keys_owned_by_enterprise.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations +from django.conf import settings + +class Migration(migrations.Migration): + + dependencies = [ + ('mfa', '0008_user_keys_last_used'), + ] + + operations = [ + migrations.AddField( + model_name='user_keys', + name='owned_by_enterprise', + field=models.NullBooleanField(default=None), + ), + migrations.RunSQL("update mfa_user_keys set owned_by_enterprise = %s where key_type='FIDO2'"%(1 if getattr(settings,"MFA_OWNED_BY_ENTERPRISE",False) else 0 )) + ] diff --git a/mfa/models.py b/mfa/models.py index bd01882..2faaf0f 100644 --- a/mfa/models.py +++ b/mfa/models.py @@ -13,6 +13,8 @@ class User_Keys(models.Model): enabled=models.BooleanField(default=True) expires=models.DateTimeField(null=True,default=None,blank=True) last_used=models.DateTimeField(null=True,default=None,blank=True) + owned_by_enterprise=models.NullBooleanField(default=None,null=True,blank=True) + def save(self, force_insert=False, force_update=False, using=None, update_fields=None): if self.key_type == "Trusted Device" and self.properties.get("signature","") == "": self.properties["signature"]= jwt.encode({"username": self.username, "key": self.properties["key"]}, settings.SECRET_KEY) diff --git a/setup.py b/setup.py index 591e1d2..67dca1e 100644 --- a/setup.py +++ b/setup.py @@ -4,7 +4,7 @@ from setuptools import find_packages, setup setup( name='django-mfa2', - version='1.5.0', + version='1.6.0', description='Allows user to add 2FA to their accounts', long_description=open("README.md").read(), long_description_content_type="text/markdown",