Exemple #1
0
 def __init__(self, usersProvider=None):
     self.logger = Logger(__name__)
     self.userProvider = usersProvider or UsersProvider()
     self.settings = Settings().getSettings()
     self.mysql = MySQLUserCreator()
     self.fs = FileSystem()
     self.mongoForgotPass = MongoForgotPassword()
Exemple #2
0
class CreateDomain:

    def __init__(self):
        self.settings = Settings().getSettings()
        self.logger = Logger(__name__)
        self.domain = Domain()

    def execute(self, *args):
        args = self._parse_arguments(*args)
        args.domain[0] = args.domain[0].lower()
        if self.domain.domain_exists(args.domain[0]) is True:
            self.logger.error("Domain already exists")
            sys.exit(1)
        regex = "^[a-zA-Z0-9][a-zA-Z0-9-_]{0,61}[a-zA-Z0-9]{0,1}\.([a-zA-Z]{1,6}|[a-zA-Z0-9-]{1,30}\.[a-zA-Z]{2,})$"
        pattern = re.compile(regex)
        if not pattern.match(args.domain[0]):
            self.logger.error("The domain you provided is not valid!")
            sys.exit(1)
        self.domain.create_domain(args.domain[0])

    def _parse_arguments(self, command_name, *args):
        parser = ArgumentParser(description='Domains creation',
                                prog='eyeos ' + command_name)
        parser.add_argument('domain', metavar='DOMAIN', nargs=1,
                            help='DNS name of the domain to create')
        args = parser.parse_args(args)
        return args
class CreateDomain:
    def __init__(self):
        self.settings = Settings().getSettings()
        self.logger = Logger(__name__)
        self.domain = Domain()

    def execute(self, *args):
        args = self._parse_arguments(*args)
        args.domain[0] = args.domain[0].lower()
        if self.domain.domain_exists(args.domain[0]) is True:
            self.logger.error("Domain already exists")
            sys.exit(1)
        regex = "^[a-zA-Z0-9][a-zA-Z0-9-_]{0,61}[a-zA-Z0-9]{0,1}\.([a-zA-Z]{1,6}|[a-zA-Z0-9-]{1,30}\.[a-zA-Z]{2,})$"
        pattern = re.compile(regex)
        if not pattern.match(args.domain[0]):
            self.logger.error("The domain you provided is not valid!")
            sys.exit(1)
        self.domain.create_domain(args.domain[0])

    def _parse_arguments(self, command_name, *args):
        parser = ArgumentParser(description='Domains creation',
                                prog='eyeos ' + command_name)
        parser.add_argument('domain',
                            metavar='DOMAIN',
                            nargs=1,
                            help='DNS name of the domain to create')
        args = parser.parse_args(args)
        return args
Exemple #4
0
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)
Exemple #5
0
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)
Exemple #6
0
class UserCreate:
    def __init__(self):
        self.logger = Logger(__name__)
        self.userManagement = UsersManagement()
        self.settings = Settings().getSettings()
        self.domain = Domain()

    def execute(self, *args):
        args = self._parse_arguments(*args)
        args.user[0] = args.user[0].lower()
        if self.validateUsername(args.user[0]) is False:
            self.logger.error("The username '" + args.user[0] + "' contains illegal characters.  "
                              "(A username may only contain letters, numbers, underscores, dashes, and dots)")
            sys.exit(1)
        if self.domain.domain_exists(args.domain) is False:
            self.logger.error("The domain " + args.domain + " does not exist. "
                              "Cannot add user to non existing domain \n"
                              "To create this domain execute: sudo eyeos create-domain " + args.domain)
            sys.exit(1)
        if self.userManagement.createUser(args):
            pass
            # sys.exit(0)
        else:
            sys.exit(1)

    def _parse_arguments(self, command_name, *args):
        parser = ArgumentParser(description='Users creation',
                                prog='eyeos ' + command_name)
        parser.add_argument('user', metavar='USERNAME', nargs=1,
                            help='username of the user to delete')
        parser.add_argument('--domain', metavar='DOMAIN', required=False,
                            default=self.settings['general']['default_domain'],
                            help='Insert the domain of the user')
        parser.add_argument('--firstname', metavar='NAME', default=False,
                            help='Insert the firstname when create a user')
        parser.add_argument('--surname', metavar='SURNAME', required=True,
                            help='Insert the surname when create a user')
        parser.add_argument('--password', metavar='PASSWORD', required=True,
                            help='Insert the password when create a user')
        parser.add_argument('--email', metavar='EMAIL', required=True,
                            help='Insert the email when create a user')
        args = parser.parse_args(args)
        return args

    def validateUsername(self, username):
        regex = re.compile(r"^[a-zA-Z0-9_.-]{4,192}$")
        if regex.match(username) is None:
            return False
        else:
            return True
Exemple #7
0
 def __init__(self, usersProvider=None):
     self.logger = Logger(__name__)
     self.userProvider = usersProvider or UsersProvider()
     self.settings = Settings().getSettings()
     self.mysql = MySQLUserCreator()
     self.fs = FileSystem()
     self.mongoForgotPass = MongoForgotPassword()
Exemple #8
0
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")
Exemple #9
0
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")
Exemple #10
0
 def __init__(self,
              injected_open=None,
              injected_eyeos_apps_storage=None,
              injected_json=None,
              injected_eyeos_apps_validator=None,
              injected_application_api=None,
              injected_principals_api=None,
              injected_base_group=None,
              injected_login_api=None):
     self.eyeos_apps_storage = injected_eyeos_apps_storage or EyeosAppsStorage(
     )
     self.open = injected_open or open
     self.json = injected_json or json
     self.logger = Logger(__name__)
     self.eyeos_apps_validator = injected_eyeos_apps_validator or EyeosAppsJsonValidator(
     )
     self.application_api = injected_application_api or Application()
     self.principals_api = injected_principals_api or Principals()
     self.principal_base_group = injected_base_group or Settings(
     ).getSettings()['principalservice']['base_group']
     self.login_api = injected_login_api or Login()
Exemple #11
0
class WaitForEyeos:
    def __init__(self):
        self.settings = Settings()
        self.logger = Logger(__name__)
        self.entrypoint = "proxy"

    def wait(self, timeout):
        logging.getLogger("requests").setLevel(logging.ERROR)
        starttime = time.time()
        while True:
            now = time.time()
            if now - starttime > timeout:
                raise TimeoutError("Wait timed out")
            try:
                ip = self.settings.getServiceIp(self.entrypoint)
                requests.get('http://{0}'.format(ip), verify=False)
                time.sleep(5)
                self.logger.info("Waited for {0} seconds".format(int(now - starttime)))
                break
            except (UnknownHostError, requests.exceptions.RequestException) as e:
                time.sleep(0.5)
                continue
Exemple #12
0
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
Exemple #13
0
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")
Exemple #14
0
class WaitForEyeos:
    def __init__(self):
        self.settings = Settings()
        self.logger = Logger(__name__)
        self.entrypoint = "proxy"

    def wait(self, timeout):
        logging.getLogger("requests").setLevel(logging.ERROR)
        starttime = time.time()
        while True:
            now = time.time()
            if now - starttime > timeout:
                raise TimeoutError("Wait timed out")
            try:
                ip = self.settings.getServiceIp(self.entrypoint)
                requests.packages.urllib3.disable_warnings()
                requests.get('http://{0}'.format(ip), verify=False)
                time.sleep(5)
                self.logger.info("Waited for {0} seconds".format(int(now - starttime)))
                break
            except (UnknownHostError, requests.exceptions.RequestException) as e:
                time.sleep(0.5)
                continue
Exemple #15
0
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
Exemple #16
0
 def __init__(self, injected_open=None, injected_eyeos_apps_storage=None, injected_json=None,
              injected_eyeos_apps_validator=None,
              injected_application_api=None,
              injected_principals_api=None,
              injected_base_group=None,
              injected_login_api=None):
     self.eyeos_apps_storage = injected_eyeos_apps_storage or EyeosAppsStorage()
     self.open = injected_open or open
     self.json = injected_json or json
     self.logger = Logger(__name__)
     self.eyeos_apps_validator = injected_eyeos_apps_validator or EyeosAppsJsonValidator()
     self.application_api = injected_application_api or Application()
     self.principals_api = injected_principals_api or Principals()
     self.principal_base_group = injected_base_group or Settings().getSettings()['principalservice']['base_group']
     self.login_api = injected_login_api or Login()
Exemple #17
0
 def __init__(self, injectedSettings=None, injectedSubprocess=None):
     self.logger = Logger(__name__)
     self.settings = injectedSettings or Settings().getSettings()
     self.subprocess = injectedSubprocess or subprocess
Exemple #18
0
 def __init__(self):
     self.settings = Settings()
     self.logger = Logger(__name__)
     self.entrypoint = "proxy"
Exemple #19
0
    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
Exemple #20
0
class UsersManagement:

    def __init__(self, usersProvider=None):
        self.logger = Logger(__name__)
        self.userProvider = usersProvider or UsersProvider()
        self.settings = Settings().getSettings()
        self.mysql = MySQLUserCreator()
        self.fs = FileSystem()
        self.mongoForgotPass = MongoForgotPassword()

    def createUser(self, args):
        with self.userProvider.connect() as usersClient:
            if self.settings['general']['multitenant'] == "true":
                email = args.user[0] + '@' + args.domain
                username = args.user[0] + '@' + args.domain
            else:
                email = args.user[0] + '@' + self.settings['email']['domain']
                username = args.user[0]
            ret = usersClient.createUser(username, args.firstname, args.surname, args.password, email)
            if ret:
                self.logger.info("User created")
                self.mysql.create_user(args.user[0], args.domain)
                self.fs.create_skel(args.user[0], args.domain)
                self.mongoForgotPass.insert_user(args.user[0], args.email, args.domain)

                login_api = Login()
                logout_api = Logout()

                eyeos_card = login_api.authenticate(args.user[0], args.password, args.domain)
                self.logger.info("Logged in as user")
                logout_api.logout(eyeos_card)

            return ret

    def _send_welcome_email(self, args, email):
        with open('lib/Users/welcome_email/text', 'r') as content:
            plain_content = content.read()
        with open('lib/Users/welcome_email/html.html', 'r') as content:
            html_content = content.read()
        with open('lib/Users/welcome_email/subject', 'r') as content:
            subject = content.read()

        email_from = email
        email_to = email
        smtp_host = self.settings['email']['smtp_host']

    def deleteUser(self, args):
        try:
            with self.userProvider.connect() as usersClient:
                usersClient.deleteUser(args.user[0])
                self.logger.info("Delete user")
                return True
        except Exception as e:
            self.logger.error("Could not delete user")
            return False

    def findUser(self, args):
        try:
            with self.userProvider.connect() as usersClient:
                usernames = usersClient.findUser(args.user[0])
                self.logger.info("Found {0} users matching '{1}'".format(len(usernames), args.user[0]))
                for user in usernames:
                    print(user)
                return True
        except Exception as e:
            self.logger.info("Does not match any entries")
            return False
Exemple #21
0
 def __init__(self, injectedSettings=None, injectedSubprocess=None):
     self.logger = Logger(__name__)
     self.settings = injectedSettings or Settings().getSettings()
     self.subprocess = injectedSubprocess or subprocess
Exemple #22
0
class EyeosApps:

    DEFAULT_APPS_DIR = './eyeos_apps/default'

    def __init__(self,
                 injected_open=None,
                 injected_eyeos_apps_storage=None,
                 injected_json=None,
                 injected_eyeos_apps_validator=None,
                 injected_application_api=None,
                 injected_principals_api=None,
                 injected_base_group=None,
                 injected_login_api=None):
        self.eyeos_apps_storage = injected_eyeos_apps_storage or EyeosAppsStorage(
        )
        self.open = injected_open or open
        self.json = injected_json or json
        self.logger = Logger(__name__)
        self.eyeos_apps_validator = injected_eyeos_apps_validator or EyeosAppsJsonValidator(
        )
        self.application_api = injected_application_api or Application()
        self.principals_api = injected_principals_api or Principals()
        self.principal_base_group = injected_base_group or Settings(
        ).getSettings()['principalservice']['base_group']
        self.login_api = injected_login_api or Login()

    def install(self, apps_directory, admin_user, password, domain):
        apps_file = apps_directory + '/apps.json'

        with self.open(apps_file, 'r') as f:
            try:
                apps = self.json.load(f)
            except ValueError as e:
                raise ValueError("File {0} does not contain valid JSON".format(
                    apps_file)) from e

        self.eyeos_apps_validator.validate(apps)

        try:
            eyeos_card = self.login_api.authenticate(admin_user, password,
                                                     domain)
            self.logger.info('Emptying previous apps...')
            self.application_api.empty_apps(eyeos_card)
            self.logger.info('Saving apps...')
            self.eyeos_apps_storage.save(apps)
            self.application_api.save(apps, eyeos_card)
            group = self.principals_api.get_systemgroup(
                self.principal_base_group, eyeos_card)
            group = self._generate_new_permissions(apps, group)
            self.principals_api.put_systemgroup(group, eyeos_card)

        except (ValueError, KeyError, EyeosAPIError) as e:
            self.logger.error(e)
            exit(1)

    def _generate_new_permissions(self, applications, group):
        """ existing permissions like eyeos.application.* should be removed
        and then add new eyeos.applications.whatever permissions for each eyeos_apps applications.
        permissions like eyeos.admin.*.edit should be removed and add new ones from the
        control_panel applications

        the eyeos.admin.*.edit permissions might pose a problem in the future if there appear new
        permissions not tied to an application. That's a problem for future everyone :S
        """

        permissions = group['permissions']

        i = 0
        while i < len(permissions):
            permission = permissions[i]
            if (re.match(r'^eyeos\.application\.[^.]*$', permission['id'])
                    or re.match(r'^eyeos\.admin\.[^.]*\.edit$',
                                permission['id'])):
                permissions.remove(permission)
                continue
            i += 1

        for eyeos_application in applications['eyeosApps']:
            permissions.append({
                "id":
                "eyeos.application." + eyeos_application['appID'],
                "name":
                'Execute ' + eyeos_application['name'],
                "description":
                "Run " + eyeos_application['name'] + " application",
                "enabled":
                True
            })
        for admin_application in applications['controlPanelApps']:
            permissions.append({
                "id":
                "eyeos.admin." + admin_application['appID'] + '.edit',
                "name":
                'Manage ' + admin_application['name'],
                "description":
                "Manage " + admin_application['name'] + " in admin panel",
                "enabled":
                False
            })

        return group
Exemple #23
0
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 +
                        '\");')
Exemple #24
0
class UsersManagement:
    def __init__(self, usersProvider=None):
        self.logger = Logger(__name__)
        self.userProvider = usersProvider or UsersProvider()
        self.settings = Settings().getSettings()
        self.mysql = MySQLUserCreator()
        self.fs = FileSystem()
        self.mongoForgotPass = MongoForgotPassword()

    def createUser(self, args):
        with self.userProvider.connect() as usersClient:
            if self.settings['general']['multitenant'] == "true":
                email = args.user[0] + '@' + args.domain
                username = args.user[0] + '@' + args.domain
            else:
                email = args.user[0] + '@' + self.settings['email']['domain']
                username = args.user[0]
            ret = usersClient.createUser(username, args.firstname,
                                         args.surname, args.password, email)
            if ret:
                self.logger.info("User created")
                self.mysql.create_user(args.user[0], args.domain)
                self.fs.create_skel(args.user[0], args.domain)
                self.mongoForgotPass.insert_user(args.user[0], args.email,
                                                 args.domain)

                login_api = Login()
                logout_api = Logout()

                eyeos_card = login_api.authenticate(args.user[0],
                                                    args.password, args.domain)
                self.logger.info("Logged in as user")
                logout_api.logout(eyeos_card)

            return ret

    def _send_welcome_email(self, args, email):
        with open('lib/Users/welcome_email/text', 'r') as content:
            plain_content = content.read()
        with open('lib/Users/welcome_email/html.html', 'r') as content:
            html_content = content.read()
        with open('lib/Users/welcome_email/subject', 'r') as content:
            subject = content.read()

        email_from = email
        email_to = email
        smtp_host = self.settings['email']['smtp_host']

    def deleteUser(self, args):
        try:
            with self.userProvider.connect() as usersClient:
                usersClient.deleteUser(args.user[0])
                self.logger.info("Delete user")
                return True
        except Exception as e:
            self.logger.error("Could not delete user")
            return False

    def findUser(self, args):
        try:
            with self.userProvider.connect() as usersClient:
                usernames = usersClient.findUser(args.user[0])
                self.logger.info("Found {0} users matching '{1}'".format(
                    len(usernames), args.user[0]))
                for user in usernames:
                    print(user)
                return True
        except Exception as e:
            self.logger.info("Does not match any entries")
            return False
Exemple #25
0
 def __init__(self, settings=None):
     self.settings = settings or Settings()
     self.logger = Logger(__name__)
Exemple #26
0
 def __init__(self):
     self.logger = Logger(__name__)
     self.userManagement = UsersManagement()
     self.settings = Settings().getSettings()
     self.domain = Domain()
Exemple #27
0
class EyeosApps:

    DEFAULT_APPS_DIR = './eyeos_apps/default'

    def __init__(self, injected_open=None, injected_eyeos_apps_storage=None, injected_json=None,
                 injected_eyeos_apps_validator=None,
                 injected_application_api=None,
                 injected_principals_api=None,
                 injected_base_group=None,
                 injected_login_api=None):
        self.eyeos_apps_storage = injected_eyeos_apps_storage or EyeosAppsStorage()
        self.open = injected_open or open
        self.json = injected_json or json
        self.logger = Logger(__name__)
        self.eyeos_apps_validator = injected_eyeos_apps_validator or EyeosAppsJsonValidator()
        self.application_api = injected_application_api or Application()
        self.principals_api = injected_principals_api or Principals()
        self.principal_base_group = injected_base_group or Settings().getSettings()['principalservice']['base_group']
        self.login_api = injected_login_api or Login()

    def install(self, apps_directory, admin_user, password, domain):
        apps_file = apps_directory + '/apps.json'

        with self.open(apps_file, 'r') as f:
            try:
                apps = self.json.load(f)
            except ValueError as e:
                raise ValueError("File {0} does not contain valid JSON".format(apps_file)) from e

        self.eyeos_apps_validator.validate(apps)

        try:
            eyeos_card = self.login_api.authenticate(admin_user, password, domain)
            self.logger.info('Emptying previous apps...')
            self.application_api.empty_apps(eyeos_card)
            self.logger.info('Saving apps...')
            self.eyeos_apps_storage.save(apps)
            self.application_api.save(apps, eyeos_card)
            group = self.principals_api.get_systemgroup(self.principal_base_group, eyeos_card)
            group = self._generate_new_permissions(apps, group)
            self.principals_api.put_systemgroup(group, eyeos_card)

        except (ValueError, KeyError, EyeosAPIError) as e:
            self.logger.error(e)
            exit(1)

    def _generate_new_permissions(self, applications, group):
        """ existing permissions like eyeos.application.* should be removed
        and then add new eyeos.applications.whatever permissions for each eyeos_apps applications.
        permissions like eyeos.admin.*.edit should be removed and add new ones from the
        control_panel applications

        the eyeos.admin.*.edit permissions might pose a problem in the future if there appear new
        permissions not tied to an application. That's a problem for future everyone :S
        """

        permissions = group['permissions']

        i = 0
        while i < len(permissions):
            permission = permissions[i]
            if (re.match(r'^eyeos\.application\.[^.]*$', permission['id']) or
                    re.match(r'^eyeos\.admin\.[^.]*\.edit$', permission['id'])):
                permissions.remove(permission)
                continue
            i += 1

        for eyeos_application in applications['eyeosApps']:
            permissions.append({
                "id": "eyeos.application." + eyeos_application['appID'],
                "name": 'Execute ' + eyeos_application['name'],
                "description": "Run " + eyeos_application['name'] + " application",
                "enabled": True
            })
        for admin_application in applications['controlPanelApps']:
            permissions.append({
                "id": "eyeos.admin." + admin_application['appID'] + '.edit',
                "name": 'Manage ' + admin_application['name'],
                "description": "Manage " + admin_application['name'] + " in admin panel",
                "enabled": False
            })

        return group
Exemple #28
0
 def __init__(self, proxy_ip=None, injected_eyeos_api_call=None):
     self.proxy_ip = proxy_ip or Settings().getServiceIp('proxy')
     self.systemgroups_url = 'https://{0}/systemgroups/v1/systemgroups'.format(
         self.proxy_ip)
     self.logger = Logger(__name__)
     self.eyeos_api_call = injected_eyeos_api_call or EyeosApiCall()
Exemple #29
0
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")
Exemple #30
0
 def __init__(self):
     self.settings = Settings().getSettings()
     self.logger = Logger(__name__)
Exemple #31
0
 def __init__(self):
     self.logger = Logger(__name__)
     self.settings = Settings().getSettings()
Exemple #32
0
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 + '\");')
Exemple #33
0
 def __init__(self, subprocess=None):
     self.logger = Logger(__name__)
     self.subprocess = subprocess or global_subprocess
Exemple #34
0
 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__)
Exemple #35
0
 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()
Exemple #36
0
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")
        self.logger.debug("Cleaning PIM Raw Data.")
        self._clean_files(paths.data + "/pim")

    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")
        os.chown(base_path + "mailbox",
                 int(self.settings['email']['mailbox_owner_uid']),
                 int(self.settings['email']['mailbox_owner_gid']))
Exemple #37
0
 def __init__(self):
     self.settings = Settings()
     self.logger = Logger(__name__)
     self.entrypoint = "proxy"
Exemple #38
0
 def __init__(self):
     self.logger = Logger(__name__)
     self.userManagement = UsersManagement()
     self.settings = Settings().getSettings()
     self.domain = Domain()
Exemple #39
0
 def __init__(self):
     self.logger = Logger(__name__)
     self.mail = MailDomain()
Exemple #40
0
 def __init__(self, settings=None):
     self.settings = settings or Settings()
     self.logger = Logger(__name__)
Exemple #41
0
 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 __init__(self):
     self.logger = Logger(__name__)
     self.ldap = Ldap()
 def __init__(self, devenvExecutor=None, instanceResolver=None):
     self.instanceResolver = instanceResolver or InstanceResolver()
     self.logger = Logger(__name__)
Exemple #44
0
    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
Exemple #45
0
class UserCreate:
    def __init__(self):
        self.logger = Logger(__name__)
        self.userManagement = UsersManagement()
        self.settings = Settings().getSettings()
        self.domain = Domain()

    def execute(self, *args):
        args = self._parse_arguments(*args)
        args.user[0] = args.user[0].lower()
        if self.validateUsername(args.user[0]) is False:
            self.logger.error(
                "The username '" + args.user[0] +
                "' contains illegal characters.  "
                "(A username may only contain letters, numbers, underscores, dashes, and dots)"
            )
            sys.exit(1)
        if self.domain.domain_exists(args.domain) is False:
            self.logger.error(
                "The domain " + args.domain + " does not exist. "
                "Cannot add user to non existing domain \n"
                "To create this domain execute: sudo eyeos create-domain " +
                args.domain)
            sys.exit(1)
        if self.userManagement.createUser(args):
            pass
            # sys.exit(0)
        else:
            sys.exit(1)

    def _parse_arguments(self, command_name, *args):
        parser = ArgumentParser(description='Users creation',
                                prog='eyeos ' + command_name)
        parser.add_argument('user',
                            metavar='USERNAME',
                            nargs=1,
                            help='username of the user to delete')
        parser.add_argument('--domain',
                            metavar='DOMAIN',
                            required=False,
                            default=self.settings['general']['default_domain'],
                            help='Insert the domain of the user')
        parser.add_argument('--firstname',
                            metavar='NAME',
                            default=False,
                            help='Insert the firstname when create a user')
        parser.add_argument('--surname',
                            metavar='SURNAME',
                            required=True,
                            help='Insert the surname when create a user')
        parser.add_argument('--password',
                            metavar='PASSWORD',
                            required=True,
                            help='Insert the password when create a user')
        parser.add_argument('--email',
                            metavar='EMAIL',
                            required=True,
                            help='Insert the email when create a user')
        args = parser.parse_args(args)
        return args

    def validateUsername(self, username):
        regex = re.compile(r"^[a-zA-Z0-9_.-]{4,192}$")
        if regex.match(username) is None:
            return False
        else:
            return True