Exemplo n.º 1
0
    def checkProjectsAuthorization(self, user, projectId):
        """
        Check if the project id provided is authorized for the user
        """
        # search the user in the cache
        if user not in UsersManager.instance().cache():
            self.error('Check project access for Login=%s not found in cache' %
                       (user))
            return False

        # check if the provided project id is authorized for the user
        granted = False
        user_profile = UsersManager.instance().cache()[user]

        # new exception for administrator
        # project is granted to all projects
        if user_profile['administrator']:
            granted = True
        else:
            for p in user_profile['projects']:
                if int(p) == int(projectId):
                    granted = True
                    break

        # return the final result
        self.trace(
            'Check project access for Login=%s and ProjectID=%s Result=%s' %
            (user, projectId, str(granted)))
        return granted
Exemplo n.º 2
0
    def getProjects(self, user):
        """
        Return projects
        """
        # search the user in the cache
        if user not in UsersManager.instance().cache():
            self.error('Get project for Login=%s not found in cache' % (user))
            return False

        # exception added for administrator
        # an administrator can see all projects
        if UsersManager.instance().cache()[user]['administrator']:
            projects_list = []
            for p in self.cache():
                projects_dict = {}
                projects_dict['project_id'] = int(p['id'])
                projects_dict['name'] = p['name']
                projects_list.append(projects_dict)
        else:
            user_projects = UsersManager.instance().cache()[user]['projects']

            projects_list = []
            for p in user_projects:
                projects_dict = {}
                projects_dict['project_id'] = int(p)
                projects_dict['name'] = self.getProjectName(prjId=int(p))
                projects_list.append(projects_dict)

        return projects_list
    def apiBasicAuthorization(self, authorization):
        """
        Check authorization for rest api
        New version in v17
        """
        if authorization.startswith("Basic "):
            try:
                encoded = authorization.split("Basic ")[1].strip()

                if sys.version_info < (3, ):
                    decoded = base64.b64decode(encoded)
                else:
                    decoded = base64.b64decode(encoded.encode())
                    decoded = decoded.decode()
                self.trace("Basic Auth decoded: %s" % decoded)
                apikey_id, apikey_secret = decoded.rsplit(":", 1)

                usersDb = UsersManager.instance().cache()
                userOk = None
                for _, profile in usersDb.items():
                    if profile["apikey_id"] == apikey_id and profile[
                            "apikey_secret"] == apikey_secret:
                        userOk = profile
                        break
                return userOk

            except Exception as e:
                self.error("unable to decode authorization: %s" % e)
            return None
        return None
Exemplo n.º 4
0
    def getProjects(self, user):
        """
        Return projects
        """
        # search the user in the cache
        if user not in UsersManager.instance().cache():
            self.error('Get project for Login=%s not found in cache' % (user))
            return False

        user_projects = UsersManager.instance().cache()[user]['projects']
        projects_list = []
        for p in user_projects:
            projects_dict = {}
            projects_dict['project_id'] = int(p)
            projects_dict['name'] = self.getProjectName(prjId=int(p))
            projects_list.append(projects_dict)

        return projects_list
    def unregisterChannelUser(self, login):
        """
        Force channel disconnection
        """
        self.info("Unregister user Login=%s" % login)
        UsersManager.instance().setOnlineStatus(login=login, online=False)
        if login not in self.usersConnected:
            self.trace("User=%s to unregister not found" % login)
            return self.CODE_NOT_FOUND

        user_profile = self.usersConnected[login]

        # close the network link with the client if exists
        if user_profile['address'] in ESI.instance().clients:
            ESI.instance().stopClient(client=user_profile['address'])
        else:
            self.usersConnected.pop(login)

        return self.CODE_OK
    def hupHandler(self, signum, frame):
        """
        Hup handler
        """
        self.info('Reloading configuration...')

        # reload settings ini
        Settings.finalize()
        Settings.initialize()

        # reload config from database
        Context.instance().readConfigDb()

        # reconfigure the level of log message
        Logger.reconfigureLevel()

        # reload cache
        UsersManager.instance().loadCache()

        self.info('Configuration reloaded!')
    def unregisterUser(self, user):
        """
        Deletes user, disconnection

        @param user: channel-id (ip, port)
        @type user: tuple
        """
        userLogin = None
        for cur_user in self.usersConnected:
            if self.usersConnected[cur_user]['address'] == user:
                userLogin = self.usersConnected[cur_user]['profile']['login']
                break
        if userLogin is None:
            self.trace('client %s not connected' % str(user))
        else:
            user_removed = self.usersConnected.pop(userLogin)
            self.info("Conn id %s: User (%s,  %s) unregistered" %
                      (user_removed['connection-id'], user_removed['address'],
                       userLogin))

            # update db
            UsersManager.instance().setOnlineStatus(login=userLogin,
                                                    online=False)
    def registerUser(self, user):
        """
        Adds new user, new connection

        @param user: user description
        @type user: dict
        """
        connStart = time.time()
        connId = self.getUniqueId()

        # user = {'address' : client, <user>:{},  'profile': <user profile>}
        self.usersConnected[user['profile']['login']] = user
        self.usersConnected[user['profile']
                            ['login']]['connected-at'] = connStart
        self.usersConnected[user['profile']['login']]['connection-id'] = connId

        self.info("User Registered: ConnID=%s Addr=%s Login=%s" %
                  (connId, user['address'], user['profile']['login']))

        # update db
        UsersManager.instance().setOnlineStatus(login=user['profile']['login'],
                                                online=True)

        return True
Exemplo n.º 9
0
    def getDefaultProjectForUser(self, user):
        """
        Get default project of the user passed as argument
        """
        pid = 1
        found = False

        for u, profile in UsersManager.instance().cache().items():
            if u == user:
                pid = profile['defaultproject']
                found = True
                break

        if not found:
            self.error('no default project returned for User=%s' % user)
        self.trace('Get default project for User=%s Result=%s' % (user, pid))
        return pid
    def apiAuthorization(self, login, password):
        """
        Check authorization for rest api
        """
        self.trace('Rest authorization called for Login=%s' % (login))
        expires = ''

        # check if this login exists on the database
        cache_users = UsersManager.instance().cache()
        if login not in cache_users:
            self.trace("Login=%s account not found" % login)
            return (self.CODE_NOT_FOUND, expires)

        user_profile = cache_users[login]

        # account disable ?
        if not user_profile['active']:
            self.trace("%s account not active" % login)
            return (self.CODE_DISABLED, expires)

        # 2 methods to authenticate the user
        # make a hash of the password and look inside the server
        # or communicate with a remote ldap authenticator

        if Settings.getInt('Users_Session',
                           'ldap-authbind') and LDAP_INSTALLED:
            auth_success = self.doLdapAuth(login, password)
            if not auth_success:
                self.trace("ldap auth failed for %s account" % login)
                return (self.CODE_FAILED, expires)

        elif Settings.getInt('Users_Session',
                             'ldap-authbind') and not LDAP_INSTALLED:
            self.error("python ldap3 library is not installed on your system")
            return (self.CODE_FAILED, expires)

        else:
            # check password, create a sha1 hash with salt: sha1(salt +
            # sha1(password))
            sha0 = hashlib.sha1()
            sha0.update(password.encode('utf8'))

            sha1 = hashlib.sha1()
            _pwd = "%s%s" % (self.cfg_db["auth-salt"], sha0.hexdigest())
            sha1.update(_pwd.encode('utf8'))

            sha3 = hashlib.sha1()
            _pwd2 = "%s%s" % (self.cfg_db["auth-salt"],
                              password.encode('utf8'))
            sha3.update(_pwd2.encode('utf8'))

            pwd_matched = False
            if user_profile['password'] == sha1.hexdigest():
                pwd_matched = True
            # keep this mode only for backward compatibility
            if user_profile['password'] == sha3.hexdigest():
                pwd_matched = True

            if not pwd_matched:
                self.trace("incorrect password for %s account" % login)
                return (self.CODE_FAILED, expires)

        session_id = self.generateSessionid()
        user_profile['last_activity'] = time.time()

        lease = int(Settings.get('Users_Session',
                                 'max-expiry-age'))  # in seconds
        end = time.gmtime(user_profile['last_activity'] + lease)
        expires = time.strftime("%a, %d-%b-%Y %T GMT", end)

        self.userSessions.update({session_id: user_profile})

        self.trace('Rest authorized for Login=%s SessionId=%s Expires=%s' %
                   (login, session_id, expires))
        return (session_id, expires)
    def cleanup(self):
        """
        Cleanup the server
        """
        self.info('Cleanup...')

        self.trace("Cleanup agent manager")
        try:
            AgentsManager.finalize()
        except Exception:
            pass

        self.trace("Cleanup context")
        try:
            Context.finalize()
        except Exception:
            pass

        self.trace("Cleanup projects manager")
        try:
            ProjectsManager.finalize()
        except Exception:
            pass

        self.trace("Cleanup users manager")
        try:
            UsersManager.finalize()
        except Exception:
            pass

        self.trace("Cleanup task manager")
        try:
            TaskManager.finalize()
        except Exception:
            pass

        self.trace("Cleanup test public manager")
        try:
            RepoPublic.finalize()
        except Exception:
            pass

        self.trace("Cleanup test repo manager")
        try:
            RepoTests.finalize()
        except Exception:
            pass

        self.trace("Cleanup test archives manager")
        try:
            RepoArchives.finalize()
        except Exception:
            pass

        self.trace("Cleanup helper manager")
        try:
            HelperManager.finalize()
        except Exception:
            pass

        self.trace("Cleanup adapters manager")
        try:
            RepoAdapters.finalize()
        except Exception:
            pass

        self.trace("Cleanup adapters data storage")
        try:
            StorageDataAdapters.finalize()
        except Exception:
            pass

        self.trace("Cleanup WSU")
        try:
            RestServerInterface.instance().stop()
            RestServerInterface.finalize()
        except Exception:
            pass

        self.trace("Cleanup ESI")
        try:
            EventServerInterface.instance().stopSA()
            EventServerInterface.finalize()
        except Exception:
            pass

        self.trace("Cleanup TSI")
        try:
            TestServerInterface.instance().stopSA()
            TestServerInterface.finalize()
        except Exception:
            pass

        self.trace("Cleanup ASI")
        try:
            AgentServerInterface.instance().stopSA()
            AgentServerInterface.finalize()
        except Exception:
            pass

        self.trace("Cleanup db manager")
        try:
            DbManager.finalize()
        except Exception:
            pass

        self.trace("Cleanup settings")
        try:
            Settings.finalize()
        except Exception:
            pass

        self.trace("Cleanup logger, cli")
        try:
            CliFunctions.finalize()
            Logger.finalize()
        except Exception:
            pass
    def initialize(self):
        """
        Starts all modules
        Exit if the service is alreayd running or if the config file is missing
        """
        starttime = time.time()
        if self.isrunning():
            sys.stdout.write(" (server is already running)")
            sys.exit(1)

        # run the server as daemon only for linux
        if platform.system() == "Linux":
            self.daemonize()

        try:
            # Initialize
            self.info("Starting up server...")
            self.trace("** System encoding (in): %s" % sys.stdin.encoding)
            self.trace("** System encoding (out): %s" % sys.stdout.encoding)
            self.info("Settings, Logger and CLI ready")

            DbManager.initialize()
            DbManager.instance().isUp()
            self.info("Database manager ready")

            # Initialize the core
            Context.initialize()
            self.info("Context ready")

            ProjectsManager.initialize(context=Context.instance())
            self.info("Projects Manager ready")
            UsersManager.initialize(context=Context.instance())
            self.info("Users Manager ready")

            TaskManager.initialize(context=Context)
            self.info("Task Manager ready")

            # Initialize all repositories
            RepoTests.initialize(context=Context.instance())
            self.info("Repo manager for tests ready")
            RepoArchives.initialize(context=Context.instance())
            self.info("Repo manager for archives ready")
            RepoAdapters.initialize(context=Context.instance())
            StorageDataAdapters.initialize(context=Context.instance())
            self.info("Adapters Manager and Storage Data ready")
            RepoPublic.initialize()
            self.info("Repo manager for public area is ready")

            HelperManager.initialize()
            self.info("Helper manager ready")

            AgentsManager.initialize(context=Context.instance())
            self.info("Agents Manager ready")

            # Initialize all interfaces
            self.info("Starting ESI on %s:%s" % (Settings.get('Bind', 'ip-esi'),
                                                 Settings.getInt('Bind', 'port-esi')))
            EventServerInterface.initialize(listeningAddress=(Settings.get('Bind', 'ip-esi'),
                                                              Settings.getInt(
                'Bind', 'port-esi')
            ),
                sslSupport=Settings.getInt(
                'Client_Channel', 'channel-ssl'),
                wsSupport=Settings.getInt(
                'Client_Channel', 'channel-websocket-support'),
                context=Context.instance()
            )
            self.info("Starting TSI on %s:%s" % (Settings.get('Bind', 'ip-tsi'),
                                                 Settings.getInt('Bind', 'port-tsi')))
            TestServerInterface.initialize(listeningAddress=(Settings.get('Bind', 'ip-tsi'),
                                                             Settings.getInt(
                                                                 'Bind', 'port-tsi')
                                                             ),
                                           context=Context.instance()
                                           )
            self.info("Starting RSU on %s:%s" % (Settings.get('Bind', 'ip-rsi'),
                                                 Settings.getInt('Bind', 'port-rsi')))
            RestServerInterface.initialize(listeningAddress=(Settings.get('Bind', 'ip-rsi'),
                                                             Settings.getInt(
                'Bind', 'port-rsi')
            )
            )
            self.info("Starting ASI on %s:%s" % (Settings.get('Bind', 'ip-asi'),
                                                 Settings.getInt('Bind', 'port-asi')))
            AgentServerInterface.initialize(listeningAddress=(Settings.get('Bind', 'ip-asi'),
                                                              Settings.getInt(
                'Bind', 'port-asi')
            ),
                sslSupport=Settings.getInt(
                'Agent_Channel', 'channel-ssl'),
                wsSupport=Settings.getInt(
                'Agent_Channel', 'channel-websocket-support'),
                tsi=TestServerInterface.instance(),
                context=Context.instance()
            )

            # Start on modules
            RestServerInterface.instance().start()
            self.info("RSI is listening on tcp://%s:%s" % (Settings.get('Bind', 'ip-rsi'),
                                                           Settings.get('Bind', 'port-rsi')))
            EventServerInterface.instance().startSA()
            self.info("ESI is listening on tcp://%s:%s" % (Settings.get('Bind', 'ip-esi'),
                                                           Settings.get('Bind', 'port-esi')))
            TestServerInterface.instance().startSA()
            self.info("TSI is listening on tcp://%s:%s" % (Settings.get('Bind', 'ip-tsi'),
                                                           Settings.get('Bind', 'port-tsi')))
            AgentServerInterface.instance().startSA()
            self.info("ASI is listening on tcp://%s:%s" % (Settings.get('Bind', 'ip-asi'),
                                                           Settings.get('Bind', 'port-asi')))

            # Now start the scheduler and reload tasks
            taskReloaded = TaskManager.instance().loadBackups()
            if taskReloaded is None:
                self.info("Reload tasks disabled")
            elif taskReloaded:
                self.info("Tasks reloaded")
            else:
                self.error("Failed to reload tasks")

        except Exception as e:
            self.error("Unable to start server: %s" % str(e))
            self.cleanup()
            sys.exit(3)

        stoptime = time.time()
        self.info("%s successfully started (in %s sec.)" % (Settings.get('Server', 'name'),
                                                            int(stoptime - starttime)))

        # only for windows platform
        if platform.system() == "Windows":
            print("Server successfully started...")

        self.setrunning()
        self.run()