# Path: will/settings.py
# def auto_key():
# def import_settings(quiet=True):
#         DEPRECATED_BUT_MAPPED_SETTINGS = {
#             "USERNAME": "HIPCHAT_USERNAME",
#             "PASSWORD": "HIPCHAT_PASSWORD",
#             "V1_TOKEN": "HIPCHAT_V1_TOKEN",
#             "V2_TOKEN": "HIPCHAT_V2_TOKEN",
#             "TOKEN": "HIPCHAT_V1_TOKEN",
#             "ROOMS": "HIPCHAT_ROOMS",
#             "NAME": "HIPCHAT_NAME",
#             "HANDLE": "HIPCHAT_HANDLE",
#             "DEFAULT_ROOM": "HIPCHAT_DEFAULT_ROOM",
#             "SLACK_DEFAULT_ROOM": "SLACK_DEFAULT_CHANNEL",
#         }
#             IO_BACKENDS = []
# 
# Path: will/backends/encryption/base.py
# class WillBaseEncryptionBackend(object):
# 
#     def __init__(self, *args, **kwargs):
#         pass
# 
#     @staticmethod
#     def encrypt_to_b64(raw):
#         raise NotImplementedError
# 
#     @staticmethod
#     def decrypt_from_b64(enc):
#         raise NotImplementedError


import binascii
import hashlib
import logging
import os
import dill as pickle
from Crypto.Cipher import AES
from will import settings
from will.backends.encryption.base import WillBaseEncryptionBackend


class AESEncryption(WillBaseEncryptionBackend):
    'AES encryption backend'
    @staticmethod
    def encrypt_to_b64(raw):
        'encrypt and b64-encode data'
        try:
            enc = binascii.b2a_base64(pickle.dumps(raw, -1))
            if settings.ENABLE_INTERNAL_ENCRYPTION:
                iv = binascii.b2a_hex(os.urandom(8))
                cipher = AES.new(key, AES.MODE_CBC, iv)
                enc = binascii.b2a_base64(cipher.encrypt(pad(enc)))
                return "%s/%s" % (iv.decode("utf-8"), enc.decode("utf-8"))
            return enc
        except Exception:
            logging.exception("Error preparing message for the wire: \n%s", raw)
            return None

    @staticmethod
    def decrypt_from_b64(enc):
        'decrypt b64-encoded data'
        try:
            if b'/' in enc and enc.index(b'/') == BS:
                iv = enc[:BS]
                encrypted_data = enc[BS+1:]
                cipher = AES.new(key, AES.MODE_CBC, iv)
                decrypted_data = unpad(cipher.decrypt(binascii.a2b_base64(encrypted_data)))
            return pickle.loads(binascii.a2b_base64(decrypted_data))
        except (KeyboardInterrupt, SystemExit):

# Path: will/settings.py
# def auto_key():
# def import_settings(quiet=True):
#         DEPRECATED_BUT_MAPPED_SETTINGS = {
#             "USERNAME": "HIPCHAT_USERNAME",
#             "PASSWORD": "HIPCHAT_PASSWORD",
#             "V1_TOKEN": "HIPCHAT_V1_TOKEN",
#             "V2_TOKEN": "HIPCHAT_V2_TOKEN",
#             "TOKEN": "HIPCHAT_V1_TOKEN",
#             "ROOMS": "HIPCHAT_ROOMS",
#             "NAME": "HIPCHAT_NAME",
#             "HANDLE": "HIPCHAT_HANDLE",
#             "DEFAULT_ROOM": "HIPCHAT_DEFAULT_ROOM",
#             "SLACK_DEFAULT_ROOM": "SLACK_DEFAULT_CHANNEL",
#         }
#             IO_BACKENDS = []
# 
# Path: will/backends/encryption/base.py
# class WillBaseEncryptionBackend(object):
# 
#     def __init__(self, *args, **kwargs):
#         pass
# 
#     @staticmethod
#     def encrypt_to_b64(raw):
#         raise NotImplementedError
# 
#     @staticmethod
#     def decrypt_from_b64(enc):
#         raise NotImplementedError


# Path: will/backends/encryption/aes.py
import binascii
import hashlib
import logging
import os
import dill as pickle
from Crypto.Cipher import AES
from will import settings
from will.backends.encryption.base import WillBaseEncryptionBackend



class AESEncryption(WillBaseEncryptionBackend):
    'AES encryption backend'
    @staticmethod
    def encrypt_to_b64(raw):
        'encrypt and b64-encode data'
        try:
            enc = binascii.b2a_base64(pickle.dumps(raw, -1))
            if settings.ENABLE_INTERNAL_ENCRYPTION:
                iv = binascii.b2a_hex(os.urandom(8))
                cipher = AES.new(key, AES.MODE_CBC, iv)
                enc = binascii.b2a_base64(cipher.encrypt(pad(enc)))
                return "%s/%s" % (iv.decode("utf-8"), enc.decode("utf-8"))
            return enc
        except Exception:
            logging.exception("Error preparing message for the wire: \n%s", raw)
            return None

    @staticmethod
    def decrypt_from_b64(enc):
        'decrypt b64-encoded data'
        try:
            if b'/' in enc and enc.index(b'/') == BS:
                iv = enc[:BS]
                encrypted_data = enc[BS+1:]
                cipher = AES.new(key, AES.MODE_CBC, iv)
                decrypted_data = unpad(cipher.decrypt(binascii.a2b_base64(encrypted_data)))
            return pickle.loads(binascii.a2b_base64(decrypted_data))
        except (KeyboardInterrupt, SystemExit):

            pass