from datetime import datetime import enum import hashlib import os from formity.extensions import db from sqlalchemy.ext.hybrid import hybrid_property class Status(enum.Enum): new = 1 confirmed = 2 allocated = 3 fulfilled = 4 rejected = 5 spam = 6 delegated = 7 intransit = 8 shippingpending = 9 pickuppending = 10 class PostalCode(db.Model): postalcode = db.Column(db.String, primary_key=True) address = db.Column(db.String, nullable=False) city = db.Column(db.String, nullable=False) voivodeship = db.Column(db.String, nullable=False) county = db.Column(db.String, nullable=False) class FaceshieldRequest(db.Model): id = db.Column(db.Integer, primary_key=True) entity_info = db.Column(db.String) full_name = db.Column(db.String) phone_number = db.Column(db.String) email = db.Column(db.String) extra = db.Column(db.String) faceshield_front_required = db.Column(db.Integer, default=0, server_default='0') faceshield_model = db.Column(db.String) faceshield_full_required = db.Column(db.Integer, default=0, server_default='0') created = db.Column(db.DateTime, default=datetime.utcnow, nullable=False) updated = db.Column(db.DateTime, default=datetime.utcnow, nullable=False, onupdate=datetime.utcnow) ua = db.Column(db.String) ip = db.Column(db.String) status = db.Column(db.Enum(Status), default=Status.new, server_default='new', nullable=False) remarks = db.Column(db.String) faceshield_front_delivered = db.Column(db.Integer, default=0, server_default='0') faceshield_full_delivered = db.Column(db.Integer, default=0, server_default='0') shipping_name = db.Column(db.String) shipping_street = db.Column(db.String) shipping_postalcode = db.Column(db.String) shipping_city = db.Column(db.String) shipping_latitude = db.Column(db.Float) shipping_longitude = db.Column(db.Float) postalcode_info = db.relationship(PostalCode, primaryjoin='remote(PostalCode.postalcode) == foreign(FaceshieldRequest.shipping_postalcode)') handling_orga = db.Column(db.String, default='hswaw', server_default='hswaw', nullable=False) def __str__(self): return '#{} {} ({})'.format(self.id, self.entity_info, self.status.name) class RequestChange(db.Model): id = db.Column(db.Integer, primary_key=True) request_id = db.Column(db.Integer, db.ForeignKey(FaceshieldRequest.id)) request = db.relationship(FaceshieldRequest, backref='changelog') user_id = db.Column(db.String, nullable=False) state_before = db.Column(db.JSON) state_after = db.Column(db.JSON) remarks = db.Column(db.String) created = db.Column(db.DateTime, default=datetime.utcnow, nullable=False) class ExternalUser(db.Model): id = db.Column(db.Integer, primary_key=True) email = db.Column(db.String, nullable=False) _password = db.Column('password', db.String, nullable=False) remarks = db.Column(db.String) def _hash(self, salt, password): return hashlib.pbkdf2_hmac('sha256', password.encode(), salt.encode(), 213700).hex() @hybrid_property def password(self): return self._password @password.setter def password(self, new_pass): # hack: do not double hash if self._password == new_pass: return salt = hashlib.sha256(os.urandom(16)).hexdigest() self._password = salt + ':' + self._hash(salt, new_pass) def check_password(self, password): salt, h = self.password.split(':') return self._hash(salt, password) == h