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:
|
||||
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'):
|
||||
v = self.validateRequestKey()
|
||||
if v is not None:
|
||||
@ -142,7 +142,10 @@ class Actor(Handler):
|
||||
if service.deployed_service.osmanager is not None:
|
||||
maxIdle = service.deployed_service.osmanager.getInstance().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')
|
||||
|
||||
# Must be invoked as '/rest/actor/UUID/[message], with message data in post body
|
||||
@ -170,7 +173,7 @@ class Actor(Handler):
|
||||
username = ''
|
||||
|
||||
if message == 'notifyComms':
|
||||
service.setProperty('comms_url', data)
|
||||
service.setCommsUrl(data)
|
||||
return Actor.result('ok')
|
||||
|
||||
# Preprocess some messages, common to all clients, such as "log"
|
||||
@ -181,7 +184,7 @@ class Actor(Handler):
|
||||
username = data
|
||||
|
||||
try:
|
||||
res = service.getInstance().osmanager().process(service, message, data)
|
||||
res = service.getInstance().osmanager().process(service, message, data, options={'scramble': False})
|
||||
except Exception as e:
|
||||
return Actor.result(six.text_type(e), ERR_OSMANAGER_ERROR)
|
||||
|
||||
|
@ -155,6 +155,7 @@ class CachedService(AssignedService):
|
||||
{'friendly_name': {'title': _('Friendly name')}},
|
||||
{'state': {'title': _('State'), 'type': 'dict', 'dict': State.dictionary()}},
|
||||
{'cache_level': {'title': _('Cache level')}},
|
||||
{'actor_version': {'title': _('Actor version')}}
|
||||
]
|
||||
|
||||
def getLogs(self, parent, item):
|
||||
|
@ -47,7 +47,7 @@ import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
__updated__ = '2014-11-12'
|
||||
__updated__ = '2014-12-04'
|
||||
|
||||
|
||||
# a few constants
|
||||
|
@ -45,6 +45,8 @@ from uds.core.services.Exceptions import MaxServicesReachedException
|
||||
from uds.models import UserService, getSqlDatetime
|
||||
from uds.core import services
|
||||
from uds.core.services import Service
|
||||
import requests
|
||||
import json
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@ -444,6 +446,46 @@ class UserServiceManager(object):
|
||||
UserServiceOpChecker.makeUnique(uService, ui, state)
|
||||
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):
|
||||
'''
|
||||
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 import Module
|
||||
|
||||
__updated__ = '2014-12-01'
|
||||
__updated__ = '2014-12-04'
|
||||
|
||||
STORAGE_KEY = 'osmk'
|
||||
|
||||
@ -89,7 +89,7 @@ class OSManager(Module):
|
||||
pass
|
||||
|
||||
# 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.
|
||||
@param service: Service that sends the request (virtual machine or whatever)
|
||||
@ -126,6 +126,14 @@ class OSManager(Module):
|
||||
'''
|
||||
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
|
||||
def transformsUserOrPasswordForService(cls):
|
||||
'''
|
||||
|
@ -35,7 +35,7 @@
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
__updated__ = '2014-12-02'
|
||||
__updated__ = '2014-12-04'
|
||||
|
||||
from django.db import models
|
||||
from django.db.models import signals
|
||||
@ -246,11 +246,14 @@ class UserService(UUIDModel):
|
||||
'''
|
||||
return [self.src_ip, self.src_hostname]
|
||||
|
||||
def getOsManager(self):
|
||||
return self.deployed_service.osmanager
|
||||
|
||||
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)
|
||||
'''
|
||||
return self.deployed_service.osmanager is not None
|
||||
return self.getOsManager() is not None
|
||||
|
||||
def transformsUserOrPasswordForService(self):
|
||||
'''
|
||||
@ -419,9 +422,15 @@ class UserService(UUIDModel):
|
||||
|
||||
def setProperty(self, propName, propValue):
|
||||
prop, _ = self.properties.get_or_create(name=propName)
|
||||
prop.value = propValue
|
||||
prop.value = propValue if propValue is None else ''
|
||||
prop.save()
|
||||
|
||||
def setCommsUrl(self, commsUrl=None):
|
||||
self.setProperty('comms_url', commsUrl)
|
||||
|
||||
def getCommsUrl(self):
|
||||
return self.getProperty('comms_url', None)
|
||||
|
||||
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,
|
||||
State.toString(self.state), State.toString(self.os_state))
|
||||
|
@ -115,7 +115,7 @@ class WindowsOsManager(osmanagers.OSManager):
|
||||
except Exception:
|
||||
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:
|
||||
* 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:
|
||||
UserServiceManager.manager().notifyReadyFromOsManager(service, '')
|
||||
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)
|
||||
|
||||
def processUnused(self, userService):
|
||||
|
@ -276,6 +276,7 @@ def service(request, idService, idTransport):
|
||||
if ip is not None:
|
||||
itrans = trans.getInstance()
|
||||
if itrans.isAvailableFor(ip):
|
||||
UserServiceManager.manager().manageOsManagerPreConnection(ads, request.user)
|
||||
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))
|
||||
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