summaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
authorsjtufs <[email protected]>2013-09-01 07:31:07 +0800
committersjtufs <[email protected]>2013-09-01 07:31:07 +0800
commitcd5d54a80a157ca816546e2af3a04a1cff14b5cc (patch)
treea4e41f60ff5bb023874cf712f102d743bf2ded51 /server
parent46dad6a4660d968a4806b108659fad1e43548294 (diff)
parentc2ac1f73431bbcef437aac017465865e5fb086d9 (diff)
Merge branch 'master' of github.com:Determinant/piztor
Diffstat (limited to 'server')
-rw-r--r--server/piztor/easy_import.py82
-rw-r--r--server/piztor/gen_users.py3
-rw-r--r--server/piztor/mesg_sender.py11
-rw-r--r--server/piztor/prober.py17
-rw-r--r--server/piztor/ptp.rst30
-rw-r--r--server/piztor/ptp_send.py35
-rw-r--r--server/piztor/server.py138
7 files changed, 249 insertions, 67 deletions
diff --git a/server/piztor/easy_import.py b/server/piztor/easy_import.py
new file mode 100644
index 0000000..e103de7
--- /dev/null
+++ b/server/piztor/easy_import.py
@@ -0,0 +1,82 @@
+from sqlalchemy import create_engine
+from sqlalchemy.orm import sessionmaker
+from model import *
+
+path = "root:helloworld@localhost/piztor"
+
+class UserData:
+ def __init__(self, username, nickname, password,
+ comp_no, sec_no, sex, perm, sub):
+ self.username = username
+ self.nickname = nickname
+ self.password = password
+ self.comp_no = int(comp_no)
+ self.sec_no = int(sec_no)
+ self.sex = int(sex)
+ self.perm = perm
+ self.sub = sub
+
+def create_database():
+ engine = create_engine('mysql://' + path, echo = True)
+ Base.metadata.drop_all(engine)
+ Base.metadata.create_all(engine)
+
+def find_or_create_group(comp_no, sec_no, session):
+ gid = UserModel.to_gid(comp_no, sec_no)
+ q = session.query(GroupInfo).filter(GroupInfo.id == gid)
+ entry = q.first()
+ if not entry:
+ entry = GroupInfo(gid = gid)
+ return entry
+
+
+def import_user_data(data):
+ engine = create_engine('mysql://' + path, echo = True)
+ Session = sessionmaker(bind = engine)
+ session = Session()
+
+ for user in data:
+ um = UserModel(username = user.username,
+ nickname = user.nickname,
+ sex = user.sex,
+ comp_no = user.comp_no,
+ sec_no = user.sec_no,
+ perm = user.perm)
+
+ for cn, sn in user.sub:
+ print cn, sn
+ g = find_or_create_group(int(cn), int(sn), session)
+ um.sub.append(g)
+ um.auth = UserAuth(user.password)
+ um.location = LocationInfo(lat = 0, lng = 0)
+ session.add(um)
+ session.commit()
+
+if __name__ == '__main__':
+
+ from sys import argv, exit
+ if len(argv) != 2:
+ print "Usage: " + argv[0] + " FILE"
+ exit(0)
+
+ data = list()
+ with open(argv[1], 'r') as f:
+ while True:
+ line = f.readline().split()
+ if len(line) == 0: break
+ idx = 0
+ comp_no = line[3]
+ sec_no = line[4]
+ sub = [ (comp_no, sec_no), (comp_no, 0xff) ]
+ data.append(UserData(username = line[0],
+ nickname = line[1],
+ password = line[0],
+ comp_no = comp_no,
+ sec_no = sec_no,
+ sex = line[2],
+ perm = line[5],
+ sub = sub))
+
+
+ create_database()
+ import_user_data(data)
diff --git a/server/piztor/gen_users.py b/server/piztor/gen_users.py
index 2d4d67b..2fd57b5 100644
--- a/server/piztor/gen_users.py
+++ b/server/piztor/gen_users.py
@@ -7,4 +7,5 @@ def get_rand_sex():
return randint(0, 1)
for i in xrange(100):
- print i, i, get_rand_gid(), get_rand_sex()
+ print i, i, i, 23, 15, get_rand_sex(), 0
+ print "23 15"
diff --git a/server/piztor/mesg_sender.py b/server/piztor/mesg_sender.py
index fb9b5a5..f7df236 100644
--- a/server/piztor/mesg_sender.py
+++ b/server/piztor/mesg_sender.py
@@ -4,8 +4,8 @@ from time import sleep
from sys import argv
from ptp_send import *
-username = "hello"
-password = "world"
+username = "yg"
+password = "yg"
mesg = "niu x push!"
#username = "1234567890123456789012"
#password = "world12345678901234567890"
@@ -20,10 +20,11 @@ if len(argv) == 4:
token = user_auth(username, password)
-set_marker(token, username, 123.456, 456.123, 0x7fffffff)
-#send_text_mesg(token, username, mesg)
+update_location(token, username, 31.028616, 121.434661)
+update_location(token, username, 31.028616, 121.434661)
+set_marker(token, username, 10.028716, 121.545661, 0x7fffffff)
+send_text_mesg(token, username, mesg)
#send_text_mesg(token, username, "a")
#send_text_mesg(token, username, "the last")
-#update_location(token, username, 31.028616, 121.434661)
logout(token, username)
diff --git a/server/piztor/prober.py b/server/piztor/prober.py
index 5f57a94..bb2bcd3 100644
--- a/server/piztor/prober.py
+++ b/server/piztor/prober.py
@@ -18,13 +18,10 @@ if len(argv) == 3:
token = user_auth(username, password)
-
-update_sub(token, username,
- [
- (23, 15), (23, 15), (23, 255), (23, 255),
- (23, 15), (23, 15), (23, 255), (23, 255),
- (23, 15), (23, 15), (23, 255), (23, 255),
- (23, 15), (23, 15), (23, 255), (23, 255),
- (23, 15), (23, 15),
- ])
-user_info(token, username, 23, 15)
+change_password(token, username, "ddd", "haha")
+#print "Client: " + username + "logged in"
+#open_push_tunnel(token, username)
+#for i in xrange(100):
+# print "Client: " + username + " updateing"
+# update_location(token, username, 123.456, 123.456)
+## sleep(5)
diff --git a/server/piztor/ptp.rst b/server/piztor/ptp.rst
index 6d8ff30..4473e5c 100644
--- a/server/piztor/ptp.rst
+++ b/server/piztor/ptp.rst
@@ -1,4 +1,4 @@
-Piztor Transmission Protocol v2.0a
+Piztor Transmission Protocol v2.0c
----------------------------------
- Pull
@@ -255,6 +255,28 @@ Piztor Transmission Protocol v2.0a
- ``0x01`` for invalid token
- ``0x02`` for insufficient level
+ - Change Password ``0x08``
+
+ - Request
+
+ ::
+
+ +-------------+-------?b-------+-------?b-------+
+ | AUTH_HEAD | OLD_PASSWORD | NEW_PASSWORD |
+ +-------------+-----string-----+-----string-----+
+
+ - Response
+
+ ::
+
+ +--------+
+ | STATUS |
+ +--------+
+
+ - ``0x00`` for success
+ - ``0x01`` for invalid token
+ - ``0x03`` for wrong password
+
- Push Notification
- General Request
@@ -293,7 +315,7 @@ Piztor Transmission Protocol v2.0a
::
- ----+----8b----+----8b-----+----4b----+
- ... | LATITUDE | LONGITUDE | DEADLINE |
- ----+----------+-----------+----int---+
+ ----+--1b---+----8b----+----8b-----+----4b----+
+ ... | LEVEL | LATITUDE | LONGITUDE | DEADLINE |
+ ----+-uchar-+----------+-----------+----int---+
diff --git a/server/piztor/ptp_send.py b/server/piztor/ptp_send.py
index 22f9842..6c3b476 100644
--- a/server/piztor/ptp_send.py
+++ b/server/piztor/ptp_send.py
@@ -24,7 +24,8 @@ class _SectionSize:
LOCATION_ENTRY = USER_ID + LATITUDE + LONGITUDE
PADDING = 1
-host = "localhost" #"localhost"
+host = "202.120.7.4"
+#host = "localhost"
port = 2223
def pack_data(optcode, data):
@@ -86,14 +87,26 @@ def gen_set_marker(token, username, lat, lng, deadline):
data += pack("!ddL", lat, lng, deadline)
return pack_data(0x07, data)
+def gen_change_password(token, username, old_pass, new_pass):
+ data = pack("!32s", token)
+ data += username
+ data += chr(0)
+ data += old_pass
+ data += chr(0)
+ data += new_pass
+ data += chr(0)
+ return pack_data(0x08, data)
+
def send(data):
received = bytes()
+ from time import time
+ begin = time()
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((host, port))
sock.sendall(data)
while True:
- rd, wr, err = select([sock], [], [], 10)
+ rd, wr, err = select([sock], [], [])
if rd:
buff = sock.recv(4096)
if len(buff) == 0:
@@ -102,7 +115,10 @@ def send(data):
else:
break
finally:
+ print "closing"
+ sock.shutdown(1)
sock.close()
+ print "Waited for {} seconds".format(str(time() - begin))
return received
def user_auth(username, password):
@@ -112,16 +128,15 @@ def user_auth(username, password):
if pl != len(resp):
logger.error("User authentication: incorrect packet length")
print "status: " + str(status)
- print "token: " + get_hex(token)
- print get_hex(resp[38:])
+# print "token: " + get_hex(token)
except error:
logger.error("User authentication: can not parse the response")
+ print get_hex(resp)
return token
def update_location(token, username, lat, lng):
resp = send(gen_update_location(token, username, lat, lng))
- print get_hex(resp)
try:
pl, optcode, status = unpack("!LBB", resp[:6])
if pl != len(resp):
@@ -183,6 +198,16 @@ def set_marker(token, username, lat, lng, deadline):
except error:
logger.error("Set marker: can not parse the response")
+def change_password(token, username, old_pass, new_pass):
+ resp = send(gen_change_password(token, username, old_pass, new_pass))
+ try:
+ pl, optcode, status = unpack("!LBB", resp)
+ if pl != len(resp):
+ logger.error("Change password: incorrect packet length")
+ print "status: " + str(status)
+ except error:
+ logger.error("Change password: can not pase the response")
+
def open_push_tunnel(token, username):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((host, port))
diff --git a/server/piztor/server.py b/server/piztor/server.py
index 26ccc4b..9435ccc 100644
--- a/server/piztor/server.py
+++ b/server/piztor/server.py
@@ -63,11 +63,13 @@ class _OptCode:
open_push_tunnel = 0x05
send_text_mesg = 0x06
set_marker = 0x07
+ change_password = 0x08
class _StatusCode:
sucess = 0x00
auth_fail = 0x01
insuf_lvl = 0x02
+ wrong_pass = 0x03
class PushData(object):
from hashlib import sha256
@@ -87,8 +89,8 @@ class PushLocationData(PushData):
self.pack(0x01, struct.pack("!Ldd", uid, lat, lng))
class PushMarkerData(PushData):
- def __init__(self, lat, lng, deadline):
- self.pack(0x02, struct.pack("!ddl", lat, lng, deadline))
+ def __init__(self, perm, lat, lng, deadline):
+ self.pack(0x02, struct.pack("!Bddl", perm, lat, lng, deadline))
class PushTunnel(object):
def __init__(self, uid):
@@ -113,7 +115,7 @@ class PushTunnel(object):
length, optcode, fingerprint = struct.unpack("!LB32s", data)
if front.finger_print != fingerprint:
raise PiztorError
- logger.info("-- Push data confirmed by client --")
+ logger.info("-- Push data confirmed by client %s --", str(self.uid))
self.blocked = False
self.push()
@@ -345,9 +347,9 @@ class UpdateLocationHandler(RequestHandler):
except struct.error:
raise BadReqError("Update location: 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))
+# 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
@@ -411,9 +413,9 @@ class UserInfoHandler(RequestHandler):
except struct.error:
raise BadReqError("User info request: Malformed request body")
- logger.info("Trying to get user info with " \
- "(token = {0}, gid = {1})" \
- .format(get_hex(token), gid))
+# logger.info("Trying to get user info with " \
+# "(token = {0}, gid = {1})" \
+# .format(get_hex(token), gid))
uauth = RequestHandler.get_uauth(token, username, self.session)
# Auth failure
@@ -464,9 +466,9 @@ class UpdateSubscription(RequestHandler):
except struct.error:
raise BadReqError("Update Subscription: Malformed request body")
- logger.info("Trying to update subscription with "
- "(token = {0}, username = {1}, grps = {2})"\
- .format(get_hex(token), username, str(sub_list)))
+# logger.info("Trying to update subscription with "
+# "(token = {0}, username = {1}, grps = {2})"\
+# .format(get_hex(token), username, str(sub_list)))
uauth = RequestHandler.get_uauth(token, username, self.session)
# Authentication failure
@@ -496,9 +498,9 @@ class UserLogoutHandler(RequestHandler):
except struct.error:
raise BadReqError("User logout: Malformed request body")
- logger.info("Trying to logout with "
- "(token = {0}, username = {1})"\
- .format(get_hex(token), username))
+# logger.info("Trying to logout with "
+# "(token = {0}, username = {1})"\
+# .format(get_hex(token), username))
uauth = RequestHandler.get_uauth(token, username, self.session)
# Authentication failure
@@ -530,9 +532,9 @@ class OpenPushTunnelHandler(RequestHandler):
except struct.error:
raise BadReqError("Open push tunnel: Malformed request body")
- logger.info("Trying to open push tunnel with "
- "(token = {0}, username = {1})"\
- .format(get_hex(token), username))
+# logger.info("Trying to open push tunnel with "
+# "(token = {0}, username = {1})"\
+# .format(get_hex(token), username))
uauth = RequestHandler.get_uauth(token, username, self.session)
# Authentication failure
@@ -565,9 +567,9 @@ class SendTextMessageHandler(RequestHandler):
except struct.error:
raise BadReqError("Send text mesg: Malformed request body")
- logger.info("Trying to send text mesg with "
- "(token = {0}, username = {1})"\
- .format(get_hex(token), username))
+# logger.info("Trying to send text mesg with "
+# "(token = {0}, username = {1})"\
+# .format(get_hex(token), username))
uauth = RequestHandler.get_uauth(token, username, self.session)
# Authentication failure
@@ -610,9 +612,9 @@ class SetMarkerHandler(RequestHandler):
except struct.error:
raise BadReqError("Set marker: Malformed request body")
- logger.info("Trying to set marker with "
- "(token = {0}, username = {1})"\
- .format(get_hex(token), username))
+# logger.info("Trying to set marker with "
+# "(token = {0}, username = {1})"\
+# .format(get_hex(token), username))
uauth = RequestHandler.get_uauth(token, username, self.session)
# Authentication failure
@@ -636,11 +638,56 @@ class SetMarkerHandler(RequestHandler):
if uid == uauth.uid: continue
if pt.has_key(uid):
tunnel = pt[uid]
- tunnel.add(PushMarkerData(lat, lng, deadline))
+ tunnel.add(PushMarkerData(u.perm, lat, lng, deadline))
tunnel.push()
logger.info("Set marker successfully!")
return self.pack(struct.pack("!B", _StatusCode.sucess))
+class ChangePasswordHandler(RequestHandler):
+
+ _optcode = _OptCode.change_password
+ _max_tr_data_size = _MAX_AUTH_HEAD_SIZE + \
+ MAX_PASSWORD_SIZE + \
+ _SectionSize.PADDING + \
+ MAX_PASSWORD_SIZE + \
+ _SectionSize.PADDING
+
+ def handle(self, tr_data, conn):
+ self.check_size(tr_data)
+ logger.info("Reading change password data...")
+ try:
+ token, = struct.unpack("!32s", tr_data[:32])
+ username, tail = RequestHandler.trunc_padding(tr_data[32:])
+ if username is None:
+ raise struct.error
+ old_pass, tail = RequestHandler.trunc_padding(tail)
+ new_pass = tail[:-1]
+ except struct.error:
+ raise BadReqError("User logout: Malformed request body")
+
+ logger.info("Trying to change password with "
+ "(token = {0}, username = {1}, old_pass = {2}, new_pass = {3})"\
+ .format(get_hex(token), username, old_pass, new_pass))
+
+ uauth = RequestHandler.get_uauth(token, username, self.session)
+ # Authentication failure
+ if uauth is None:
+ logger.warning("Authentication failure")
+ return self.pack(struct.pack("!B", _StatusCode.auth_fail))
+ if not uauth.check_password(old_pass):
+ return self.pack(struct.pack("!B", _StatusCode.wrong_pass))
+ uauth.set_password(new_pass)
+ self.session.commit()
+ logger.info("Password changed successfully!")
+
+ pt = RequestHandler.push_tunnels
+ uid = uauth.uid
+ pt[uid].close()
+ del pt[uid]
+ uauth.regen_token()
+
+ return self.pack(struct.pack("!B", _StatusCode.sucess))
+
class PTP(Protocol, TimeoutMixin):
@@ -651,7 +698,8 @@ class PTP(Protocol, TimeoutMixin):
UserLogoutHandler,
OpenPushTunnelHandler,
SendTextMessageHandler,
- SetMarkerHandler]
+ SetMarkerHandler,
+ ChangePasswordHandler]
handler_num = len(handlers)
@@ -676,6 +724,25 @@ class PTP(Protocol, TimeoutMixin):
logger.info("A new connection is made")
self.setTimeout(self.factory.timeout)
+ def response(self, buff):
+ try:
+ h = PTP.handlers[self.optcode]()
+ reply = h.handle(buff[5:], self)
+# logger.info("Wrote: %s", get_hex(reply))
+ self.transport.write(reply)
+ if self.tunnel:
+ logger.info("Blocking the client...")
+ self.tunnel.push()
+ self.length = -1
+ return
+ self.transport.loseConnection()
+ except BadReqError as e:
+ logger.warn("Rejected a bad request: %s", str(e))
+ self.transport.loseConnection()
+ except DBCorruptionError:
+ logger.error("*** Database corruption ***")
+
+
def dataReceived(self, data):
self.buff += data
self.resetTimeout()
@@ -701,25 +768,12 @@ class PTP(Protocol, TimeoutMixin):
self.tunnel.on_receive(buff)
self.length = -1
return
- h = PTP.handlers[self.optcode]()
- reply = h.handle(buff[5:], self)
- logger.info("Wrote: %s", get_hex(reply))
- self.transport.write(reply)
- if self.tunnel:
- logger.info("Blocking the client...")
- self.tunnel.push()
- self.length = -1
- self.setTimeout(None)
- return
- self.transport.loseConnection()
+ self.setTimeout(None)
+ reactor.callFromThread(self.response, buff)
+ #self.response(buff)
except BadReqError as e:
logger.warn("Rejected a bad request: %s", str(e))
self.transport.loseConnection()
- except DBCorruptionError:
- logger.error("*** Database corruption ***")
- self.transport.loseConnection()
- if self.tunnel is None:
- self.transport.loseConnection()
def connectionLost(self, reason):
if self.tunnel: