Exemplo n.º 1
0
    def getMeta(self, user, srcIp, os, idMetaPool):
        logger.debug('This is meta')
        # We need to locate the service pool related to this meta, and also the transport
        # First, locate if there is a service in any pool associated with this metapool
        meta = MetaPool.objects.get(uuid=idMetaPool)

        # If access is denied by calendar...
        if meta.isAccessAllowed() is False:
            raise ServiceAccessDeniedByCalendar()

        # Sort pools based on meta selection
        if meta.policy == MetaPool.PRIORITY_POOL:
            pools = [(p.priority, p.pool) for p in meta.members.all()]
        elif meta.policy == MetaPool.MOST_AVAILABLE_BY_NUMBER:
            pools = [(p.usage(), p) for p in meta.pools.all()]
        else:
            pools = [(random.randint(0, 10000), p) for p in meta.pools.all()]

        # Sort pools related to policy now, and xtract only pools, not sort keys
        # Remove "full" pools (100%) from result and pools in maintenance mode, not ready pools, etc...
        pools = [
            p[1] for p in sorted(pools, key=lambda x: x[0])
            if p[1].usage() < 100 and p[1].isUsable()
        ]

        logger.debug('Pools: %s', pools)

        usable = None

        # Now, Lets find first if there is one assigned in ANY pool

        def ensureTransport(pool):
            usable = None
            for t in pool.transports.all().order_by('priority'):
                typeTrans = t.getType()
                if t.getType() and t.validForIp(
                        srcIp) and typeTrans.supportsOs(
                            os['OS']) and t.validForOs(os['OS']):
                    usable = (pool, t)
                    break
            return usable

        try:
            alreadyAssigned = UserService.objects.filter(
                deployed_service__in=pools,
                state__in=State.VALID_STATES,
                user=user,
                cache_level=0).order_by('deployed_service__name')[0]
            logger.debug('Already assigned %s', alreadyAssigned)

            # Ensure transport is available for the OS, and store it
            usable = ensureTransport(alreadyAssigned.deployed_service)
            # Found already assigned, ensure everythinf is fine
            if usable:
                self.getService(user,
                                os,
                                srcIp,
                                'F' + usable[0].uuid,
                                usable[1].uuid,
                                doTest=False)

        except Exception:  # No service already assigned, lets find a suitable one
            for pool in pools:  # Pools are already sorted, and "full" pools are filtered out
                # Ensure transport is available for the OS
                usable = ensureTransport(pool)

                # Stop if a pool-transport is found and can be assigned to user
                if usable:
                    try:
                        self.getService(user,
                                        os,
                                        srcIp,
                                        'F' + usable[0].uuid,
                                        usable[1].uuid,
                                        doTest=False)
                        break  # If all goes fine, stop here
                    except Exception as e:
                        logger.info(
                            'Meta service {}:{} could not be assigned, trying a new one'
                            .format(usable[0].name, e))
                        usable = None

        if not usable:
            log.doLog(
                meta, log.WARN,
                "No user service accessible from device (ip {}, os: {})".
                format(srcIp, os['OS']), log.SERVICE)
            raise InvalidServiceException(
                _('The service is not accessible from this device'))

        logger.debug('Found usable pair: %s', usable)
        usable[0].validateUser(user)
        # We have found an usable user service already assigned & can be accessed from this, so return it
        return None, usable[0], None, usable[1], None
Exemplo n.º 2
0
    def getService(self, user, srcIp, idService, idTransport, doTest=True):
        """
        Get service info from
        """
        userService = self.locateUserService(user, idService, create=True)

        # Early log of "access try" so we can imagine what is going on
        userService.setConnectionSource(srcIp, 'unknown')

        if userService.isInMaintenance() is True:
            raise ServiceInMaintenanceMode()

        if userService.deployed_service.isAccessAllowed() is False:
            raise ServiceAccessDeniedByCalendar()

        if idTransport is None or idTransport == '':  # Find a suitable transport
            for v in userService.deployed_service.transports.order_by(
                    'priority'):
                if v.validForIp(srcIp):
                    idTransport = v.uuid
                    break

        try:
            trans = Transport.objects.get(uuid=idTransport)
        except Exception:
            raise InvalidServiceException()

        # Ensures that the transport is allowed for this service
        if trans not in userService.deployed_service.transports.all():
            raise InvalidServiceException()

        # If transport is not available for the request IP...
        if trans.validForIp(srcIp) is False:
            msg = 'The requested transport {} is not valid for {}'.format(
                trans.name, srcIp)
            logger.error(msg)
            raise InvalidServiceException(msg)

        if user is not None:
            userName = user.name
        else:
            userName = '******'

        if doTest is False:
            # traceLogger.info('GOT service "{}" for user "{}" with transport "{}" (NOT TESTED)'.format(userService.name, userName, trans.name))
            return None, userService, None, trans, None

        serviceNotReadyCode = 0x0001
        ip = 'unknown'
        # Test if the service is ready
        if userService.isReady():
            serviceNotReadyCode = 0x0002
            log.doLog(
                userService, log.INFO,
                "User {0} from {1} has initiated access".format(
                    user.name, srcIp), log.WEB)
            # If ready, show transport for this service, if also ready ofc
            iads = userService.getInstance()
            ip = iads.getIp()
            userService.logIP(ip)  # Update known ip

            if self.checkUuid(
                    userService) is False:  # Machine is not what is expected
                serviceNotReadyCode = 0x0004
                log.doLog(userService, log.WARN,
                          "User service is not accessible (ip {0})".format(ip),
                          log.TRANSPORT)
                logger.debug(
                    'Transport is not ready for user service {0}'.format(
                        userService))
            else:
                events.addEvent(userService.deployed_service,
                                events.ET_ACCESS,
                                username=userName,
                                srcip=srcIp,
                                dstip=ip,
                                uniqueid=userService.unique_id)
                if ip is not None:
                    serviceNotReadyCode = 0x0003
                    itrans = trans.getInstance()
                    if itrans.isAvailableFor(userService, ip):
                        # userService.setConnectionSource(srcIp, 'unknown')
                        log.doLog(userService, log.INFO, "User service ready",
                                  log.WEB)
                        self.notifyPreconnect(
                            userService,
                            itrans.processedUser(userService,
                                                 user), itrans.protocol)
                        traceLogger.info(
                            'READY on service "{}" for user "{}" with transport "{}" (ip:{})'
                            .format(userService.name, userName, trans.name,
                                    ip))
                        return ip, userService, iads, trans, itrans
                    else:
                        message = itrans.getCustomAvailableErrorMsg(
                            userService, ip)
                        log.doLog(userService, log.WARN, message,
                                  log.TRANSPORT)
                        logger.debug(
                            'Transport is not ready for user service {}:  {}'.
                            format(userService, message))
                else:
                    logger.debug(
                        'Ip not available from user service {0}'.format(
                            userService))
        else:
            log.doLog(
                userService, log.WARN,
                "User {0} from {1} tried to access, but service was not ready".
                format(user.name, srcIp), log.WEB)

        traceLogger.error(
            'ERROR {} on service "{}" for user "{}" with transport "{}" (ip:{})'
            .format(serviceNotReadyCode, userService.name, userName,
                    trans.name, ip))
        raise ServiceNotReadyError(code=serviceNotReadyCode,
                                   service=userService,
                                   transport=trans)
Exemplo n.º 3
0
    def getService(self, user, srcIp, idService, idTransport, doTest=True):
        '''
        Get service info from
        '''
        kind, idService = idService[0], idService[1:]

        logger.debug('Kind of service: {0}, idService: {1}'.format(
            kind, idService))
        if kind == 'A':  # This is an assigned service
            logger.debug('Getting A service {}'.format(idService))
            userService = UserService.objects.get(uuid=idService)
            userService.deployed_service.validateUser(user)
        else:
            ds = ServicePool.objects.get(uuid=idService)
            # We first do a sanity check for this, if the user has access to this service
            # If it fails, will raise an exception
            ds.validateUser(user)
            # Now we have to locate an instance of the service, so we can assign it to user.
            userService = self.getAssignationForUser(ds, user)

        logger.debug('Found service: {0}'.format(userService))

        if userService.isInMaintenance() is True:
            raise ServiceInMaintenanceMode()

        # If service is not visible, do not allow it to be used
        if userService.deployed_service.isVisible() is False:
            raise InvalidServiceException()

        if userService.deployed_service.isAccessAllowed() is False:
            raise ServiceAccessDeniedByCalendar()

        if idTransport is None or idTransport == '':  # Find a suitable transport
            for v in userService.deployed_service.transports.order_by(
                    'priority'):
                if v.validForIp(srcIp):
                    idTransport = v.uuid
                    break

        try:
            trans = Transport.objects.get(uuid=idTransport)
        except Exception:
            raise InvalidServiceException()

        # Ensures that the transport is allowed for this service
        if trans not in userService.deployed_service.transports.all():
            raise InvalidServiceException()

        # If transport is not available for the request IP...
        if trans.validForIp(srcIp) is False:
            raise InvalidServiceException()

        if user is not None:
            userName = user.name

        if doTest is False:
            # traceLogger.info('GOT service "{}" for user "{}" with transport "{}" (NOT TESTED)'.format(userService.name, userName, trans.name))
            return (None, userService, None, trans, None)

        serviceNotReadyCode = 0x0001
        ip = 'unknown'
        # Test if the service is ready
        if userService.isReady():
            serviceNotReadyCode = 0x0002
            log.doLog(
                userService, log.INFO,
                "User {0} from {1} has initiated access".format(
                    user.name, srcIp), log.WEB)
            # If ready, show transport for this service, if also ready ofc
            iads = userService.getInstance()
            ip = iads.getIp()

            if self.checkUuid(
                    userService) is False:  # Machine is not what is expected
                serviceNotReadyCode = 0x0004
                log.doLog(userService, log.WARN,
                          "User service is not accessible (ip {0})".format(ip),
                          log.TRANSPORT)
                logger.debug(
                    'Transport is not ready for user service {0}'.format(
                        userService))
            else:
                events.addEvent(userService.deployed_service,
                                events.ET_ACCESS,
                                username=userName,
                                srcip=srcIp,
                                dstip=ip,
                                uniqueid=userService.unique_id)
                if ip is not None:
                    serviceNotReadyCode = 0x0003
                    itrans = trans.getInstance()
                    if itrans.isAvailableFor(userService, ip):
                        userService.setConnectionSource(srcIp, 'unknown')
                        log.doLog(userService, log.INFO, "User service ready",
                                  log.WEB)
                        self.notifyPreconnect(
                            userService,
                            itrans.processedUser(userService,
                                                 user), itrans.protocol)
                        traceLogger.info(
                            'READY on service "{}" for user "{}" with transport "{}" (ip:{})'
                            .format(userService.name, userName, trans.name,
                                    ip))
                        return (ip, userService, iads, trans, itrans)
                    else:
                        log.doLog(
                            userService, log.WARN,
                            "User service is not accessible (ip {0})".format(
                                ip), log.TRANSPORT)
                        logger.debug(
                            'Transport is not ready for user service {0}'.
                            format(userService))
                else:
                    logger.debug(
                        'Ip not available from user service {0}'.format(
                            userService))
        else:
            log.doLog(
                userService, log.WARN,
                "User {0} from {1} tried to access, but service was not ready".
                format(user.name, srcIp), log.WEB)

        traceLogger.error(
            'ERROR {} on service "{}" for user "{}" with transport "{}" (ip:{})'
            .format(serviceNotReadyCode, userService.name, userName,
                    trans.name, ip))
        raise ServiceNotReadyError(code=serviceNotReadyCode,
                                   service=userService,
                                   transport=trans)