forked from shaba/openuds
Adding support for pre-access scripts so UDS can support certain
operations (i.e. add an user to an specific group, or allowing user to access using specific protocol, thanks to José Luis Sepúlveda from upv for the feedback ;-)
This commit is contained in:
parent
2159e0f29d
commit
9a86682c9d
@ -122,7 +122,7 @@ class Actor(Handler):
|
|||||||
if len(self._args) < 1:
|
if len(self._args) < 1:
|
||||||
raise RequestError('Invalid request')
|
raise RequestError('Invalid request')
|
||||||
|
|
||||||
# if path is .../test (/rest/actor/[test|init]?key=.....&version=....&id=....)
|
# if path is .../test (/rest/actor/[test|init]?key=.....&version=....&id=....) version & ids are only used on init
|
||||||
if self._args[0] in ('test', 'init'):
|
if self._args[0] in ('test', 'init'):
|
||||||
v = self.validateRequestKey()
|
v = self.validateRequestKey()
|
||||||
if v is not None:
|
if v is not None:
|
||||||
@ -142,7 +142,10 @@ class Actor(Handler):
|
|||||||
if service.deployed_service.osmanager is not None:
|
if service.deployed_service.osmanager is not None:
|
||||||
maxIdle = service.deployed_service.osmanager.getInstance().maxIdle()
|
maxIdle = service.deployed_service.osmanager.getInstance().maxIdle()
|
||||||
logger.debug('Max idle: {}'.format(maxIdle))
|
logger.debug('Max idle: {}'.format(maxIdle))
|
||||||
return Actor.result((service.uuid, service.unique_id, 0 if maxIdle is None else maxIdle))
|
return Actor.result((service.uuid,
|
||||||
|
service.unique_id,
|
||||||
|
0 if maxIdle is None else maxIdle)
|
||||||
|
)
|
||||||
raise RequestError('Invalid request')
|
raise RequestError('Invalid request')
|
||||||
|
|
||||||
# Must be invoked as '/rest/actor/UUID/[message], with message data in post body
|
# Must be invoked as '/rest/actor/UUID/[message], with message data in post body
|
||||||
@ -170,7 +173,7 @@ class Actor(Handler):
|
|||||||
username = ''
|
username = ''
|
||||||
|
|
||||||
if message == 'notifyComms':
|
if message == 'notifyComms':
|
||||||
service.setProperty('comms_url', data)
|
service.setCommsUrl(data)
|
||||||
return Actor.result('ok')
|
return Actor.result('ok')
|
||||||
|
|
||||||
# Preprocess some messages, common to all clients, such as "log"
|
# Preprocess some messages, common to all clients, such as "log"
|
||||||
@ -181,7 +184,7 @@ class Actor(Handler):
|
|||||||
username = data
|
username = data
|
||||||
|
|
||||||
try:
|
try:
|
||||||
res = service.getInstance().osmanager().process(service, message, data)
|
res = service.getInstance().osmanager().process(service, message, data, options={'scramble': False})
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return Actor.result(six.text_type(e), ERR_OSMANAGER_ERROR)
|
return Actor.result(six.text_type(e), ERR_OSMANAGER_ERROR)
|
||||||
|
|
||||||
|
@ -155,6 +155,7 @@ class CachedService(AssignedService):
|
|||||||
{'friendly_name': {'title': _('Friendly name')}},
|
{'friendly_name': {'title': _('Friendly name')}},
|
||||||
{'state': {'title': _('State'), 'type': 'dict', 'dict': State.dictionary()}},
|
{'state': {'title': _('State'), 'type': 'dict', 'dict': State.dictionary()}},
|
||||||
{'cache_level': {'title': _('Cache level')}},
|
{'cache_level': {'title': _('Cache level')}},
|
||||||
|
{'actor_version': {'title': _('Actor version')}}
|
||||||
]
|
]
|
||||||
|
|
||||||
def getLogs(self, parent, item):
|
def getLogs(self, parent, item):
|
||||||
|
@ -47,7 +47,7 @@ import logging
|
|||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
__updated__ = '2014-11-12'
|
__updated__ = '2014-12-04'
|
||||||
|
|
||||||
|
|
||||||
# a few constants
|
# a few constants
|
||||||
|
@ -45,6 +45,8 @@ from uds.core.services.Exceptions import MaxServicesReachedException
|
|||||||
from uds.models import UserService, getSqlDatetime
|
from uds.models import UserService, getSqlDatetime
|
||||||
from uds.core import services
|
from uds.core import services
|
||||||
from uds.core.services import Service
|
from uds.core.services import Service
|
||||||
|
import requests
|
||||||
|
import json
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@ -444,6 +446,46 @@ class UserServiceManager(object):
|
|||||||
UserServiceOpChecker.makeUnique(uService, ui, state)
|
UserServiceOpChecker.makeUnique(uService, ui, state)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def manageOsManagerPreConnection(self, uService, user):
|
||||||
|
'''
|
||||||
|
Sends, if the user service has os manager and the os manager "wants" to send an pre-script to actor
|
||||||
|
the script to the Service
|
||||||
|
If fails, it will silently ignore it, but probably connection will not success
|
||||||
|
This is so right now to keep compatibility with previos xmlrpc actor..
|
||||||
|
@return: Nothing
|
||||||
|
'''
|
||||||
|
logger.debug('Managing specific OS Manager data before connection')
|
||||||
|
if uService.needsOsManager() is False:
|
||||||
|
logger.debug('No os manager for service, finishing')
|
||||||
|
return
|
||||||
|
|
||||||
|
osm = uService.getOsManager()
|
||||||
|
instanceOsManager = osm.getInstance()
|
||||||
|
script = instanceOsManager.preAccessScript(uService, user)
|
||||||
|
if script is None:
|
||||||
|
logger.debug('OS Manager does not provides a pre access script')
|
||||||
|
|
||||||
|
logger.debug('Pre access script: {}'.format(script))
|
||||||
|
return self.sendScript(uService, script)
|
||||||
|
|
||||||
|
def sendScript(self, uService, script):
|
||||||
|
'''
|
||||||
|
If allowed, send script to user service
|
||||||
|
'''
|
||||||
|
url = uService.getCommsUrl()
|
||||||
|
if url is None:
|
||||||
|
logger.error('Can\'t connect with actor (no actor or legacy actor)')
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
r = requests.post(url, data={'script': script}, headers={'content-type': 'application/json'}, verify=False, timeout=5)
|
||||||
|
r = json.loads(r.content)
|
||||||
|
# In fact we ignore result right now
|
||||||
|
except Exception as e:
|
||||||
|
logger.error('Exception caught sending script: {}. Check connection on destination machine: {}'.format(e, url))
|
||||||
|
|
||||||
|
# All done
|
||||||
|
|
||||||
def checkForRemoval(self, uService):
|
def checkForRemoval(self, uService):
|
||||||
'''
|
'''
|
||||||
This method is used by UserService when a request for setInUse(False) is made
|
This method is used by UserService when a request for setInUse(False) is made
|
||||||
|
@ -36,7 +36,7 @@ from django.utils.translation import ugettext_noop as _
|
|||||||
from uds.core.util.State import State
|
from uds.core.util.State import State
|
||||||
from uds.core import Module
|
from uds.core import Module
|
||||||
|
|
||||||
__updated__ = '2014-12-01'
|
__updated__ = '2014-12-04'
|
||||||
|
|
||||||
STORAGE_KEY = 'osmk'
|
STORAGE_KEY = 'osmk'
|
||||||
|
|
||||||
@ -89,7 +89,7 @@ class OSManager(Module):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
# These methods must be overriden
|
# These methods must be overriden
|
||||||
def process(self, service, message, data):
|
def process(self, service, message, data, options=None):
|
||||||
'''
|
'''
|
||||||
This method must be overriden so your so manager can manage requests and responses from agent.
|
This method must be overriden so your so manager can manage requests and responses from agent.
|
||||||
@param service: Service that sends the request (virtual machine or whatever)
|
@param service: Service that sends the request (virtual machine or whatever)
|
||||||
@ -126,6 +126,14 @@ class OSManager(Module):
|
|||||||
'''
|
'''
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def preAccessScript(self, userService, user):
|
||||||
|
'''
|
||||||
|
This gives us the chance to include "customized" initialization for any os manager for an specifyc user & service on assignation to an user
|
||||||
|
such as "include" in allowed user list, etc...
|
||||||
|
Both values are db objects
|
||||||
|
'''
|
||||||
|
return None
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def transformsUserOrPasswordForService(cls):
|
def transformsUserOrPasswordForService(cls):
|
||||||
'''
|
'''
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
__updated__ = '2014-12-02'
|
__updated__ = '2014-12-04'
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.db.models import signals
|
from django.db.models import signals
|
||||||
@ -246,11 +246,14 @@ class UserService(UUIDModel):
|
|||||||
'''
|
'''
|
||||||
return [self.src_ip, self.src_hostname]
|
return [self.src_ip, self.src_hostname]
|
||||||
|
|
||||||
|
def getOsManager(self):
|
||||||
|
return self.deployed_service.osmanager
|
||||||
|
|
||||||
def needsOsManager(self):
|
def needsOsManager(self):
|
||||||
'''
|
'''
|
||||||
Returns True if this User Service needs an os manager (i.e. parent services pools is marked to use an os manager)
|
Returns True if this User Service needs an os manager (i.e. parent services pools is marked to use an os manager)
|
||||||
'''
|
'''
|
||||||
return self.deployed_service.osmanager is not None
|
return self.getOsManager() is not None
|
||||||
|
|
||||||
def transformsUserOrPasswordForService(self):
|
def transformsUserOrPasswordForService(self):
|
||||||
'''
|
'''
|
||||||
@ -419,9 +422,15 @@ class UserService(UUIDModel):
|
|||||||
|
|
||||||
def setProperty(self, propName, propValue):
|
def setProperty(self, propName, propValue):
|
||||||
prop, _ = self.properties.get_or_create(name=propName)
|
prop, _ = self.properties.get_or_create(name=propName)
|
||||||
prop.value = propValue
|
prop.value = propValue if propValue is None else ''
|
||||||
prop.save()
|
prop.save()
|
||||||
|
|
||||||
|
def setCommsUrl(self, commsUrl=None):
|
||||||
|
self.setProperty('comms_url', commsUrl)
|
||||||
|
|
||||||
|
def getCommsUrl(self):
|
||||||
|
return self.getProperty('comms_url', None)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "User service {0}, cache_level {1}, user {2}, name {3}, state {4}:{5}".format(self.id, self.cache_level, self.user, self.friendly_name,
|
return "User service {0}, cache_level {1}, user {2}, name {3}, state {4}:{5}".format(self.id, self.cache_level, self.user, self.friendly_name,
|
||||||
State.toString(self.state), State.toString(self.os_state))
|
State.toString(self.state), State.toString(self.os_state))
|
||||||
|
@ -115,7 +115,7 @@ class WindowsOsManager(osmanagers.OSManager):
|
|||||||
except Exception:
|
except Exception:
|
||||||
log.doLog(service, log.ERROR, "do not understand {0}".format(data), origin)
|
log.doLog(service, log.ERROR, "do not understand {0}".format(data), origin)
|
||||||
|
|
||||||
def process(self, service, msg, data):
|
def process(self, service, msg, data, options):
|
||||||
'''
|
'''
|
||||||
We understand this messages:
|
We understand this messages:
|
||||||
* msg = info, data = None. Get information about name of machine (or domain, in derived WinDomainOsManager class) (old method)
|
* msg = info, data = None. Get information about name of machine (or domain, in derived WinDomainOsManager class) (old method)
|
||||||
@ -180,6 +180,8 @@ class WindowsOsManager(osmanagers.OSManager):
|
|||||||
else:
|
else:
|
||||||
UserServiceManager.manager().notifyReadyFromOsManager(service, '')
|
UserServiceManager.manager().notifyReadyFromOsManager(service, '')
|
||||||
logger.debug('Returning {} to {} message'.format(ret, msg))
|
logger.debug('Returning {} to {} message'.format(ret, msg))
|
||||||
|
if options is not None and options.get('scramble', True) is False:
|
||||||
|
return ret
|
||||||
return scrambleMsg(ret)
|
return scrambleMsg(ret)
|
||||||
|
|
||||||
def processUnused(self, userService):
|
def processUnused(self, userService):
|
||||||
|
@ -276,6 +276,7 @@ def service(request, idService, idTransport):
|
|||||||
if ip is not None:
|
if ip is not None:
|
||||||
itrans = trans.getInstance()
|
itrans = trans.getInstance()
|
||||||
if itrans.isAvailableFor(ip):
|
if itrans.isAvailableFor(ip):
|
||||||
|
UserServiceManager.manager().manageOsManagerPreConnection(ads, request.user)
|
||||||
log.doLog(ads, log.INFO, "User service ready, rendering transport", log.WEB)
|
log.doLog(ads, log.INFO, "User service ready, rendering transport", log.WEB)
|
||||||
transport = itrans.renderForHtml(ads, ads.uuid, trans.uuid, ip, request.session['OS'], request.user, webPassword(request))
|
transport = itrans.renderForHtml(ads, ads.uuid, trans.uuid, ip, request.session['OS'], request.user, webPassword(request))
|
||||||
return render_to_response(theme.template('show_transport.html'), {'transport': transport, 'nolang': True}, context_instance=RequestContext(request))
|
return render_to_response(theme.template('show_transport.html'), {'transport': transport, 'nolang': True}, context_instance=RequestContext(request))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user