Projet

Général

Profil

« Précédent | Suivant » 

Révision a9a12993

Ajouté par Josué Kouka il y a plus de 8 ans

encrypt user credentials (#9534)

Voir les différences:

README
45 45
Example of local_settings.py
46 46
----------------------------
47 47

  
48
    # Secret Key used for the encryption/decryption
49
    # Must be 16, 32 or 64 bytes long
50
    SECRET_KEY = 'whatever you want but keep it secret'
51

  
48 52
    SITE_DOMAIN =  'example.com'
49 53
    SITE_LOGIN_PATH = '/'
50 54
    SITE_HOME_PATH = '/profile' # Not required
debian/control
13 13
    python-gadjo,
14 14
    python-django-jsonfield,
15 15
    python-ldap,
16
    python-crypto
16 17
Recommends: python-django-mellon
17 18
Description: Authentication Reverse Proxy
18 19

  
mandayejs/mandaye/models.py
14 14
# You should have received a copy of the GNU Affero General Public License
15 15
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 16

  
17
import base64
18
from Crypto.Cipher import AES
17 19

  
18 20
from django.db import models
19
from jsonfield import JSONField
21
from django.conf import settings
20 22
from django.utils.translation import ugettext_lazy as _
21 23

  
24
from jsonfield import JSONField
25

  
26
from mandayejs.mandaye.utils import get_password_field
27

  
22 28

  
23 29
class UserCredentials(models.Model):
24 30
    user = models.ForeignKey('auth.User')
......
33 39
            or self.user.email \
34 40
            or self.user.username
35 41

  
36
    def to_login_info(self):
42
    def save(self, *args, **kwargs):
43
        self.encrypt()
44
        super(UserCredentials, self).save(*args, **kwargs)
45

  
46
    def _get_cipher(self):
47
        """Return cipher object
48
        """
49
        return AES.new(getattr(settings, 'SECRET_KEY'), AES.MODE_CFB, "0000000000000000")
50

  
51
    def encrypt(self,):
52
        """Encrypt password
53
        """
54
        password_field_name = get_password_field()
55
        cipher = self._get_cipher()
56
        self.locators[password_field_name] = \
57
           base64.b64encode(cipher.encrypt(
58
               self.locators.get(password_field_name,'')
59
            )) 
60

  
61
        return self.locators
62

  
63
    def decrypt(self,):
64
        """Decrypt password
65
        """
66
        password_field_name = get_password_field()
67
        cipher = self._get_cipher()
68
        self.locators[password_field_name] = \
69
            cipher.decrypt(
70
                base64.b64decode(
71
                    self.locators.get(password_field_name,'')
72
            ))
73

  
74
        return self.locators
75

  
76
    def to_login_info(self, decrypt=False):
77
        if decrypt:
78
            self.decrypt()
37 79
        return {'#'+k : v for k,v in self.locators.items() }
38 80

  
mandayejs/mandaye/utils.py
51 51
    url = url._replace(netloc=settings.SITE_DOMAIN)
52 52
    return url.path
53 53

  
54
def get_password_field():
55
    """Return name of the password field
56
    """
57
    try:
58
        field_name = [ field.get('name') for field in settings.SITE_LOCATORS if field.get('kind') == 'password' ]
59
        return field_name[0]
60
    except (IndexError,):
61
        return None
54 62

  
mandayejs/mandaye/views.py
153 153
        'auth_checker': os.path.join(site_static_root, site_auth_checker)
154 154
    }
155 155
    logger.debug(login_info)
156
    login_info['locators'] = [ credentials.to_login_info(decrypt=True)]
156 157
    result = exec_phantom(login_info)
157 158
    logger.debug(result)
158 159

  
tests/tests.py
1
import pytest
2

  
3
from django.conf import settings
4
from django.contrib.auth.models import User
5

  
6
from mandayejs.mandaye.models import UserCredentials
7

  
8
pytestmark = pytest.mark.django_db
9

  
10
def create_user(**kwargs):
11
    password = kwargs.pop('password', None) or kwargs.get('username')
12
    user, created = User.objects.get_or_create(**kwargs)
13
    if password:
14
        user.set_password(password)
15
        user.save()
16
    return user
17

  
18
def create_credentials(user, credentials):
19
    user, created = UserCredentials.objects.get_or_create(user=user, locators=credentials)
20
    return user
21

  
22

  
23
@pytest.fixture
24
def user_john(db):
25
    return create_user(username='john')    
26

  
27
@pytest.fixture
28
def cred_john(db,user_john):
29
    return create_credentials(user_john, {
30
            "username": "john",
31
            "password": "john password"
32
        })
33

  
34
@pytest.fixture(params=['cred_john'])
35
def credentials(request, cred_john):
36
    return locals().get(request.param)
37

  
38

  
39
def test_encryption(credentials):
40
    decrypted = credentials.decrypt()
41
    assert decrypted.get('password') == 'john password'
42
    
43

  
44
def test_migrate_users_command():
45
    pass
tox.ini
1
[tox]
2
envlist = django17
3

  
4
[testenv:django17]
5
setenv = DJANGO_SETTINGS_MODULE=mandayejs.settings
6
usedevelop = True
7
command = pytest -vs tests/tests.py 
8

  
9
deps = django>1.7,<1.8
10
    pytest
11
    pytest-django
12

  
13
[testenv:pylint]
14
usedevelop = True
15
command = pylint mandayejs
16
deps = pylint

Formats disponibles : Unified diff