class Application: def __init__(self, injected_proxy_ip=None, injected_api_call=None): self.proxy_ip = injected_proxy_ip or Settings().getServiceIp('proxy') self.api_call = injected_api_call or EyeosApiCall() self.logger = Logger(__name__) def insert_apps(self, apps, card): apps_url = "https://{0}/application/v1/applications".format(self.proxy_ip) self.logger.debug('POST request to: {0}'.format(apps_url)) req = self.api_call.post(apps_url, card=card, verify=False, json=apps) if req.status_code != 201: raise EyeosAPIError("Error inserting apps. API response: [ code: {0}, content: {1}]" .format(req.status_code, req.content)) self.logger.info('Apps correctly installed.') def empty_apps(self, card): apps_url = "https://{0}/application/v1/applications".format(self.proxy_ip) self.logger.debug('DELETE request to: {0}'.format(apps_url)) req = self.api_call.delete(apps_url, card=card, verify=False) if req.status_code != 200: raise EyeosAPIError("Error emptying apps. API response: [ code: {0}, content: {1}]" .format(req.status_code, req.content)) self.logger.info('Apps correctly emptied.') def save(self, apps, card): self.insert_apps(apps['eyeosApps'], card)
class Application: def __init__(self, injected_proxy_ip=None, injected_api_call=None): self.proxy_ip = injected_proxy_ip or Settings().getServiceIp('proxy') self.api_call = injected_api_call or EyeosApiCall() self.logger = Logger(__name__) def insert_apps(self, apps, card): apps_url = "https://{0}/application/v1/applications".format( self.proxy_ip) self.logger.debug('POST request to: {0}'.format(apps_url)) req = self.api_call.post(apps_url, card=card, verify=False, json=apps) if req.status_code != 201: raise EyeosAPIError( "Error inserting apps. API response: [ code: {0}, content: {1}]" .format(req.status_code, req.content)) self.logger.info('Apps correctly installed.') def empty_apps(self, card): apps_url = "https://{0}/application/v1/applications".format( self.proxy_ip) self.logger.debug('DELETE request to: {0}'.format(apps_url)) req = self.api_call.delete(apps_url, card=card, verify=False) if req.status_code != 200: raise EyeosAPIError( "Error emptying apps. API response: [ code: {0}, content: {1}]" .format(req.status_code, req.content)) self.logger.info('Apps correctly emptied.') def save(self, apps, card): self.insert_apps(apps['eyeosApps'], card)
class MySQLUserCreator(): def __init__(self): self.settings = Settings().getSettings() self.logger = Logger(__name__) def _get_db_credentials(self, username, domain): if self.settings['general']['multitenant'] == "true": username = username + "_" + domain m = hashlib.sha256() salted_user = username + self.settings['mysql']['user_salt'] m.update(str.encode(salted_user)) mysqlPassword = m.hexdigest() if self.settings['general']['multitenant'] == "true": self.logger.debug( "Creating db and user for mysql with multitenant.") m.update(str.encode(username)) dbname = m.hexdigest() username = dbname[0:16] return (username + "_dbv2", username, mysqlPassword) return (username + "_db", username, mysqlPassword) def create_user(self, username, domain): print("Creating db for", username, domain) dbname, mysqlUsername, mysqlPassword = self._get_db_credentials( username, domain) db = MySQLdb.connect(host=self.settings['mysql']['host'], user="******", passwd=self.settings['mysql']['root_password'], db="mysql") print("Connected to mysql db") with db, db.cursor() as cur: create_stmt = "CREATE USER %(username)s@'%%' IDENTIFIED BY %(password)s;" self.logger.debug("Creating mysql user " + mysqlUsername) cur.execute(create_stmt, { 'username': mysqlUsername, 'password': mysqlPassword }) self.logger.debug("Creating db " + dbname + " with user " + mysqlUsername) cur.execute("CREATE DATABASE `" + dbname + "`;") self.logger.debug("Granting privileges on " + dbname + " to user " + mysqlUsername) cur.execute( "GRANT ALL PRIVILEGES ON `" + dbname + "`.* TO %(username)s@'%%';", {'username': mysqlUsername}) cur.execute("FLUSH PRIVILEGES;") db.commit() print("Created db")
class FileSystem: def __init__(self, injectedSettings=None, injectedSubprocess=None): self.logger = Logger(__name__) self.settings = injectedSettings or Settings().getSettings() self.subprocess = injectedSubprocess or subprocess def clean_filesystem(self): self.logger.info("Cleaning filesystem.") self._clean_files(paths.raw_fs) self.logger.info("Cleaning databases.") self._clean_files(paths.data + "/db") self.logger.info("Cleaning LDAP.") self._clean_files(paths.data + "/ldap") self.logger.info("Cleaning elasticsearch.") self._clean_files(paths.data + "/elasticsearch") self.logger.info("Cleaning MySql.") self._clean_files(paths.data + "/mysql") self.logger.info("Cleaning Seafile Sync Files.") self._clean_files(paths.data + "/seafilesync") self.logger.info("Cleaning Seafile Raw Data.") self._clean_files(paths.data + "/seafileRawData") def _clean_files(self, path): if os.path.isdir(path): shutil.rmtree(path) if not os.path.exists(path): os.makedirs(path) def create_skel(self, username, domain): self.logger.debug("Creating folders for " + username) list_of_dirs = [ "config", "files", "local", "mailbox", "networkdrives", "workgroups" ] if self.settings['general']['multitenant'] == "true": base_path = paths.raw_fs + "/users/" + domain + "/" + username + "/" else: base_path = paths.raw_fs + "/users/" + username + "/" mode = 0o755 for directory in list_of_dirs: os.makedirs(base_path + directory, mode, exist_ok=True) self.logger.debug("Created " + base_path + directory) os.system("chmod 777 " + base_path + "mailbox")
class Logout: def __init__(self, injected_proxy_ip=None, injected_eyeos_api_call=None): self.settings = Settings().getSettings() self.proxy_ip = injected_proxy_ip or self.settings['general']['public_hostname'] self.logger = Logger(__name__) self.eyeos_api_call = injected_eyeos_api_call or EyeosApiCall() def logout(self, card): self.logger.info("Retrieving a valid card...") data = { 'timestamp': int(time.time()) } logout_url = "https://{0}/relay/presence/v1/routingKey/logout/userEvent/logout".format(self.proxy_ip) self.logger.debug('POST request to: {0}'.format(logout_url)) req = self.eyeos_api_call.post(logout_url, verify=False, data=data, card=card) if req.status_code != 200: raise ValueError("Error logging out with user")
class FileSystem: def __init__(self, injectedSettings=None, injectedSubprocess=None): self.logger = Logger(__name__) self.settings = injectedSettings or Settings().getSettings() self.subprocess = injectedSubprocess or subprocess def clean_filesystem(self): self.logger.info("Cleaning filesystem.") self._clean_files(paths.raw_fs) self.logger.info("Cleaning databases.") self._clean_files(paths.data + "/db") self.logger.info("Cleaning LDAP.") self._clean_files(paths.data + "/ldap") self.logger.info("Cleaning elasticsearch.") self._clean_files(paths.data + "/elasticsearch") self.logger.info("Cleaning MySql.") self._clean_files(paths.data + "/mysql") self.logger.info("Cleaning Seafile Sync Files.") self._clean_files(paths.data + "/seafilesync") self.logger.info("Cleaning Seafile Raw Data.") self._clean_files(paths.data + "/seafileRawData") def _clean_files(self, path): if os.path.isdir(path): shutil.rmtree(path) if not os.path.exists(path): os.makedirs(path) def create_skel(self, username, domain): self.logger.debug("Creating folders for " + username) list_of_dirs = ["config", "files", "local", "mailbox", "networkdrives", "workgroups"] if self.settings['general']['multitenant'] == "true": base_path = paths.raw_fs + "/users/" + domain + "/" + username + "/" else: base_path = paths.raw_fs + "/users/" + username + "/" mode = 0o755 for directory in list_of_dirs: os.makedirs(base_path + directory, mode, exist_ok=True) self.logger.debug("Created " + base_path + directory) os.system("chmod 777 " + base_path + "mailbox")
class MySQLUserCreator(): def __init__(self): self.settings = Settings().getSettings() self.logger = Logger(__name__) def _get_db_credentials(self, username, domain): if self.settings['general']['multitenant'] == "true": username = username + "_" + domain m = hashlib.sha256() salted_user = username + self.settings['mysql']['user_salt'] m.update(str.encode(salted_user)) mysqlPassword = m.hexdigest() if self.settings['general']['multitenant'] == "true": self.logger.debug("Creating db and user for mysql with multitenant.") m.update(str.encode(username)) dbname = m.hexdigest() username = dbname[0:16] return (username + "_dbv2", username, mysqlPassword) return (username + "_db", username, mysqlPassword) def create_user(self, username, domain): print("Creating db for", username, domain) dbname, mysqlUsername, mysqlPassword = self._get_db_credentials(username, domain) db = MySQLdb.connect(host=self.settings['mysql']['host'], user="******", passwd=self.settings['mysql']['root_password'], db="mysql") print("Connected to mysql db") with db, db.cursor() as cur: create_stmt = "CREATE USER %(username)s@'%%' IDENTIFIED BY %(password)s;" self.logger.debug("Creating mysql user " + mysqlUsername) cur.execute(create_stmt, {'username': mysqlUsername, 'password': mysqlPassword}) self.logger.debug("Creating db " + dbname + " with user " + mysqlUsername) cur.execute("CREATE DATABASE `" + dbname + "`;") self.logger.debug("Granting privileges on " + dbname + " to user " + mysqlUsername) cur.execute("GRANT ALL PRIVILEGES ON `" + dbname + "`.* TO %(username)s@'%%';", {'username': mysqlUsername}) cur.execute("FLUSH PRIVILEGES;") db.commit() print("Created db")
class Login: def __init__(self, injected_proxy_ip=None, injected_eyeos_api_call=None): self.settings = Settings().getSettings() self.proxy_ip = injected_proxy_ip or self.settings['general'][ 'public_hostname'] self.logger = Logger(__name__) self.eyeos_api_call = injected_eyeos_api_call or EyeosApiCall() def authenticate(self, username, password, domain=False): if not domain: domain = self.settings['general']['default_domain'] self.logger.info("Retrieving a valid card...") data = { 'type': 'Basic', 'username': username, 'password': password, 'domain': domain } auth_url = "https://{0}/login/v1/methods/login/".format(self.proxy_ip) self.logger.debug('POST request to: {0}'.format(auth_url)) req = self.eyeos_api_call.post(auth_url, verify=False, json=data) if req.status_code != 200: raise ValueError( "Error authenticating with user {0} (Check if captcha is preventing access)" .format(data['username'])) try: login_card = req.json() except ValueError as e: raise EyeosAPIError("Error parsing JSON response: {0}".format( req.content)) from e try: return EyeosCard(login_card['card'], login_card['signature']) except KeyError as e: raise EyeosAPIError("Can't retrieve card form login API") from e
class Login: def __init__(self, injected_proxy_ip=None, injected_eyeos_api_call=None): self.settings = Settings().getSettings() self.proxy_ip = injected_proxy_ip or self.settings['general']['public_hostname'] self.logger = Logger(__name__) self.eyeos_api_call = injected_eyeos_api_call or EyeosApiCall() def authenticate(self, username, password, domain=False): if not domain: domain = self.settings['general']['default_domain'] self.logger.info("Retrieving a valid card...") data = { 'type': 'Basic', 'username': username, 'password': password, 'domain': domain } auth_url = "https://{0}/login/v1/methods/login/".format(self.proxy_ip) self.logger.debug('POST request to: {0}'.format(auth_url)) req = self.eyeos_api_call.post(auth_url, verify=False, json=data) if req.status_code != 200: raise ValueError("Error authenticating with user {0} (Check if captcha is preventing access)" .format(data['username'])) try: login_card = req.json() except ValueError as e: raise EyeosAPIError("Error parsing JSON response: {0}".format(req.content)) from e try: return EyeosCard(login_card['card'], login_card['signature']) except KeyError as e: raise EyeosAPIError("Can't retrieve card form login API") from e
class __Ldap: ldap = None def __init__(self, settings=None): self.settings = settings or Settings() self.logger = Logger(__name__) def getInstance(self): settings = self.settings.getSettings() user = settings['ldap']['admin_ldap_username'] password = settings['ldap']['admin_ldap_password'] host = self.settings.getServiceIp('ldap') self.logger.debug("Connecting to " + host + " with user " + user) self.dn_base = settings['ldap']['ldap_cn_base'] server = Server(host, get_info=ALL) self.ldapClient = Connection(server, user=user, password=password, raise_exceptions=True) try: self.ldapClient.bind() except ldap.LDAPSocketOpenError as e: self.logger.error( "Could not connect to LDAP - SocketOpenError: " + str(e)) return self def __enter__(self): return self def __exit__(self, exc_type, exc_val, exc_tb): return self.ldapClient.unbind() def disconnect(self): self.ldapClient.unbind() def createUser(self, user, firstname, lastname, password, email): password = password.encode('utf-8') hashPassword = hashlib.md5() hashPassword.update(password) password = base64.b64encode(hashPassword.digest()) dn = "cn=" + user + "," + self.dn_base attrs = {} attrs['objectClass'] = [ 'inetOrgPerson', 'person', 'top', 'organizationalPerson' ] attrs['cn'] = user attrs['userPassword'] = "******" + password.decode('utf-8') attrs['sn'] = lastname attrs['givenName'] = firstname attrs['mail'] = email try: self.ldapClient.add(dn, attributes=attrs) self.logger.info(self.ldapClient.result) except ldap.LDAPEntryAlreadyExistsResult: self.logger.error("Could not create user, duplicated " + user) return False except Exception as e: self.logger.error("Could not create user: "******"cn=" + user + "," + self.dn_base self.ldapClient.delete(deleteDN) return True def findUser(self, user): self.ldapClient.search( search_base=self.dn_base, search_filter='(&(objectClass=inetOrgPerson)(cn=' + user + '))', search_scope=SUBTREE, attributes=['cn']) usernames = [] for result in self.ldapClient.response: cn = result['attributes']['cn'][0] if cn: usernames.append(cn) return usernames
class __Ldap: ldap = None def __init__(self, settings=None): self.settings = settings or Settings() self.logger = Logger(__name__) def getInstance(self): settings = self.settings.getSettings() user = settings['ldap']['admin_ldap_username'] password = settings['ldap']['admin_ldap_password'] host = self.settings.getServiceIp('ldap') self.logger.debug("Connecting to " + host + " with user " + user) self.dn_base = settings['ldap']['ldap_cn_base'] server = Server(host, get_info=ALL) self.ldapClient = Connection(server, user=user, password=password, raise_exceptions=True) try: self.ldapClient.bind() except ldap.LDAPSocketOpenError as e: self.logger.error("Could not connect to LDAP - SocketOpenError: " + str(e)) return self def __enter__(self): return self def __exit__(self, exc_type, exc_val, exc_tb): return self.ldapClient.unbind() def disconnect(self): self.ldapClient.unbind() def createUser(self, user, firstname, lastname, password, email): password = password.encode('utf-8') hashPassword = hashlib.md5() hashPassword.update(password) password = base64.b64encode(hashPassword.digest()) dn = "cn=" + user + "," + self.dn_base attrs = {} attrs['objectClass'] = ['inetOrgPerson', 'person', 'top', 'organizationalPerson'] attrs['cn'] = user attrs['userPassword'] = "******" + password.decode('utf-8') attrs['sn'] = lastname attrs['givenName'] = firstname attrs['mail'] = email try: self.ldapClient.add(dn, attributes=attrs) self.logger.info(self.ldapClient.result) except ldap.LDAPEntryAlreadyExistsResult: self.logger.error("Could not create user, duplicated " + user) return False except Exception as e: self.logger.error("Could not create user: "******"cn="+user+","+self.dn_base self.ldapClient.delete(deleteDN) return True def findUser(self, user): self.ldapClient.search(search_base=self.dn_base, search_filter='(&(objectClass=inetOrgPerson)(cn=' + user + '))', search_scope=SUBTREE, attributes=['cn']) usernames = [] for result in self.ldapClient.response: cn = result['attributes']['cn'][0] if cn: usernames.append(cn) return usernames
class MailDomain: def __init__(self): self.logger = Logger(__name__) self.settings = Settings().getSettings() def create_domain(self, domain): self._prepare_db() self._prepare_table() self._insert_domain(domain) def domain_exists(self, domain): self._prepare_db() self._prepare_table() db = MySQLdb.connect(host=self.settings['email']['dbhost'], user=self.settings['email']['dbuser'], passwd=self.settings['email']['dbpwd'], db=self.settings['email']['dbname']) with db, db.cursor() as cur: cur.execute("SELECT * FROM domains WHERE domain='" + domain + "';") data = cur.fetchone() if data is not None and data[0] == domain: self.logger.debug('The domain ' + domain + ' exists.') return True else: self.logger.debug('The domain ' + domain + ' don\'t exists.') return False def _prepare_db(self): db = MySQLdb.connect(host=self.settings['mysql']['host'], user="******", passwd=self.settings['mysql']['root_password'], db="mysql") with db, db.cursor() as cur: dbname = self.settings['email']['dbname'] query = "CREATE DATABASE IF NOT EXISTS `" + dbname + "`;" self.logger.debug('Creating database ' + dbname) cur.execute(query) username = self.settings['email']['dbuser'] mysqlpassword = self.settings['email']['dbpwd'] self.logger.debug("Granting privileges on " + dbname + " to user " + username) cur.execute( "GRANT ALL PRIVILEGES ON `" + dbname + "`.* TO %(username)s@'%%' IDENTIFIED BY %(password)s;", { 'username': username, 'password': mysqlpassword }) cur.execute("FLUSH PRIVILEGES;") def _prepare_table(self): db = MySQLdb.connect(host=self.settings['email']['dbhost'], user=self.settings['email']['dbuser'], passwd=self.settings['email']['dbpwd'], db=self.settings['email']['dbname']) with db, db.cursor() as cur: cur.execute( "CREATE TABLE IF NOT EXISTS " "domains (domain varchar(50) NOT NULL,PRIMARY KEY (domain) )ENGINE=MyISAM;" ) def _insert_domain(self, domain): db = MySQLdb.connect(host=self.settings['email']['dbhost'], user=self.settings['email']['dbuser'], passwd=self.settings['email']['dbpwd'], db=self.settings['email']['dbname']) with db, db.cursor() as cur: self.logger.info('Creating domain ' + domain) cur.execute('INSERT INTO domains(domain) VALUES(\"' + domain + '\");')
class MailDomain: def __init__(self): self.logger = Logger(__name__) self.settings = Settings().getSettings() def create_domain(self, domain): self._prepare_db() self._prepare_table() self._insert_domain(domain) def domain_exists(self, domain): self._prepare_db() self._prepare_table() db = MySQLdb.connect(host=self.settings['email']['dbhost'], user=self.settings['email']['dbuser'], passwd=self.settings['email']['dbpwd'], db=self.settings['email']['dbname']) with db, db.cursor() as cur: cur.execute("SELECT * FROM domains WHERE domain='" + domain + "';") data = cur.fetchone() if data is not None and data[0] == domain: self.logger.debug('The domain ' + domain + ' exists.') return True else: self.logger.debug('The domain ' + domain + ' don\'t exists.') return False def _prepare_db(self): db = MySQLdb.connect(host=self.settings['mysql']['host'], user="******", passwd=self.settings['mysql']['root_password'], db="mysql") with db, db.cursor() as cur: dbname = self.settings['email']['dbname'] query = "CREATE DATABASE IF NOT EXISTS `" + dbname + "`;" self.logger.debug('Creating database ' + dbname) cur.execute(query) username = self.settings['email']['dbuser'] mysqlpassword = self.settings['email']['dbpwd'] self.logger.debug("Granting privileges on " + dbname + " to user " + username) cur.execute("GRANT ALL PRIVILEGES ON `" + dbname + "`.* TO %(username)s@'%%' IDENTIFIED BY %(password)s;", {'username': username, 'password': mysqlpassword}) cur.execute("FLUSH PRIVILEGES;") def _prepare_table(self): db = MySQLdb.connect(host=self.settings['email']['dbhost'], user=self.settings['email']['dbuser'], passwd=self.settings['email']['dbpwd'], db=self.settings['email']['dbname']) with db, db.cursor() as cur: cur.execute("CREATE TABLE IF NOT EXISTS " "domains (domain varchar(50) NOT NULL,PRIMARY KEY (domain) )ENGINE=MyISAM;") def _insert_domain(self, domain): db = MySQLdb.connect(host=self.settings['email']['dbhost'], user=self.settings['email']['dbuser'], passwd=self.settings['email']['dbpwd'], db=self.settings['email']['dbname']) with db, db.cursor() as cur: self.logger.info('Creating domain ' + domain) cur.execute('INSERT INTO domains(domain) VALUES(\"' + domain + '\");')