У меня есть модель для пользователей, где в поле для пароля есть настраиваемое поле. Эта модель работает нормально, но я не могу запустить тесты для этой модели.
моя модель
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