# Copyright 1999-2015. Parallels IP Holdings GmbH. All Rights Reserved.
""" Utility to strip sensitive user data from reports generated by collect utility """
import os, sys, re
from os.path import join, isdir, isfile, exists
from tempfile import mkstemp
from shutil import move

re_aes = r'(.*)\$AES\-\d+\-CBC\$[A-Za-z0-9\+\-\/=\$]+(.*)'
re_sha = r'(.*)\$5\$[A-Za-z0-9\+\-\/=\$\.]+(.*)'
re_passwords = r'(.*)\$(?:AES\-\d+\-CBC|5)\$[A-Za-z0-9\+\-\/=\$\.]+(.*)'
re_mysql_password = r'''(mysql.*?\s\-p)\S+(\s)'''
re_sysuser_password = r'''('System User Password',[^,]*,\s?')[^'\s]*(')'''
re_admin_data = r'''('admin_?address[',\s]+|email[',\s]+|fax[',\s]+|phone[',\s]+|pname[',\s]+).*(')'''

patterns = {
    "db/": (re_passwords, re_sysuser_password),
    "db/misc.sql": re_admin_data,
    "plesk/PMM/": re_passwords,
    "plesk/cp-server/admin/panel.log": re_mysql_password,
}

SUBST_PATTERN = r'\1*****\2'

def replace(file_path, regexps):
    fh, abs_path = mkstemp()
    with os.fdopen(fh, 'w') as new_file:
        with open(file_path) as old_file:
            for line in old_file:
                for regexp in regexps:
                    line = regexp.sub(SUBST_PATTERN, line)
                new_file.write(line)
    move(abs_path, file_path)

def prepare_matcher(regexps):
    if isinstance(regexps, basestring):
        regexps = (regexps,)
    return [re.compile(pat) for pat in regexps]

def sanitize_files():
    for path in patterns:
        regs = prepare_matcher(patterns[path])
        if isfile(path):
            replace(path, regs)
        elif isdir(path):
            for root, dirs, files in os.walk(path):
                for fil in files:
                    replace(join(root, fil), regs)
        elif exists(path):
            sys.stderr.write("Unexpected file type: %s. Skip it." % path)

def main():
    os.chdir(sys.argv[1])
    sanitize_files()

if __name__ == "__main__":
    import unittest
    class ReTests(unittest.TestCase):
        # cannot use setUpClass in python 2.6
        def setUp(self):
            self.data_aes = {
                r'"$AES-128-CBC$cULLZKgnTOnhLpNgfsVu1w==$q1D2tUr2KE2Hyju0/bxMMA=="': r'"*****"',
                r'<<HelloWorld>>': r'<<HelloWorld>>'
            }
            self.data_sha = {
                r'"$5$+mu8Mw8yBI+RGsvn$8cl7QhZ.hBTTSVCpp9g.b.qGW8nXRmeUAuS.mHdGWN9"': r'"*****"',
                r'"something"': r'"something"'
            }
            self.data_mysql = {
                r'mysql -ppass -u"admin"': r'mysql -p***** -u"admin"',
                r'mysql -p"pass" -uadmin': r'mysql -p***** -uadmin',
                r'''mysql -p'pass' -u"admin"''': r'''mysql -p***** -u"admin"''',
                r'mysqldump -p"pass" -uadmin | mysql -uuser -psecret hello': r'mysqldump -p***** -uadmin | mysql -uuser -p***** hello',
                r'''Database cloning command: mysqldump  -h'localhost' -P'3306' -u'qateam_ttl' -p'ifgrfc' 'qateam_ttl' 2> /opt/psa/tmp/db-dumpumaI7p | mysql -h'localhost' -P'3306' -u'qateam_ttl' -p'ifgrfc' 'qateam_devttl' ''': r'''Database cloning command: mysqldump  -h'localhost' -P'3306' -u'qateam_ttl' -p***** 'qateam_ttl' 2> /opt/psa/tmp/db-dumpumaI7p | mysql -h'localhost' -P'3306' -u'qateam_ttl' -p***** 'qateam_devttl' ''',
            }
            self.data_system_user_log = {
                '''INSERT INTO `log_components` VALUES (3633,'System User Password','','ifgrfc');''': '''INSERT INTO `log_components` VALUES (3633,'System User Password','','*****');''',
            }

        def test_aes(self):
            self._re_test_helper(re_aes, self.data_aes)

        def test_sha(self):
            self._re_test_helper(re_sha, self.data_sha)

        def test_passwords(self):
            data_passwords = self.data_aes
            data_passwords.update(self.data_sha)
            self._re_test_helper(re_passwords, data_passwords)

        def test_mysql(self):
            self._re_test_helper(re_mysql_password, self.data_mysql)

        def test_sysuser_passwords(self):
            self._re_test_helper(re_sysuser_password, self.data_system_user_log)

        def _re_test_helper(self, regexp, data):
            for arg in data:
                act = re.sub(regexp, SUBST_PATTERN, arg)
                self.assertEqual(act, data[arg])


    unittest.main()
