Adding ticket messaging support on actor & server

This commit is contained in:
Adolfo Gómez García 2016-07-19 13:56:11 +02:00
parent 957403a23f
commit ac02161eb9
5 changed files with 32 additions and 24 deletions

View File

@ -150,6 +150,8 @@ class MessagesProcessor(QtCore.QThread):
self.script.emit(QtCore.QString.fromUtf8(data))
elif msgId == ipc.MSG_INFORMATION:
self.information.emit(pickle.loads(data))
elif msgId == ipc.MSG_TICKET:
pass # Not processed because not useful here
except Exception as e:
try:
logger.error('Got error on IPC thread {}'.format(utils.exceptionToMessage(e)))

View File

@ -231,6 +231,11 @@ class Api(object):
data = ','.join(['{}={}'.format(v[0], v[1]) for v in ipsInfo])
return self.postMessage('ip', data)
def getTicket(self, ticketId, secure=False):
url = self._getUrl('ticket/' + ticketId, self.masterKey) + "&secure={}".format('1' if secure else '0')
return self._request(url)['result']
def log(self, logLevel, message):
data = json.dumps({'message': message, 'level': logLevel})
return self.postMessage('log', data, processData=False)

View File

@ -36,6 +36,7 @@ import sys
import six
import traceback
import pickle
import json
from udsactor.utils import toUnicode
from udsactor.log import logger
@ -65,11 +66,14 @@ MSG_LOGOFF = 0xA1
MSG_MESSAGE = 0xB2
MSG_SCRIPT = 0xC3
MSG_INFORMATION = 0xD4
MSG_TICKET = 0xF6
# Request messages
REQ_INFORMATION = MSG_INFORMATION
REQ_LOGIN = 0xE5
REQ_LOGOUT = MSG_LOGOFF
REQ_TICKET = MSG_TICKET
VALID_REQUESTS = (REQ_INFORMATION, REQ_LOGIN, REQ_LOGOUT, REQ_TICKET)
VALID_MESSAGES = (MSG_LOGOFF, MSG_MESSAGE, MSG_SCRIPT, MSG_INFORMATION)
@ -81,6 +85,7 @@ REV_DICT = {
MSG_MESSAGE: 'MSG_MESSAGE',
MSG_SCRIPT: 'MSG_SCRIPT',
MSG_INFORMATION: 'MSG_INFORMATION',
MSG_TICKET: 'MSG_TICKET',
REQ_LOGIN: 'REQ_LOGIN',
REQ_LOGOUT: 'REQ_LOGOUT'
}
@ -134,14 +139,14 @@ class ClientProcessor(threading.Thread):
break
buf = six.byte2int(b) # Empty buffer, this is set as non-blocking
if state is None:
if buf in (REQ_INFORMATION, REQ_LOGIN, REQ_LOGOUT):
if buf in VALID_REQUESTS:
logger.debug('State set to {}'.format(buf))
state = buf
recv_msg = buf
continue # Get next byte
else:
logger.debug('Got unexpected data {}'.format(buf))
elif state in (REQ_INFORMATION, REQ_LOGIN, REQ_LOGOUT):
elif state in VALID_REQUESTS:
logger.debug('First length byte is {}'.format(buf))
msg_len = buf
state = ST_SECOND_BYTE
@ -252,6 +257,10 @@ class ServerIPC(threading.Thread):
def sendInformationMessage(self, info):
self.sendMessage(MSG_INFORMATION, pickle.dumps(info))
# This one is the only one dumped in json, be care with this!!
def sendTicketMessage(self, ticketData):
self.sendMessage(MSG_TICKET, json.dumps(ticketData))
def cleanupFinishedThreads(self):
'''
Cleans up current threads list
@ -331,6 +340,9 @@ class ClientIPC(threading.Thread):
def sendLogout(self, username):
self.sendRequestMessage(REQ_LOGOUT, username)
def requestTicket(self, ticketId, secure=True):
self.sendRequestMessage(REQ_TICKET, json.dumps({'ticketId': ticketId, 'secure': secure}))
def messageReceived(self):
'''
Override this method to automatically get notified on new message

View File

@ -44,6 +44,7 @@ from .utils import exceptionToMessage
import socket
import time
import random
import json
IPC_PORT = 39188
@ -232,16 +233,20 @@ class CommonService(object):
if len(res) >= 3:
self.api.maxSession = int(res[2]) # Third parameter is max session duration
msg = ipc.REQ_INFORMATION # Senf information, requested or not, to client on login notification
if msg == ipc.REQ_LOGOUT:
elif msg == ipc.REQ_LOGOUT:
self.api.logout(data)
self.onLogout(data)
if msg == ipc.REQ_INFORMATION:
elif msg == ipc.REQ_INFORMATION:
info = {}
if self.api.idle is not None:
info['idle'] = self.api.idle
if self.api.maxSession is not None:
info['maxSession'] = self.api.maxSession
self.ipc.sendInformationMessage(info)
elif msg == ipc.REQ_TICKET:
d = json.loads('data')
result = self.api.getTicket(d['ticketId'], d['secure'])
self.ipc.sendTicketMessage(result)
def initIPC(self):
# ******************************************

View File

@ -124,13 +124,15 @@ class Actor(Handler):
return services[0]
def getTicket(self, secure=False):
def getTicket(self):
'''
Processes get requests in order to obtain a ticket content
GET /rest/actor/ticket/[ticketId]
GET /rest/actor/ticket/[ticketId]?key=masterKey&[secure=true|1|false|0]
'''
logger.debug("Ticket args for GET: {0}".format(self._args))
secure = self._params.get('secure') in ('1', 'true')
if len(self._args) != 2:
raise RequestError('Invalid request')
@ -139,21 +141,6 @@ class Actor(Handler):
except Exception:
return Actor.result({})
def getSecureTicket(self):
'''
Processes get request for SECURE tickets request, i.e. tickets that can only be got by actors with valid credentials
GET /rest/actor/sticket/[ticketId]?key=[master key]
'''
logger.debug('Get secure ticket value for {}'.format(self._args))
# v = self.validateRequestKey()
# if v is not None:
# return v
# TODO: Remove this, is just for testings
# return Actor.result({'username': 'user', 'password': 'password', 'domain': None})
# return self.getTicket(secure=True)
raise RequestError('Invalid request')
def get(self):
'''
Processes get requests
@ -166,9 +153,6 @@ class Actor(Handler):
if self._args[0] == 'ticket':
return self.getTicket()
if self._args[0] == 'sticket':
return self.getSecureTicket()
if self._args[0] == 'testn': # Test, but without master key
return self.test()