Model to store passwords per project in django

Django -- Posted on Oct. 13, 2018

Model to store password per project in django

              
                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)
                  
   
            

Related Posts