Exemple #1
0
    def createAssignedFor(self, servicePool: ServicePool,
                          user: User) -> UserService:
        """
        Creates a new assigned deployed service for the current publication (if any) of service pool and user indicated
        """
        # First, honor maxPreparingServices
        if self.canInitiateServiceFromDeployedService(servicePool) is False:
            # Cannot create new
            logger.info(
                'Too many preparing services. Creation of assigned service denied by max preparing services parameter. (login storm with insufficient cache?).'
            )
            raise ServiceNotReadyError()

        if servicePool.service.getType().publicationType is not None:
            publication = servicePool.activePublication()
            logger.debug(
                'Creating a new assigned element for user %s por publication %s',
                user, publication)
            if publication:
                assigned = self.__createAssignedAtDb(publication, user)
            else:
                raise Exception(
                    'Invalid publication creating service assignation: {} {}'.
                    format(servicePool, user))
        else:
            logger.debug('Creating a new assigned element for user %s', user)
            assigned = self.__createAssignedAtDbForNoPublication(
                servicePool, user)

        assignedInstance = assigned.getInstance()
        state = assignedInstance.deployForUser(user)

        UserServiceOpChecker.makeUnique(assigned, assignedInstance, state)

        return assigned
Exemple #2
0
    def script(self):
        # Could be one-liner, (... = ..[0:4]), but mypy complains so this is fine :)
        idService = self._args[0]
        idTransport = self._args[1]
        scrambler = self._args[2]
        hostname = self._args[3]

        try:
            res = userServiceManager().getService(
                self._user, self._request.os, self._request.ip, idService, idTransport
            )
            logger.debug('Res: %s', res)
            (
                ip,
                userService,
                userServiceInstance,
                transport,
                transportInstance,
            ) = res  # pylint: disable=unused-variable
            password = cryptoManager().symDecrpyt(self.getValue('password'), scrambler)

            userService.setConnectionSource(
                self._request.ip, hostname
            )  # Store where we are accessing from so we can notify Service

            if not ip:
                raise ServiceNotReadyError()

            transportScript = transportInstance.getEncodedTransportScript(
                userService,
                transport,
                ip,
                self._request.os,
                self._user,
                password,
                self._request,
            )

            return Connection.result(result=transportScript)
        except ServiceNotReadyError as e:
            # Refresh ticket and make this retrayable
            return Connection.result(
                error=errors.SERVICE_IN_PREPARATION, errorCode=e.code, retryable=True
            )
        except Exception as e:
            logger.exception("Exception")
            return Connection.result(error=str(e))
Exemple #3
0
    def getService(  # pylint: disable=too-many-locals, too-many-branches, too-many-statements
        self,
        user: User,
        os: typing.MutableMapping,
        srcIp: str,
        idService: str,
        idTransport: str,
        doTest: bool = True,
        clientHostname: typing.Optional[str] = None
    ) -> typing.Tuple[typing.Optional[str], UserService,
                      typing.Optional['services.UserDeployment'], Transport,
                      typing.Optional[transports.Transport]]:
        """
        Get service info from user service
        """
        if idService[0] == 'M':  # Meta pool
            return self.getMeta(user, srcIp, os, idService[1:])

        userService = self.locateUserService(user, idService, create=True)

        if not userService:
            raise InvalidServiceException(
                _('Invalid service. The service is not available at this moment. Please, try later'
                  ))

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

        if userService.isInMaintenance():
            raise ServiceInMaintenanceMode()

        if not userService.deployed_service.isAccessAllowed():
            raise ServiceAccessDeniedByCalendar()

        if not idTransport:  # Find a suitable transport
            t: Transport
            for t in userService.deployed_service.transports.order_by(
                    'priority'):
                typeTrans = t.getType()
                if t.validForIp(srcIp) and typeTrans.supportsOs(
                        os['OS']) and t.validForOs(os['OS']):
                    idTransport = t.uuid
                    break

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

        # Ensures that the transport is allowed for this service
        if userService.deployed_service.transports.filter(
                id=transport.id).count() == 0:
            raise InvalidServiceException()

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

        userName = user.name if user else 'unknown'

        if not doTest:
            # traceLogger.info('GOT service "{}" for user "{}" with transport "{}" (NOT TESTED)'.format(userService.name, userName, trans.name))
            return None, userService, None, transport, 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
            userServiceInstance = userService.getInstance()
            ip = userServiceInstance.getIp()
            userService.logIP(ip)  # Update known ip
            logger.debug('IP: %s', ip)

            if self.checkUuid(
                    userService
            ) is False:  # The service is not the expected one
                serviceNotReadyCode = 0x0004
                log.doLog(
                    userService, log.WARN,
                    "User service is not accessible due to invalid UUID (ip {0})"
                    .format(ip), log.TRANSPORT)
                logger.debug('UUID check failed for user service %s',
                             userService)
            else:
                events.addEvent(userService.deployed_service,
                                events.ET_ACCESS,
                                username=userName,
                                srcip=srcIp,
                                dstip=ip,
                                uniqueid=userService.unique_id)
                if ip:
                    serviceNotReadyCode = 0x0003
                    transportInstance = transport.getInstance()
                    if transportInstance.isAvailableFor(userService, ip):
                        # userService.setConnectionSource(srcIp, 'unknown')
                        log.doLog(userService, log.INFO, "User service ready",
                                  log.WEB)
                        self.notifyPreconnect(
                            userService,
                            transportInstance.processedUser(userService, user),
                            transportInstance.protocol)
                        traceLogger.info(
                            'READY on service "%s" for user "%s" with transport "%s" (ip:%s)',
                            userService.name, userName, transport.name, ip)
                        return ip, userService, userServiceInstance, transport, transportInstance

                    message = transportInstance.getCustomAvailableErrorMsg(
                        userService, ip)
                    log.doLog(userService, log.WARN, message, log.TRANSPORT)
                    logger.debug(
                        'Transport is not ready for user service %s: %s',
                        userService, message)
                else:
                    logger.debug('Ip not available from user service %s',
                                 userService)
        else:
            log.doLog(
                userService, log.WARN,
                "User {} from {} tried to access, but service was not ready".
                format(user.name, srcIp), log.WEB)

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