summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTeddy <ted.sybil@gmail.com>2013-08-24 21:47:35 +0800
committerTeddy <ted.sybil@gmail.com>2013-08-24 21:47:35 +0800
commit0f3318eba61d5c2975ed844659995e8f1ec2b1a9 (patch)
tree59d7069a7d3e8b73ad206887b521eb31badd319b
parent25fcbcc8a369d64c4b44850afde3e558dd3f8711 (diff)
new implementation
-rw-r--r--server/piztor/exc.py14
-rw-r--r--server/piztor/import.py44
-rw-r--r--server/piztor/model.py78
3 files changed, 136 insertions, 0 deletions
diff --git a/server/piztor/exc.py b/server/piztor/exc.py
new file mode 100644
index 0000000..5daf420
--- /dev/null
+++ b/server/piztor/exc.py
@@ -0,0 +1,14 @@
+class PiztorError(Exception):
+ pass
+
+class ConnectionError(PiztorError):
+ pass
+
+class ReqReadError(ConnectionError):
+ pass
+
+class BadReqError(ConnectionError):
+ pass
+
+class InvalidTokenError(ConnectionError):
+ pass
diff --git a/server/piztor/import.py b/server/piztor/import.py
new file mode 100644
index 0000000..1521849
--- /dev/null
+++ b/server/piztor/import.py
@@ -0,0 +1,44 @@
+from sqlalchemy import create_engine
+from sqlalchemy.orm import sessionmaker
+from model import *
+
+path = "piztor.sqlite"
+
+class UserData:
+ def __init__(self, username, password, sex):
+ self.username = username
+ self.password = password
+ self.sex = sex
+
+def create_database():
+ engine = create_engine('sqlite:///' + path, echo = True)
+ Base.metadata.drop_all(engine)
+ Base.metadata.create_all(engine)
+
+def import_user_data(data):
+ engine = create_engine('sqlite:///' + path, echo = True)
+ Session = sessionmaker(bind = engine)
+ session = Session()
+ for user in data:
+ um = UserModel(username = user.username, sex = user.sex)
+ 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
+ data.append(UserData(line[0], line[1], line[2]))
+
+ create_database()
+ import_user_data(data)
diff --git a/server/piztor/model.py b/server/piztor/model.py
new file mode 100644
index 0000000..d869c32
--- /dev/null
+++ b/server/piztor/model.py
@@ -0,0 +1,78 @@
+from sqlalchemy import Column, Integer, String, Float, ForeignKey, LargeBinary, Boolean
+from sqlalchemy.ext.declarative import declarative_base
+from sqlalchemy.orm import relationship, backref
+
+Base = declarative_base()
+_SALT_LEN = 16
+_TOKEN_LEN = 16
+
+class _TableName: # avoid typoes
+ UserModel = 'users'
+ LocationInfo = 'location_info'
+ UserAuth = 'user_auth'
+
+class UserModel(Base):
+ __tablename__ = _TableName.UserModel
+
+ id = Column(Integer, primary_key = True)
+ username = Column(String)
+ sex = Column(Boolean)
+ location = None
+ auth = None
+
+class LocationInfo(Base):
+ __tablename__ = _TableName.LocationInfo
+
+ uid = Column(Integer, ForeignKey('users.id'), primary_key = True)
+ lat = Column(Float(precesion = 64))
+ lng = Column(Float(precesion = 64))
+ user = relationship("UserModel", uselist = False,
+ backref = backref("location", uselist = False,
+ cascade = "all, delete-orphan"))
+
+ # More: last_update
+
+from hashlib import sha256
+from os import urandom
+
+def _sprinkle_salt(uauth, passwd):
+ data = sha256(uauth.salt)
+ data.update(chr(0))
+ data.update(passwd)
+ return data.digest()
+
+def _random_binary_string(length):
+ return urandom(length)
+
+class UserAuth(Base):
+ __tablename__ = _TableName.UserAuth
+
+ uid = Column(Integer, ForeignKey('users.id'), primary_key = True)
+ password = Column(LargeBinary)
+ salt = Column(LargeBinary)
+ token = Column(LargeBinary)
+
+ user = relationship("UserModel", uselist = False,
+ backref = backref("auth", uselist = False,
+ cascade = "all, delete-orphan"))
+
+ def regen_token(self):
+ self.token = sha256(_random_binary_string(_TOKEN_LEN)).digest()
+
+ def __init__(self, passwd):
+ self.set_password(passwd)
+
+ def set_password(self, passwd):
+ self.salt = _random_binary_string(_SALT_LEN)
+ self.password = _sprinkle_salt(self, passwd)
+ self.regen_token()
+
+ def check_password(self, passwd):
+ passwd = _sprinkle_salt(self, passwd)
+ return passwd == self.password
+
+ def check_token(self, tk):
+ return self.token == tk
+
+ def get_token(self):
+ return self.token