summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTeddy <ted.sybil@gmail.com>2013-08-27 16:23:27 +0800
committerTeddy <ted.sybil@gmail.com>2013-08-27 16:23:27 +0800
commit193c42df2fdcf9f29de75389ef217e0817b00054 (patch)
tree8f99b08add45dd47e7380ea5d237770a651e7751
parent9b2e7086a1ea7e7a2de70a24a3847806d75fa250 (diff)
ptp v4.0a std-complaint server
-rw-r--r--server/piztor/exc.py2
-rw-r--r--server/piztor/prober.py19
-rw-r--r--server/piztor/server.py87
3 files changed, 82 insertions, 26 deletions
diff --git a/server/piztor/exc.py b/server/piztor/exc.py
index 390193c..26b6210 100644
--- a/server/piztor/exc.py
+++ b/server/piztor/exc.py
@@ -1,7 +1,7 @@
class PiztorError(Exception):
pass
-class DBCurruptedError(PiztorError):
+class DBCorruptionError(PiztorError):
pass
class BadReqError(PiztorError):
diff --git a/server/piztor/prober.py b/server/piztor/prober.py
index 6c28364..613d667 100644
--- a/server/piztor/prober.py
+++ b/server/piztor/prober.py
@@ -2,6 +2,7 @@ import socket
from struct import *
from random import random
from select import select
+from time import sleep
def get_hex(data):
return "".join([hex(ord(c))[2:].zfill(2) for c in data])
@@ -43,6 +44,13 @@ def gen_request_user_info(token, username, uid):
data += pack("!L", uid)
return data
+def gen_logout(token, username):
+ length = 4 + 1 + 32 + len(username) + 1
+ data = pack("!LB32s", length, 0x04, token)
+ data += username
+ data += chr(0)
+ return data
+
def send(data):
received = bytes()
try:
@@ -145,7 +153,16 @@ for i in xrange(10):
# print (info_key, info_value)
except:
print "fuck6"
- from time import sleep
+
+ resp = send(gen_logout(token, username))
+ try:
+ pl, optcode, status = unpack("!LBB", resp)
+ except:
+ print "fuck7"
+ if pl != len(resp): print "God!"
+# print "size: " + str((pl, len(resp)))
+# print "opt: " + str(optcode)
+# print "status: " + str(status)
sleep(10)
print failed_cnt
diff --git a/server/piztor/server.py b/server/piztor/server.py
index 1560735..18c2e2d 100644
--- a/server/piztor/server.py
+++ b/server/piztor/server.py
@@ -22,7 +22,7 @@ db_path = "root:helloworld@localhost/piztor"
FORMAT = "%(asctime)-15s %(message)s"
logging.basicConfig(format = FORMAT)
logger = logging.getLogger('piztor_server')
-logger.setLevel(logging.WARN)
+logger.setLevel(logging.INFO)
engine = create_engine('mysql://' + db_path, echo = False, pool_size = 1024)
@@ -48,8 +48,9 @@ _HEADER_SIZE = _SectionSize.LENGTH + \
class _OptCode:
user_auth = 0x00
location_update = 0x01
- location_request= 0x02
- user_info_request = 0x03
+ location_info= 0x02
+ user_info = 0x03
+ user_logout = 0x04
class _StatusCode:
sucess = 0x00
@@ -85,7 +86,7 @@ class RequestHandler(object):
return None
except MultipleResultsFound:
- raise DBCorruptedError()
+ raise DBCorruptionError()
@classmethod
def trunc_padding(cls, data):
@@ -143,23 +144,23 @@ class UserAuthHandler(RequestHandler):
.filter(UserModel.username == username).one()
except NoResultFound:
logger.info("No such user: {0}".format(username))
- return UserAuthHandler._failed_response
+ return self._failed_response
except MultipleResultsFound:
- raise DBCorruptedError()
+ raise DBCorruptionError()
uauth = user.auth
if uauth is None:
- raise DBCorruptedError()
+ raise DBCorruptionError()
if not uauth.check_password(password):
logger.info("Incorrect password: {0}".format(password))
- return UserAuthHandler._failed_response
+ return self._failed_response
else:
logger.info("Logged in sucessfully: {0}".format(username))
uauth.regen_token()
#logger.info("New token generated: " + get_hex(uauth.token))
self.session.commit()
- return struct.pack("!LBBL32s", UserAuthHandler._response_size,
+ return struct.pack("!LBBL32s", self._response_size,
_OptCode.user_auth,
_StatusCode.sucess,
user.id,
@@ -197,7 +198,7 @@ class LocationUpdateHandler(RequestHandler):
# Authentication failure
if uauth is None:
logger.warning("Authentication failure")
- return struct.pack("!LBB", LocationUpdateHandler._response_size,
+ return struct.pack("!LBB", self._response_size,
_OptCode.location_update,
_StatusCode.failure)
@@ -207,7 +208,7 @@ class LocationUpdateHandler(RequestHandler):
logger.info("Location is updated sucessfully")
self.session.commit()
- return struct.pack("!LBB", LocationUpdateHandler._response_size,
+ return struct.pack("!LBB", self._response_size,
_OptCode.location_update,
_StatusCode.sucess)
@@ -243,15 +244,15 @@ class LocationInfoHandler(RequestHandler):
# Auth failure
if uauth is None:
logger.warning("Authentication failure")
- return struct.pack("!LBB", LocationInfoHandler._response_size(0),
- _OptCode.location_request,
+ return struct.pack("!LBB", self._response_size(0),
+ _OptCode.location_info,
_StatusCode.failure)
ulist = self.session.query(UserModel).filter(UserModel.gid == gid).all()
reply = struct.pack(
"!LBB",
- LocationInfoHandler._response_size(len(ulist)),
- _OptCode.location_request,
+ self._response_size(len(ulist)),
+ _OptCode.location_info,
_StatusCode.sucess)
for user in ulist:
@@ -279,7 +280,7 @@ class UserInfoHandler(RequestHandler):
_fail_response = \
struct.pack("!LBB", _failed_response_size,
- _OptCode.user_info_request,
+ _OptCode.user_info,
_StatusCode.failure)
_code_map = {0x00 : ('gid', pack_int),
@@ -312,35 +313,73 @@ class UserInfoHandler(RequestHandler):
# Auth failure
if uauth is None:
logger.warning("Authentication failure")
- return UserInfoHandler._fail_response
+ return self._fail_response
# TODO: check the relationship between user and quser
user = uauth.user
- reply = struct.pack("!BB", _OptCode.user_info_request,
+ reply = struct.pack("!BB", _OptCode.user_info,
_StatusCode.sucess)
try:
quser = self.session.query(UserModel) \
.filter(UserModel.id == uid).one()
except NoResultFound:
logger.info("No such user: {0}".format(username))
- return UserInfoHandler._fail_response
+ return self._fail_response
except MultipleResultsFound:
- raise DBCorruptedError()
+ raise DBCorruptionError()
- for code in UserInfoHandler._code_map:
+ for code in self._code_map:
reply += UserInfoHandler.pack_entry(quser, code)
reply = struct.pack("!L", len(reply) + _SectionSize.LENGTH) + reply
return reply
-
+class UserLogoutHandler(RequestHandler):
+
+ _max_tr_data_size = _MAX_AUTH_HEAD_SIZE
+
+ _response_size = \
+ _SectionSize.LENGTH + \
+ _SectionSize.OPT_ID + \
+ _SectionSize.STATUS
+
+ def handle(self, tr_data):
+ self.check_size(tr_data)
+ logger.info("Reading user logout data...")
+ try:
+ token, = struct.unpack("!32s", tr_data[:32])
+ username, tail = RequestHandler.trunc_padding(tr_data[32:])
+ if username is None:
+ raise struct.error
+ except struct.error:
+ raise BadReqError("User logout: Malformed request body")
+
+# logger.info("Trying to update location with "
+# "(token = {0}, username = {1}, lat = {2}, lng = {3})"\
+# .format(get_hex(token), username, lat, lng))
+#
+ uauth = RequestHandler.get_uauth(token, username, self.session)
+ # Authentication failure
+ if uauth is None:
+ logger.warning("Authentication failure")
+ return struct.pack("!LBB", self._response_size,
+ _OptCode.location_update,
+ _StatusCode.failure)
+ uauth.regen_token()
+ logger.info("User Logged out successfully!")
+ self.session.commit()
+ return struct.pack("!LBB", self._response_size,
+ _OptCode.user_logout,
+ _StatusCode.sucess)
+
class PTP(Protocol, TimeoutMixin):
handlers = [UserAuthHandler,
LocationUpdateHandler,
LocationInfoHandler,
- UserInfoHandler]
+ UserInfoHandler,
+ UserLogoutHandler]
handler_num = len(handlers)
@@ -390,7 +429,7 @@ class PTP(Protocol, TimeoutMixin):
raise BadReqError("The actual length is larger than promised")
except BadReqError as e:
logger.warn("Rejected a bad request: %s", str(e))
- except DBCorruptedError:
+ except DBCorruptionError:
logger.error("*** Database corruption ***")
finally:
self.transport.loseConnection()