def deleteUser(username): usMgr = UserManager() user = usMgr.getOne(username) if user is None: raise MissingKey("no user with this username exists") success = usMgr.deleteOne(username) return {"success": success}
def register(): usMgr = UserManager() newUserVal = request.json usrPK = usMgr.addOne(newUserVal) success = True if usrPK else False result = {"success": success} return result
def setUp(self): logger = logging.getLogger(f"{__name__}.setUp") from app.UserManager import UserManager self.uMgr = UserManager() self.conn = self.uMgr.conn # clear table with self.conn.cursor() as cur: cur.execute(f"delete from {UserManager.TABLE_NAME}") self.conn.commit() # insert test user data self.uMgr.addOne(dict(zip( ["username", "password", "fName", "lName", "email"], ["stallylol", "123456", "Stally", "Duan", "*****@*****.**"] ))) self.uMgr.addOne(dict(zip( ["username", "password", "fName", "lName", "email"], ["shiyugun", "abcdef", "Shiyu", "Gao", "*****@*****.**"] ))) self.uMgr.addOne(dict(zip( ["username", "password", "fName", "lName", "email"], ["aspenrocks", "78910", "Aspen", "Forster", "*****@*****.**"] ))) self.uMgr.addOne(dict(zip( ["username", "password", "fName", "lName", "email"], ["toBeDeleted", "wtfwtf", "Dummy", "Value", "*****@*****.**"] ))) self.usernames = ["stallylol", "shiyugun", "aspenrocks", "toBeDeleted"]
def findUser(): usMgr = UserManager() query = usMgr.keepValidFieldsOnly(request.json, throw=True) # ignore empty values query = { k: v for k, v in query.items() if v is not None and v != "" and v != [] } users = usMgr.getMany(query) return users
def updateUser(username): usMgr = UserManager() newUserVal = usMgr.keepValidFieldsOnly(request.json, throw=True) # pop None / empty values newUserVal = { k: v for k, v in newUserVal.items() if v is not None and v != "" } success = usMgr.updateOne(username, newUserVal) result = {"success": success} return result
def addUser(): usMgr = UserManager() newUserVal = usMgr.keepValidFieldsOnly(request.json, throw=True) # pop None / empty values newUserVal = { k: v for k, v in newUserVal.items() if v is not None and v != "" } usrPk = usMgr.addOne(newUserVal) success = True if usrPk else False result = {"success": success} return result
def setUp(self): from app.BookingManager import BookingManager from app.UserManager import UserManager from app.CarManager import CarManager self.bkMgr = BookingManager() self.uMgr = UserManager() self.cMgr = CarManager() self.conn = self.bkMgr.conn self.bk_ids = [-1, -1, -1, -1, -1] self.car_ids = [-1] * 3 self.usernames = [] # firstly clear table with self.conn.cursor() as cur: cur.execute("delete from {}".format(BookingManager.TABLE_NAME)) cur.execute("delete from {}".format(CarManager.TABLE_NAME)) cur.execute("delete from {}".format(UserManager.TABLE_NAME)) self.conn.commit() # insert test user data self._insertUsers() # insert test car data self._insertCars() # insert test booking data values = [[ "stallylol", self.car_ids[0], '2020-05-01', '09:14:23', '2020-05-02', '09:15:00', "booked" ], [ "stallylol", self.car_ids[1], '2020-04-01', '09:14:23', '2020-04-02', '09:15:00', "finished" ], [ "shiyugun", self.car_ids[2], '2020-04-23', '09:14:23', '2020-04-25', '09:15:00', "cancelled" ], [ "shiyugun", self.car_ids[0], '2020-03-01', '05:20:00', '2020-03-02', '06:15:00', "finished" ], [ 'aspenrocks', self.car_ids[1], '2020-05-04', '11:14:23', '2020-05-010', '12:15:00', "booked" ]] for i in range(5): self.bk_ids[i] = self.bkMgr.addOne( dict( zip([ "username", "car_id", "date_booking", "time_booking", "date_return", "time_return", "status" ], values[i])))
class LoginManager: def __init__(self): self.user_manager = UserManager() def login_by_phone(self, phone=None): if not phone: return None user = self.user_manager.get_user_by_phone(phone) return user
class OrderManager: def __init__(self): self.user_manager = UserManager() def get_all_orders_for_collector(self, collector_id=None): if not collector_id: return None collector = self.user_manager.get_user_by_id(user_id=collector_id) if collector: orders_pickups = OrderPickup.objects.filter(collector=collector) return orders_pickups else: return None def get_order_by_id(self, order_id=None): if not order_id: return None if Order.objects.filter(id=order_id).exists(): return Order.objects.get(id=order_id) else: return None def get_payable_by_order(self, order=None): if not order: return None transactions = Transaction.objects.filter(order=order) payable = order.total if transactions: payable = order.total - sum([txn.amt for txn in transactions]) return payable
def __init__(self): self.public_exponent = 65537 self.key_size = 512 self.user_manager = UserManager() self.otp_length = 4
class EncryptionManager: def __init__(self): self.public_exponent = 65537 self.key_size = 512 self.user_manager = UserManager() self.otp_length = 4 def generate_key_pair_for_user(self, user_id): private_key = rsa.generate_private_key( public_exponent=self.public_exponent, key_size=self.key_size, backend=default_backend()) public_key = private_key.public_key() user = self.user_manager.get_user_by_id(user_id=user_id) print(type(user)) if user: user.privkey = private_key.private_bytes( encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.TraditionalOpenSSL, encryption_algorithm=serialization.NoEncryption()).decode() user.pubkey = public_key.public_bytes( encoding=serialization.Encoding.PEM, format=serialization.PublicFormat.SubjectPublicKeyInfo).decode( ) user.save() def get_private_key_by_user_id(self, user_id): # user = self.user_manager.get_user_by_id(user_id=user_id) # if not user.privkey: # self.generate_key_pair_for_user(user_id=user.id) # user = self.user_manager.get_user_by_id(user_id=user_id) with open(settings.PRIVKEY, "rb") as key_file: private_key = serialization.load_pem_private_key( key_file.read(), password=None, backend=default_backend()) return private_key def get_public_key_by_user_id(self, user_id): private_key = self.get_private_key_by_user_id(user_id) return private_key.public_key() def get_encrypted_cipher(self, user_id, data): public_key = self.get_public_key_by_user_id(user_id) ciphertext = public_key.encrypt( data.encode(), padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA1()), algorithm=hashes.SHA1(), label=None)) return ciphertext def get_decrypt_cipher(self, user_id, ciphertext): private_key = self.get_private_key_by_user_id(user_id) plaintext = private_key.decrypt( ciphertext, padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA1()), algorithm=hashes.SHA1(), label=None)) return plaintext def get_otp_string(self): otp = "" for _ in range(self.otp_length): otp += str(random.randint(1, 9)) return otp def get_signature(self, data, user_id): private_key = self.get_private_key_by_user_id(user_id) signature = private_key.sign( data.encode(), padding.PSS(mgf=padding.MGF1(hashes.SHA1()), salt_length=padding.PSS.MAX_LENGTH), hashes.SHA1()) return signature def get_encoded_signature(self, signature): return b64encode(signature) def get_decoded_signature(self, signature): return b64decode(signature) def is_data_verified(self, data, signature, user_id): public_key = self.get_public_key_by_user_id(user_id) print(type(signature)) try: public_key.verify( signature, data.encode(), padding.PSS(mgf=padding.MGF1(hashes.SHA1()), salt_length=padding.PSS.MAX_LENGTH), hashes.SHA1()) return True except Exception as e: print(e) return False
class TestBookingManager(_ut.TestCase): def setUp(self): from app.BookingManager import BookingManager from app.UserManager import UserManager from app.CarManager import CarManager self.bkMgr = BookingManager() self.uMgr = UserManager() self.cMgr = CarManager() self.conn = self.bkMgr.conn self.bk_ids = [-1, -1, -1, -1, -1] self.car_ids = [-1] * 3 self.usernames = [] # firstly clear table with self.conn.cursor() as cur: cur.execute("delete from {}".format(BookingManager.TABLE_NAME)) cur.execute("delete from {}".format(CarManager.TABLE_NAME)) cur.execute("delete from {}".format(UserManager.TABLE_NAME)) self.conn.commit() # insert test user data self._insertUsers() # insert test car data self._insertCars() # insert test booking data values = [[ "stallylol", self.car_ids[0], '2020-05-01', '09:14:23', '2020-05-02', '09:15:00', "booked" ], [ "stallylol", self.car_ids[1], '2020-04-01', '09:14:23', '2020-04-02', '09:15:00', "finished" ], [ "shiyugun", self.car_ids[2], '2020-04-23', '09:14:23', '2020-04-25', '09:15:00', "cancelled" ], [ "shiyugun", self.car_ids[0], '2020-03-01', '05:20:00', '2020-03-02', '06:15:00', "finished" ], [ 'aspenrocks', self.car_ids[1], '2020-05-04', '11:14:23', '2020-05-010', '12:15:00', "booked" ]] for i in range(5): self.bk_ids[i] = self.bkMgr.addOne( dict( zip([ "username", "car_id", "date_booking", "time_booking", "date_return", "time_return", "status" ], values[i]))) def _insertCars(self): self.car_ids[0] = self.cMgr.addOne( dict( zip([ "year", "car_model", "body_type", "num_seats", "car_colour", "cost_hour", "car_status" ], [2020, "Honda", "sedan", 5, "yellow", 23.45, "available"]))) self.car_ids[1] = self.cMgr.addOne( dict( zip([ "year", "car_model", "body_type", "num_seats", "car_colour", "cost_hour", "latitude", "longitude", "car_status" ], [ 2019, "Hyundai", "sedan", 5, "blue", 36.99, -37.813629, 144.963058, "available" ]))) self.car_ids[2] = self.cMgr.addOne( dict( zip([ "year", "car_model", "body_type", "num_seats", "car_colour", "cost_hour", "latitude", "longitude", "car_status" ], [ 2016, "Jeep", "truck", 8, "Red", 54.99, -38.150002, 144.350006, "available" ]))) def _insertUsers(self): self.usernames = ["stallylol", "shiyugun", "aspenrocks"] self.uMgr.addOne( dict( zip(["username", "password", "fName", "lName", "email"], [ "stallylol", "123456", "Stally", "Duan", "*****@*****.**" ]))) self.uMgr.addOne( dict( zip(["username", "password", "fName", "lName", "email"], ["shiyugun", "abcdef", "Shiyu", "Gao", "*****@*****.**" ]))) self.uMgr.addOne( dict( zip(["username", "password", "fName", "lName", "email"], [ "aspenrocks", "78910", "Aspen", "Forster", "*****@*****.**" ]))) def tearDown(self): # clear booking table with self.conn.cursor() as cur: for bk_id in self.bk_ids: cur.execute( f"delete from {self.bkMgr.TABLE_NAME} where booking_id = %s", bk_id) for car_id in self.car_ids: cur.execute( f"delete from {self.cMgr.TABLE_NAME} where car_id = %s", car_id) for username in self.usernames: cur.execute( f"delete from {self.uMgr.TABLE_NAME} where username = %s", username) self.conn.commit() def _countBookings(self): with self.conn.cursor() as cursor: cursor.execute("select count(*) from {}".format( self.bkMgr.TABLE_NAME)) return cursor.fetchone()[0] def _bookingExists(self, booking_id): with self.conn.cursor() as cursor: cursor.execute( f"SELECT COUNT(*) FROM {self.bkMgr.TABLE_NAME} WHERE booking_id = %s", (booking_id, )) return cursor.fetchone()[0] == 1 def testGetAll(self): log = logging.getLogger(f"{__name__}.testGetAll") # count total number of records count = self._countBookings() log.debug('number of booking records: ' + str(count)) # confirm number of results from no arg call matches number of bookings self.assertEqual(count, len(self.bkMgr.getMany({}))) def testGetAllForUser(self): # confirm that number of results returned matches number of specific users category self.assertEqual(2, len(self.bkMgr.getMany({"username": "******"}))) self.assertEqual(1, len(self.bkMgr.getMany({"username": "******"}))) # confirm it returns zero entries when getting bookings for a non-existent user self.assertEqual(0, len(self.bkMgr.getMany({"username": "******"}))) def testGetAllForUserFilterByStatu(self): # confirm returns correct result when supplied with user and status bookings = self.bkMgr.getMany({ "username": "******", "status": "cancelled" }) self.assertEqual(1, len(bookings)) # confirm returns correct result when supplied with user and incorrect status keyword self.assertEqual( 0, len( self.bkMgr.getMany({ "username": '******', "status": 'somethingwrong' }))) def testGetOne(self): '''check that `getOne` returns an item when supplying valid booking_id, and the returned item has the correct keys ''' log = logging.getLogger(f"{__name__}.testGetOne") booking = self.bkMgr.getOne(self.bk_ids[0]) self.assertTrue(self._bookingExists(self.bk_ids[0])) self.assertEqual( set([ "booking_id", "username", "car_id", "date_booking", "time_booking", "date_return", "time_return", "status" ]), set(booking.keys())) def testGetOneNonExistent(self): '''confirm that `getOne` returns None when booking_id not in db''' nonExistentId = self.bk_ids[-1] + 10 self.assertIsNone(self.bkMgr.getOne(nonExistentId)) def testAddOne(self): count = self._countBookings() newBooking = dict( zip([ "username", "car_id", "date_booking", "time_booking", "date_return", "time_return", "status" ], [ "aspenrocks", self.car_ids[2], '2020-05-20', '10:00:00', '2020-05-25', '10:00:00', "booked" ])) bk_id = self.bkMgr.addOne(newBooking) self.bk_ids.append(bk_id) booking = self.bkMgr.getOne(bk_id) self.assertEqual(dict(**newBooking, booking_id=bk_id), booking) self.assertEqual(count + 1, self._countBookings()) def testUpdateOneChangeStatus(self): # change status to 'finished' self.assertTrue( self.bkMgr.updateOne(self.bk_ids[0], {"status": "finished"})) self.assertTrue( self.bkMgr.updateOne(self.bk_ids[4], {"status": "cancelled"})) def testTransformDateTime(self): '''confirm that BookingManager.tranformDateTime transforms date & time from db format to ISO string ''' booking = { "date_booking": date(2020, 1, 1), "time_booking": timedelta(hours=19) } result = self.bkMgr.tranformDateTime(booking) self.assertEqual( { "date_booking": "2020-01-01", "time_booking": "19:00:00" }, result)
class TestUserManager(_ut.TestCase): def setUp(self): logger = logging.getLogger(f"{__name__}.setUp") from app.UserManager import UserManager self.uMgr = UserManager() self.conn = self.uMgr.conn # clear table with self.conn.cursor() as cur: cur.execute(f"delete from {UserManager.TABLE_NAME}") self.conn.commit() # insert test user data self.uMgr.addOne(dict(zip( ["username", "password", "fName", "lName", "email"], ["stallylol", "123456", "Stally", "Duan", "*****@*****.**"] ))) self.uMgr.addOne(dict(zip( ["username", "password", "fName", "lName", "email"], ["shiyugun", "abcdef", "Shiyu", "Gao", "*****@*****.**"] ))) self.uMgr.addOne(dict(zip( ["username", "password", "fName", "lName", "email"], ["aspenrocks", "78910", "Aspen", "Forster", "*****@*****.**"] ))) self.uMgr.addOne(dict(zip( ["username", "password", "fName", "lName", "email"], ["toBeDeleted", "wtfwtf", "Dummy", "Value", "*****@*****.**"] ))) self.usernames = ["stallylol", "shiyugun", "aspenrocks", "toBeDeleted"] def tearDown(self): logger = logging.getLogger(f"{__name__}.tearDown") # delete all inserted test data with self.conn.cursor() as cur: for username in self.usernames: cur.execute(f"delete from {self.uMgr.TABLE_NAME} where username = %s", username) self.conn.commit() def _countUsers(self): with self.conn.cursor() as cursor: cursor.execute("SELECT count(*) from {}".format(self.uMgr.TABLE_NAME)) return cursor.fetchone()[0] def _userExists(self, username): with self.connection.cursor() as cursor: cursor.execute(f"SELECT COUNT(*) FROM {self.uMgr.TABLE_NAME} WHERE username = %s", (username,)) return cursor.fetchone()[0] == 1 def testGetAll(self): '''confirm that number of records returned is same as number of records in test_database ''' self.assertEqual(self._countUsers(), len(self.uMgr.getMany({}))) def testGetOne(self): # confirm true when user exists self.assertEqual('aspenrocks', self.uMgr.getOne('aspenrocks')["username"]) # confirm that getItem() returns none when username not in db self.assertIsNone(self.uMgr.getOne("u34nonExistent")) def testAddOne(self): count = self._countUsers() success = self.uMgr.addOne(dict(zip( ["username", "password", 'fName', 'lName', "email"], ["papakase", "xxxyyy", "kaspian", "fitz", "*****@*****.**"] ))) self.assertTrue(success) self.assertTrue(count + 1, self._countUsers()) def testAddOneDuplicateUsername(self): '''confirm repeat username is rejected due to primary key constraint''' from app.errors.api_exceptions import DuplicateKey with self.assertRaises(DuplicateKey): self.uMgr.addOne(dict(zip( ["username", "password", 'fName', 'lName', "email"], ["stallylol", "612345", "Stally", "Duan", "*****@*****.**"] ))) def testAddOneNullEmail(self): '''confirm null values are rejected due to not null constraint''' from app.errors.api_exceptions import InvalidArgument with self.assertRaises(InvalidArgument): self.uMgr.addOne(dict(zip( ["username", "password", 'fName', 'lName', "email"], ["papakase", "element", "kaspian", "fitz", None] ))) def testUpdateOne(self): log = logging.getLogger(f"{__name__}.testUpdateOne") # update password log.debug(f"before updating, password is: {self.uMgr.getOne('stallylol')['password']}") self.assertTrue(self.uMgr.updateOne("stallylol", {"password": "******"})) self.assertEqual("111213", self.uMgr.getOne("stallylol")["password"]) def testUpdateOneNonExistentUser(self): # fail update becuase username does not exist self.assertFalse(self.uMgr.updateOne("someoneelse", {"password": "******"}))
def __init__(self): self.user_manager = UserManager()
def __init__(self): super().__init__() self.order_manager = OrderManager() self.encryption_manager = EncryptionManager() self.otp_manager = OTPManager() self.user_manager = UserManager()
class OrdersView(View): def __init__(self): super().__init__() self.order_manager = OrderManager() self.encryption_manager = EncryptionManager() self.otp_manager = OTPManager() self.user_manager = UserManager() def get(self, request, order_id=None): login_id = request.session.get('login_id', None) if not login_id: redirect(reverse('home')) if not order_id: pickups = self.order_manager.get_all_orders_for_collector(login_id) context = {"pickups": pickups if pickups else []} return render(request, "orders.html", context) if order_id: order = self.order_manager.get_order_by_id(order_id=order_id) if order: payable = self.order_manager.get_payable_by_order(order) context = {"order": order, "payable": payable} return render(request, "order.html", context) else: return redirect(reverse('orders')) def post(self, request, order_id=None): login_id = request.session.get('login_id', None) if not login_id: redirect(reverse('home')) if order_id: if request.POST.get('action') == 'start_transaction': payable = request.POST.get('payable') if not payable: return redirect(reverse('orders')) context = { "payable": int(payable), "order_id": order_id, "user_id": login_id } return render(request, "transact.html", context) if request.POST.get('action') == 'start_verification': order_id = request.POST.get('order_id') payable = request.POST.get('payable') user_id = request.POST.get('user_id') if order_id and payable and user_id: data = f"{order_id}.{payable}.{user_id}" print(data) ciphertext = self.encryption_manager.get_encrypted_cipher( user_id=int(user_id), data=data) plaintext = self.encryption_manager.get_decrypt_cipher( user_id=user_id, ciphertext=ciphertext) otp = self.encryption_manager.get_otp_string() data = f"{plaintext.decode()}.{otp}" signature = self.encryption_manager.get_signature( data=data, user_id=user_id) print(f'generated: {signature}') otp_message = f"Your OTP is - {otp}. Payable amount is Rs.{payable}" self.otp_manager.send_otp( data=otp_message, to=[self.user_manager.get_user_by_id(user_id).phone]) print(f'otp_message: {otp_message}') context = { "order_id": order_id, "payable": payable, "user_id": user_id, "cipher": b64encode(ciphertext).decode(), "signature": b64encode(signature).decode() } return render(request, "verify.html", context) else: return redirect(reverse('orders')) if request.POST.get('action') == 'start_otp_validation': otp = request.POST.get('otp') order_id = request.POST.get('order_id') payable = request.POST.get('payable') user_id = request.POST.get('user_id') signature = request.POST.get('signature') print(f'Received: {b64decode(signature)}') data = f"{order_id}.{payable}.{user_id}.{otp}" is_verified = self.encryption_manager.is_data_verified( data=data, signature=b64decode(signature), user_id=user_id) if is_verified: return render(request, "success.html") else: return redirect(reverse('orders'))