# Path: pyledger/server/config.py
# SECRET = b'test'
# LIFETIME = 1
# 
# Path: pyledger/server/db.py
# class User(Model):
#     __tablename__ = 'users'
#     id = Column(Integer, primary_key=True)
#     name = Column(String, unique=True)
#     when = Column(DateTime)
#     info = Column(LargeBinary)
#     key = Column(String)
#     password = Column(String)
#     profile = Column(Integer)
#     contracts = relationship("Contract", back_populates="user")
#     sessions = relationship("Session", back_populates='user')
# 
#     def __repr__(self):
#         return '<User {} with key: {}>'.format(self.name, self.key)
# 
#     def __str__(self):
#         return '<User {} with key: {}>'.format(self.name, self.key)
# 
#     def set_password(self, password):
#         self.password = base64.b64encode(password)
# 
#     def get_password(self):
#         return base64.b64decode(self.password)
# 
#     def check_password(self, password):
#         kpdf = PBKDF2HMAC(
#             algorithm=hashes.SHA256(),
#             length=32,
#             salt=SECRET,
#             iterations=1000000,
#             backend=password_backend
#         )
#         try:
#             kpdf.verify(password.encode('utf-8'), self.get_password())
#             correct = True
#         except InvalidKey as e:
#             print(e)
#             correct = False
# 
#         return correct
# 
#     @classmethod
#     def query(cls):
#         return DB.session.query(cls)
# 
#     @staticmethod
#     def from_name(name):
#         return User.query().filter(User.name == name).one_or_none()
# 
#     def get_permissions(self):
#         return Permissions(self.profile)
# 
#     def set_permissions(self, permissions):
#         self.profile = permissions.value
# 
# DB = Handler()
# 
# class Permissions(Enum):
#     ROOT = 1
#     USER = 2
#     ANON = 3


import datetime
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from pyledger.server.config import password_backend, SECRET
from pyledger.server.db import User, DB, Permissions
permissions_registry = {}
method_permissions_registry = {}


def create_master(password):
    kpdf = PBKDF2HMAC(
        algorithm=hashes.SHA256(),
        length=32,
        salt=SECRET,
        iterations=1000000,
        backend=password_backend
    )
    master_user = User()
    master_user.name = 'master'
    master_user.when = datetime.datetime.now()
    master_user.set_permissions(Permissions.ROOT)
    master_user.set_password(kpdf.derive(password.encode('utf-8')))

    DB.session.add(master_user)
    DB.session.commit()


def create_user(name, password):
    kpdf = PBKDF2HMAC(
        algorithm=hashes.SHA256(),
        length=32,
        salt=SECRET,
        iterations=1000000,
        backend=password_backend
    )

# Path: pyledger/server/config.py
# SECRET = b'test'
# LIFETIME = 1
# 
# Path: pyledger/server/db.py
# class User(Model):
#     __tablename__ = 'users'
#     id = Column(Integer, primary_key=True)
#     name = Column(String, unique=True)
#     when = Column(DateTime)
#     info = Column(LargeBinary)
#     key = Column(String)
#     password = Column(String)
#     profile = Column(Integer)
#     contracts = relationship("Contract", back_populates="user")
#     sessions = relationship("Session", back_populates='user')
# 
#     def __repr__(self):
#         return '<User {} with key: {}>'.format(self.name, self.key)
# 
#     def __str__(self):
#         return '<User {} with key: {}>'.format(self.name, self.key)
# 
#     def set_password(self, password):
#         self.password = base64.b64encode(password)
# 
#     def get_password(self):
#         return base64.b64decode(self.password)
# 
#     def check_password(self, password):
#         kpdf = PBKDF2HMAC(
#             algorithm=hashes.SHA256(),
#             length=32,
#             salt=SECRET,
#             iterations=1000000,
#             backend=password_backend
#         )
#         try:
#             kpdf.verify(password.encode('utf-8'), self.get_password())
#             correct = True
#         except InvalidKey as e:
#             print(e)
#             correct = False
# 
#         return correct
# 
#     @classmethod
#     def query(cls):
#         return DB.session.query(cls)
# 
#     @staticmethod
#     def from_name(name):
#         return User.query().filter(User.name == name).one_or_none()
# 
#     def get_permissions(self):
#         return Permissions(self.profile)
# 
#     def set_permissions(self, permissions):
#         self.profile = permissions.value
# 
# DB = Handler()
# 
# class Permissions(Enum):
#     ROOT = 1
#     USER = 2
#     ANON = 3


# Path: pyledger/server/auth.py
import datetime
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from pyledger.server.config import password_backend, SECRET
from pyledger.server.db import User, DB, Permissions

permissions_registry = {}
method_permissions_registry = {}


def create_master(password):
    kpdf = PBKDF2HMAC(
        algorithm=hashes.SHA256(),
        length=32,
        salt=SECRET,
        iterations=1000000,
        backend=password_backend
    )
    master_user = User()
    master_user.name = 'master'
    master_user.when = datetime.datetime.now()
    master_user.set_permissions(Permissions.ROOT)
    master_user.set_password(kpdf.derive(password.encode('utf-8')))

    DB.session.add(master_user)
    DB.session.commit()


def create_user(name, password):
    kpdf = PBKDF2HMAC(
        algorithm=hashes.SHA256(),
        length=32,
        salt=SECRET,
        iterations=1000000,
        backend=password_backend
    )

    user = User()