# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: 'Python 3.9.6 64-bit (''.venv'': venv)'
#     name: python3
# ---

# +
import base64
import json
import os
from base64 import b64encode,b64decode

from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC

# +
import base64
import json
import os
import threading
from base64 import b64encode,b64decode

from prompt_toolkit import prompt
from prompt_toolkit.filters import Condition
from prompt_toolkit.key_binding import KeyBindings

from prompt_toolkit.validation import Validator
from prompt_toolkit.completion import PathCompleter
 
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.fernet import Fernet, InvalidToken


# +
# Returns a string representation of a salt
def generate_salt(size=16):
    return b64encode(os.urandom(size)).decode()

def create_key(pass_phrase, salt=generate_salt()):
    salt =  b64decode(salt)
    # Taken from the website itse
    # https://cryptography.io/en/latest/fernet/#using-passwords-with-fernet
    kdf = PBKDF2HMAC(
        algorithm=hashes.SHA256(),
        length=32,
        salt=salt,
        iterations=10000
    )

    key = base64.urlsafe_b64encode(kdf.derive(pass_phrase.encode()))

    return key  


def encrypt(data, pass_phrase, salt=generate_salt()):
    pass


class Crypto:

    
    def __init__(self, pass_phrase, data, salt=generate_salt()):
        """initializes the crypto class

        Args:
            pass_phrase (str): the password for encrypting or decrypting
            data (str): the data we want to decrypt or encrypt
            salt (str, optional): string representation of a salt we want to use for creating key. Defaults to generate_salt().
        """
        self.data = str(data)
        self.salt = salt
        self.pass_phrase = pass_phrase
        
        # self.encrypt_status = False

        self.key = self.create_key()


    def create_key(self):
        """[summary]

        Returns:
            [type]: [description]
        """
        
        # Taken from the website itse
        # https://cryptography.io/en/latest/fernet/#using-passwords-with-fernet
        kdf = PBKDF2HMAC(
            algorithm=hashes.SHA256(),
            length=32,
            salt=b64decode(self.salt),
            iterations=10000
        )

        key = base64.urlsafe_b64encode(kdf.derive(self.pass_phrase.encode()))

        return key    

    def encrypt(self):
        # if self.encrypt_status == True:
        #     return

        f = Fernet(self.key)

        self.data = f.encrypt(self.data.encode()).decode()
        return self

        # self.encrypt_status = True
    def decrypt(self):
        """[summary]

        Returns:
            [type]: [description]
        """
        # if self.encrypt_status == False:
        #     return

        f = Fernet(self.key)

        self.data = f.decrypt(self.data.encode()).decode()
        # self.encrypt_status = False
        return self

    def __str__(self):
        return json.dumps(self.to_dict())

    def to_dict(self):
        return {
            'salt':self.salt,
            'data':self.data
        }
  
# -

passwd = "<PASSWORD>"

c.encrypt()
ssc = str(c)

str(c)

s = json.loads(ssc)
cc = crypto("ABCD", **s)
cc.decrypt()
cc.data

mydict

# +
passwd = "MYpass"

mydict={
    'user1': str(Crypto(passwd, "PASS1").encrypt()),
    'user2': str(Crypto(passwd, "PASS2").encrypt()),
    'user3': str(Crypto(passwd, "PASS3").encrypt())
}
# -

mydict['user1']

Crypto(passwd, **json.loads(mydict['user2'])).decrypt().data

lastf = Crypto(passwd, json.dumps(mydict)).encrypt()
str(lastf)

with open("vault.json", "w") as f:
    f.write(str(lastf))

firstf = Crypto(passwd, **json.loads(str(lastf))).decrypt()
(firstf.to_dict())

ag = json.loads(firstf.to_dict()['data'])
ag

ag['user3']

# +
the_dict = {
    "google": {
        "mathurshiva901": {
            "password": {
                "pass": "<PASSWORD>",
                "salt": "unique_salt"
            }
        },
        "mathurshiva90b": {
            "password": {
                "pass": "<PASSWORD>",
                "salt": "unique_salt"
            }
        },
        "mathurshiva90c": {
            "password": {
                "pass": "<PASSWORD>",
                "salt": "unique_salt"
            }
        },
        "mathurshiva90d": {
            "password": {
                "pass": "<PASSWORD>",
                "salt": "unique_salt"
            }
        }
    },  
    "orkut": {
        "mathurshiva901": {
            "password": {
                "pass": "<PASSWORD>",
                "salt": "unique_salt"
            }
        },
        "mathurshiva90b": {
            "password": {
                "pass": "<PASSWORD>",
                "salt": "unique_salt"
            }
        },
        "mathurshiva90c": {
            "password": {
                "pass": "<PASSWORD>",
                "salt": "unique_salt"
            }
        },
        "mathurshiva90d": {
            "password": {
                "pass": "<PASSWORD>encrypted",
                "salt": "<PASSWORD>_salt"
            }
        }
    }
}

dictt = {}
for keys in the_dict:
    dictt[keys] = {}
    for keys2 in the_dict[keys]:
        dictt[keys][keys2] = {}
        for keys3 in the_dict[keys][keys2]:
            dictt[keys][keys2][keys3] = None

            
from prompt_toolkit.completion import NestedCompleter

out = prompt(">", completer= NestedCompleter.from_nested_dict(dictt))
out
# -



dictt



StarcoderdataJupyterScriptsDedupFiltered