невозможно написать тест для модели django, содержащей поле пользовательской модели - PullRequest
1 голос
/ 02 апреля 2020

У меня есть модель для пользователей, где в поле для пароля есть настраиваемое поле. Эта модель работает нормально, но я не могу запустить тесты для этой модели.

моя модель

from core_engine.CustomModelFields import *

class Users(models.Model):
    username = models.EmailField(unique=True)
    name = models.CharField(max_length=100)
    password = EncryptedField(max_length=500)

в моем core_engine.CustomModelFields.py файл

from account_engine.crypto import *

class EncryptedField(CharField):

    def from_db_value(self, value, expression, connection, context):
        value = Password.decrypt(str(value))
        return value.decode("utf-8")

    def to_python(self, value):
        if not value:
            return None
        return value

        #Only need to decrypt if password already encrypted. 
        try:
            if Password.encrypt(Password.decrypt(value)) == value:
                value = Password.decrypt(str(value))
                return value.decode("utf-8")
        except:
            return value

    def get_db_prep_save(self, value, connection):
        value = Password.encrypt(str(value))
        return value    

и, наконец, в файле accounts_engine.crypto.py, у меня есть

import base64, hashlib
from django.db import models
from Crypto import Random
from Crypto.Cipher import AES

BS = 16
pad = lambda s: s + (BS - len(s) % BS) * chr(BS - len(s) % BS)
unpad = lambda s : s[0:-s[-1]]


class Password(models.Model):



    def encrypt( raw ):
        mysecretpassword = 'somepassword'
        KEY = hashlib.sha256(mysecretpassword.encode('utf-8')).digest()
        raw = pad(raw)
        iv = Random.new().read( AES.block_size )
        cipher = AES.new( KEY, AES.MODE_CBC, iv )
        return base64.b64encode( iv + cipher.encrypt( raw ) )

    def decrypt( enc ):
        mysecretpassword = 'somepassword'
        KEY = hashlib.sha256(mysecretpassword.encode('utf-8')).digest()  
        enc = base64.b64decode(enc)
        iv = enc[:16]
        cipher = AES.new(KEY, AES.MODE_CBC, iv )
        return unpad(cipher.decrypt( enc[16:] ))

Все, что я хочу сделать, это просто проверить мою модель пользователей и увидеть, что я возможность создать пользователя во время теста, который потребуется для других тестов

, поэтому в моем файле test.py у меня есть

class UsersTestCase(TestCase):

    @classmethod
    def setUp(self):
        print(dt.datetime.now())
        self.user= Users.objects.create(
            username = 'test@test.com',
            date_first_registered = dt.datetime.now(),
            password = Password.encrypt('abc')
        )

    def test_get_user(self):

        first_customer = Users.objects.first()
        self.assertEqual(first_customer.username, 'test@test.com')

При выполнении вышеуказанного теста я получаю сообщение об ошибке :

TypeError: Object type <class 'str'> cannot be passed to C code

Редактировать: я понимаю, что ошибка связана с тем, что я передаю пароль как Password.encrypt ('ab c').

, какие изменения я должен внести в свой Тестовая функция для того, чтобы создать, чтобы создать нового пользователя

TRACEBACK

Traceback (most recent call last):
  File "D:\project_path\account_engine\tests\tests_models.py", line 15, in setUp
    password = Password.encrypt('abc')
  File "D:\project_path\account_engine\crypto.py", line 21, in encrypt
    return base64.b64encode( iv + cipher.encrypt( raw ) )
  File "d:\project_path\venv\lib\site-packages\Crypto\Cipher\_mode_cbc.py", line 178, in encrypt
    c_uint8_ptr(plaintext),
  File "d:\project_path\venv\lib\site-packages\Crypto\Util\_raw_api.py", line 144, in c_uint8_ptr
    raise TypeError("Object type %s cannot be passed to C code" % type(data))
TypeError: Object type <class 'str'> cannot be passed to C code

1 Ответ

1 голос
/ 02 апреля 2020

Метод шифрования принимает bytes строковый тип, а не str в Python 3:

. Открытые и зашифрованные тексты (ввод / вывод) могут быть только байтами, байтами или просмотром памяти. В Python 3 вы не можете передавать строки. В Python 2 вы не можете передавать строки Unicode.

Сначала необходимо кодировать raw:

def encrypt( raw ):
    mysecretpassword = 'somepassword'
    KEY = hashlib.sha256(mysecretpassword.encode('utf-8')).digest()
    raw = pad(raw)
    iv = Random.new().read( AES.block_size )
    cipher = AES.new( KEY, AES.MODE_CBC, iv )
    return base64.b64encode(iv + cipher.encrypt(raw.encode('utf-8')))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...