diff options
author | Teddy <[email protected]> | 2013-08-24 21:47:35 +0800 |
---|---|---|
committer | Teddy <[email protected]> | 2013-08-24 21:47:35 +0800 |
commit | 0f3318eba61d5c2975ed844659995e8f1ec2b1a9 (patch) | |
tree | 59d7069a7d3e8b73ad206887b521eb31badd319b | |
parent | 25fcbcc8a369d64c4b44850afde3e558dd3f8711 (diff) |
new implementation
-rw-r--r-- | server/piztor/exc.py | 14 | ||||
-rw-r--r-- | server/piztor/import.py | 44 | ||||
-rw-r--r-- | server/piztor/model.py | 78 |
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 |