added REST api client part, valid for windows & linux actors

This commit is contained in:
Adolfo Gómez García 2014-10-07 18:01:36 +02:00
parent c9524191b1
commit 06d6b9fd24
6 changed files with 181 additions and 14 deletions

View File

@ -133,7 +133,7 @@ class Actor(Handler):
# Returns UID of selected Machine
service = self.getUserServiceByIds()
if service is None:
return Actor.result(error=ERR_HOST_NOT_MANAGED)
return Actor.result(_('Unmanaged host'), error=ERR_HOST_NOT_MANAGED)
else:
return Actor.result(service.uuid)
raise RequestError('Invalid request')
@ -163,6 +163,7 @@ class Actor(Handler):
username = ''
# Preprocess some messages, common to all clients, such as "log"
if message == 'log':
logger.debug(self._params)
data = '\t'.join((self._params.get('message'), six.text_type(self._params.get('level', 10000))))
elif message in ('login', 'logout', 'logon', 'logoff'):
username = data

View File

@ -50,7 +50,7 @@ from uds.models import User
import logging
__updated__ = '2014-09-12'
__updated__ = '2014-10-07'
logger = logging.getLogger(__name__)
authLogger = logging.getLogger('authLog')
@ -59,6 +59,7 @@ USER_KEY = 'uk'
PASS_KEY = 'pk'
ROOT_ID = -20091204 # Any negative number will do the trick
def getUDSCookie(request, response):
if 'uds' not in request.COOKIES:
import random
@ -70,7 +71,9 @@ def getUDSCookie(request, response):
return cookie
def getRootUser():
# pylint: disable=unexpected-keyword-arg, no-value-for-parameter
from uds.models import Authenticator
u = User(id=ROOT_ID, name=GlobalConfig.SUPER_USER_LOGIN.get(True), real_name=_('System Administrator'), state=State.ACTIVE, staff_member=True, is_admin=True)
u.manager = Authenticator()

View File

@ -16,6 +16,7 @@ from uds.core import osmanagers
from uds.core.managers.UserServiceManager import UserServiceManager
from uds.core.util.State import State
from uds.core.util import log
import six
import logging
@ -26,12 +27,14 @@ def scrambleMsg(data):
'''
Simple scrambler so password are not seen at source page
'''
if isinstance(data, six.text_type):
data = data.encode('utf8')
res = []
n = 0x32
for c in data[::-1]:
res.append(chr(ord(c) ^ n))
n = (n + ord(c)) & 0xFF
return unicode(str.join(str(''), res).encode('hex'))
return six.text_type(b''.join(res).encode('hex'))
class WindowsOsManager(osmanagers.OSManager):
@ -131,7 +134,7 @@ class WindowsOsManager(osmanagers.OSManager):
state = State.PREPARING
elif msg == "log":
self.doLog(service, data, log.ACTOR)
elif msg == "logon":
elif msg == "logon" or msg == 'login':
si = service.getInstance()
si.userLoggedIn(data)
service.updateData(si)
@ -140,7 +143,7 @@ class WindowsOsManager(osmanagers.OSManager):
ip, hostname = service.getConnectionSource()
ret = "{0}\t{1}".format(ip, hostname)
inUse = True
elif msg == "logoff":
elif msg == "logoff" or msg == 'logout':
si = service.getInstance()
si.userLoggedOut(data)
service.updateData(si)

View File

@ -31,13 +31,154 @@
'''
from __future__ import unicode_literals
import requests
import json
class RestApi(object):
def __init__(self, host, masterKey, useSSL):
# Valid logging levels
OTHER, DEBUG, INFO, WARN, ERROR, FATAL = (10000 * (x + 1) for x in xrange(6))
class RESTError(Exception):
ERRCODE = 0
class ConnectionError(RESTError):
ERRCODE = -1
# Errors ""raised"" from broker
class InvalidKeyError(RESTError):
ERRCODE = 1
class UnmanagedHostError(RESTError):
ERRCODE = 2
class UserServiceNotFoundError(RESTError):
ERRCODE = 3
class OsManagerError(RESTError):
ERRCODE = 4
def ensureResultIsOk(result):
if not 'error' in result:
return
for i in (InvalidKeyError, UnmanagedHostError, UserServiceNotFoundError, OsManagerError):
if result['error'] == i.ERRCODE:
raise i(result['result'])
err = RESTError(result['result'])
err.ERRCODE = result['error']
raise err
def unscramble(value):
if value is None or value == '':
return value
value = value.decode('hex')
n = 0x32
result = []
for ch in value:
c = ord(ch) ^ n
n = (n + c) & 0xFF
result.append(chr(c))
return b''.join(result)[::-1].decode('utf8')
class Api(object):
def __init__(self, host, masterKey, ssl, scrambledResponses=False):
self.host = host
self.masterKey = masterKey
self.useSSL = useSSL
self.url = "{}://{}/rest/actor".format(('http', 'https')[useSSL], self.host)
self.useSSL = ssl
self.scrambledResponses = scrambledResponses
self.uuid = None
self.url = "{}://{}/rest/actor/".format(('http', 'https')[ssl], self.host)
def _getUrl(self, method, key=None, ids=None):
url = self.url + method
params = []
if key is not None:
params.append('key=' + key)
if ids is not None:
params.append('id=' + ids)
if len(params) > 0:
url += '?' + '&'.join(params)
print url
return url
def _request(self, url, data=None):
try:
if data is None:
r = requests.get(url)
else:
r = requests.post(url, data)
r = r.json()
except requests.exceptions.ConnectionError as e:
raise ConnectionError(e.message.args[1].strerror)
except Exception as e:
raise ConnectionError(unicode(e))
ensureResultIsOk(r)
if self.scrambledResponses is True:
# test && init are not scrambled, even if rest of messages are
try:
r['result'] = unscramble(r['result'])
except Exception:
pass
return r
def test(self):
url = self._getUrl('test', self.masterKey)
return self._request(url)['result']
def init(self, ids):
'''
Ids is a comma separated values indicating MAC=ip
'''
url = self._getUrl('init', self.masterKey, ids)
self.uuid = self._request(url)['result']
return self.uuid
def postMessage(self, msg, data, processData=True):
if self.uuid is None:
raise ConnectionError('REST api has not been initialized')
if processData:
data = json.dumps({'data': data })
print data
url = self._getUrl('/'.join([self.uuid, msg]))
return self._request(url, data)
def login(self, username):
return self.postMessage('login', username)['result']
def logout(self, username):
return self.postMessage('logout', username)['result']
def information(self):
return self.postMessage('information', '')['result']
def setReady(self, ipsInfo):
data = ','.join(['{}={}'.format(v[0], v[1]) for v in ipsInfo])
return self.postMessage('ready', data)['result']
def notifyIpChanges(self, ipsInfo):
data = ','.join(['{}={}'.format(v[0], v[1]) for v in ipsInfo])
return self.postMessage('ip', data)['result']
def log(self, logLevel, message):
data = json.dumps({'message': message, 'level': logLevel})
return self.postMessage('log', data, processData=False)['result']

View File

@ -48,7 +48,7 @@ class MyForm(QtGui.QDialog):
if data is not None:
self.ui.host.setText(data['host'])
self.ui.masterKey.setText(data['masterKey'])
self.ui.useSSl.setCurrentIndex(0 if data['ssl'] is True else 1)
self.ui.useSSl.setCurrentIndex(1 if data['ssl'] is True else 0)
def textChanged(self):
enableButtons = self.ui.host.text() != '' and self.ui.masterKey.text() != ''
@ -63,7 +63,7 @@ class MyForm(QtGui.QDialog):
pass
def acceptAndSave(self):
data = { 'host': self.ui.host.text(), 'masterKey': self.ui.masterKey.text(), 'ssl': self.ui.useSSl.currentIndex() == 0 }
data = { 'host': unicode(self.ui.host.text()), 'masterKey': unicode(self.ui.masterKey.text()), 'ssl': self.ui.useSSl.currentIndex() == 1 }
writeConfig(data)
self.close()

View File

@ -2,12 +2,31 @@ from __future__ import unicode_literals
from management import *
from store import readConfig
import REST
cfg = readConfig()
print cfg
print "Intefaces: ", list(getNetworkInfo())
print "Joined Domain: ", getDomainName()
renameComputer('win7-64')
joinDomain('dom.dkmon.com', 'ou=pruebas_2,dc=dom,dc=dkmon,dc=com', 'administrador@dom.dkmon.com', 'Temporal2012', True)
#renameComputer('win7-64')
#joinDomain('dom.dkmon.com', 'ou=pruebas_2,dc=dom,dc=dkmon,dc=com', 'administrador@dom.dkmon.com', 'Temporal2012', True)
#reboot()
r = REST.Api(cfg['host'], cfg['masterKey'], cfg['ssl'], scrambledResponses=True)
r.test()
try:
r.init('02:46:00:00:00:07')
except REST.UnmanagedHostError:
print 'Unmanaged host (confirmed)'
uuid = r.init('02:46:00:00:00:06')
print 'uuid = {}'.format(uuid)
#print 'Login: {}'.format(r.login('test-user'))
#print 'Logout: {}'.format(r.logout('test-user'))
print r.information()
print r.setReady([(v.mac, v.ip) for v in getNetworkInfo()])
print r.log(REST.ERROR, 'Test error message')