Model to store password per project in django
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | import base64
from Crypto.Cipher import AES
from Crypto.Hash import SHA256
from Crypto import Random
from django.db import models
from django.conf import settings
def encrypt(key, source, encode=True):
key = SHA256.new(key).digest()
IV = Random.new().read(AES.block_size)
encryptor = AES.new(key, AES.MODE_CBC, IV)
padding = AES.block_size - len(source) % AES.block_size
source += bytes([padding]) * padding
data = IV + encryptor.encrypt(source)
return base64.b64encode(data).decode("utf-8") if encode else data
def decrypt(key, source, decode=True):
if decode:
source = base64.b64decode(source.encode("utf-8"))
key = SHA256.new(key).digest()
IV = source[:AES.block_size]
decryptor = AES.new(key, AES.MODE_CBC, IV)
data = decryptor.decrypt(source[AES.block_size:])
padding = data[-1]
if data[-padding:] != bytes([padding]) * padding:
raise ValueError("Invalid padding...")
return data[:-padding] # remove the padding
class Timestamped(models.Model):
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
abstract = True
class AccountType(Timestamped):
name = models.CharField(max_length=100)
class Meta:
default_related_name = 'accounttypes'
verbose_name = 'account type'
verbose_name_plural = 'account types'
def __str__(self):
return self.name
class Project(Timestamped):
name = models.CharField(max_length=100)
class Meta:
default_related_name = 'projects'
verbose_name = 'project'
verbose_name_plural = 'projects'
def __str__(self):
return self.name
class Password(Timestamped):
account_type = models.ForeignKey(AccountType, on_delete=models.CASCADE)
project = models.ForeignKey(Project, on_delete=models.CASCADE)
username = models.CharField(max_length=100)
password = models.CharField(max_length=255)
comments = models.TextField(blank=True)
url = models.URLField(blank=True)
class Meta:
default_related_name = 'passwords'
verbose_name = 'password'
verbose_name_plural = 'passwords'
def __str__(self):
return self.username
def save(self, *args, **kwargs):
encrypted = encrypt(bytes(settings.SECRET_KEY, 'utf-8'), bytes(self.password, 'utf-8'))
self.password = encrypted
decrypted = decrypt(bytes(settings.SECRET_KEY, 'utf-8'), encrypted)
print(encrypted)
print(decrypted)
super().save(*args, **kwargs)
|