def register(username: str, password: str, role: str, age: int): ''' Creates a new user.''' _id = _db.counter.find_one_and_update( {'_id': 'USER_COUNT'}, {'$inc': { 'count': 1 }}, return_document=pymongo.ReturnDocument.AFTER)['count'] _log.debug(_id) query = { "_id": _id, "username": username, "password": password, "role": role } user = User(_id, username, password, role, int(age)) _log.debug(query) try: _db.users.insert_one(user.to_dict()) except pymongo.errors.DuplicateKeyError: _log.info( 'Duplicate key error detected in the database for username %s', username) return 'Duplicate Username Error' except pymongo.errors.PyMongoError: _log.exception('register has failed in the db') return None return User.from_dict(_db.users.find_one({'_id': _id}))
def logout(): """ Clears user session TODO: invalidate JWT? :return: """ User.clear_user_session_id() return NoContent, 204
def test_register(self, mock_db): ''' Tests the registration in Mongo ''' mock_db.counter.find_one_and_update.return_value = {'count': -1} username = '******' password = '******' role = 'TEST ROLE' age = 65 user = User(-1, username, password, role, age) mock_db.users.insert_one.return_value = user mock_db.users.find_one.return_value = user.to_dict() ret_user = src.data.mongo.register(username, password, role, age) _log.debug(ret_user) self.assertEqual(ret_user.username, user.username)
def logout(): if request.method == "DELETE": empty = make_response({}) empty.set_cookie('authorization', '') return empty, 204 elif request.method == 'GET': auth_token = request.cookies.get('authorization') if auth_token: _log.debug(auth_token) _log.debug(User) _log.debug(User.decode_auth_token(auth_token)) return jsonify( db.get_user_by_id(User.decode_auth_token(auth_token))), 200 else: return {}, 401
def test_login(self, mock_user, mock_db): ''' Tests the login fn ''' mock_db.return_value = {'test': 'dict'} given_user = User() mock_user.return_value = given_user user = src.data.mongo.login('username', 'password') self.assertEqual(user, given_user)
def get_user_by_username(username: str): '''Returns a user by their id''' user = {} db_user = _db.users.find_one({'username': username}) if db_user: user = User.from_dict(db_user) return user
def login(username): '''handles requests to login and sets the cookies''' _log.debug("%s is logging in", username) if request.method == "POST": _log.debug(request.get_json()) _log.debug(request.path) password = request.get_json()["password"] user = db.login(username, password) if user: # Generate our token user_dict = user.to_dict() auth_token = user.encode_auth_token() response = make_response(jsonify(user_dict)) response.set_cookie('authorization', auth_token.decode()) return response, 200 return {}, 400 if request.method == "DELETE": _log.debug("Deleting user: %s", username) user = db.get_user_by_username(username) if user: auth_token = request.cookies.get("authorization") sender = db.get_user_by_id(User.decode_auth_token(auth_token)) if sender and (sender.usertype == "admin" or sender.usertype == "moderator"): db.delete_user_by_id(user._id) return "User Deleted", 200 return "Only an Admin or Moderator can delete a user", 401 return {}, 400 else: return {}, 501
def test_acc_helper(self, mock_calc, mock_db): ''' tests the accuracy helper''' set1 = Set(1, 1, 'test 1', ['test', 'test2'], ['test', 'test2']) set2 = Set(2, 2, 'test 1', ['test', 'test2'], ['test', 'test2']) set_list = [set1, set2] user_1 = User(1, 'test', 'test', 'voter') user_2 = User(2, 'test', 'test', 'voter') user_3 = User(3, 'test', 'test', 'voter') user_4 = User(4, 'test', 'test', 'voter') user_list = [user_1, user_2, user_3, user_4] mock_db.return_value = user_list mock_calc.return_value = .67 ret_list = set_accuracy_helper(set_list) _log.debug(mock_db) _log.debug(mock_calc) self.assertEqual(ret_list[0].accuracy, .67) self.assertEqual(ret_list[1].accuracy, .67)
def login(username: str, password: str): '''checks the given username/password combination against the database. returns the username for now. Will discus and return either the user id or username''' # query = {"username": username, "password": password} response = _db.users.find_one({'username': username}) if response: return User.from_dict(response) return None
def get_users_by_usertype(usertype): ''' Retrieves all users of a given usertype''' query = {'usertype': usertype} user_list = None try: user_list = _db.users.find(query) except pymongo.errors.PyMongoError: _log.exception('get_user_by_usertype failed on usertype %s', usertype) return [User.from_dict(user) for user in user_list] if user_list else None
def get_users_by_set(setid): ''' Returns a list of all users that have voted on a particular set''' query = {'voted_sets': setid} user_list = None try: user_list = _db.users.find(query) except pymongo.errors.PyMongoError: _log.exception('get_users_by_set has failed on set_id %d', setid) return [User.from_dict(user) for user in user_list] if user_list else None
def get_users_by_age_range(start_age, end_age): ''' Retrieves all users within the age range given. Start inclusive, End exclusive ''' query = {'$and': [{'age': {'$gte': start_age}}, {'age': {'$lt': end_age}}]} user_list = [] try: user_list = _db.users.find(query) except pymongo.errors.PyMongoError: _log.exception('get_users_by_age_range has failed on range %d to %d', start_age, end_age) return [User.from_dict(user) for user in user_list] if user_list else None
def login(body): """ Responds to a request for /api/login :param body: dict containing keys email, password :return: JWT token, message """ email = body['email'] password = body['password'] try: # Get the user object using their email (unique to every user) user = User.query.filter_by(email=email).first() # Try to authenticate the found user using their password if user and user.password_is_valid(password): # save user id in session for authorization purposes User.save_user_session_id(user.id) # Generate the access token. # This will be used as the authorization header access_token = user.generate_token(user.id) if access_token: response = { 'message': 'You logged in successfully.', 'access_token': access_token.decode(), 'uid': User.get_user_session_id(), } return response, 200 else: # User does not exist, return error message response = { 'message': 'Invalid email or password, Please try again' } return response, 401 except Exception as e: # Create a response containing an string error message response = {'message': str(e)} # Return a server error using the HTTP Error Code 500 (Internal Server Error) return response, 500
def change_user_password(token, body): """ Verifies token is valid, and updates user password :param token: jwt token :return: """ try: decoded = User.decode_token(token) uid = decoded.get('sub') password = body['password'] user = User.query.filter_by(id=uid).first() user.update_password(password) return 'Password updated', 200 except Exception as e: response = jsonify({'message': str(e)}) return response, 401
def update_usertype(username): if request.method == "POST": _log.debug("Updating user:%s usertype", username) user = db.get_user_by_username(username) if user: auth_token = request.cookies.get("authorization") sender = db.get_user_by_id(User.decode_auth_token(auth_token)) _log.debug(user._id) _log.debug(request.get_json()) #sender = db.get_user_by_username("admin") if sender and (sender.usertype == "admin" or sender.usertype == "moderator"): db.update_usertype(user._id, request.get_json()["usertype"]) return "Usertype updated", 200 return "Only an Admin can edit usertype", 401 return {}, 400 return {}, 501
def reset_password_verifier(token): """ Verifies token from url path (client side) is valid :param token: jwt token :return: """ try: decoded = User.decode_token(token) uid = decoded.get('sub') user = User.query.filter_by(id=uid).first() results = { 'uid': uid, 'message': 'Token verified', } return results, 200 except Exception as e: response = jsonify({'message': str(e)}) return response, 401
def register(body): """ Responds to a request for /api/register :param body: dict containing keys email, password :return: JWT token, message """ email = body['email'] password = body['password'] # query to see if user already exists user = User.query.filter_by(email=email).first() if not user: try: user = User(email=email, password=password) user.save() # save user id in session for authorization purposes User.save_user_session_id(user.id) # Generate the access token. This will be used as the authorization header access_token = user.generate_token(user.id) response = jsonify({ 'message': 'You registered successfully. Please log in', 'access_token': access_token.decode(), 'uid': User.get_user_session_id(), }) response.status_code = 201 return response except Exception as e: response = jsonify({'message': str(e)}) return response, 401 else: response = jsonify( {'message': 'There is an existing user. Please login.'}) response.status_code = 422 return response
def test_user_by_id(self, mock_db): ''' Tests get user by id ''' user = User(-1, 'TEST', 'TEST', 'VOTER', -1) mock_db.users.find_one.return_value = user.to_dict() ret_user = src.data.mongo.get_user_by_id(-1) self.assertEqual(user.username, ret_user.username)
def get_users(): try: user_list = _db.users.find() except pymongo.errors.PyMongoError: _log.exception('get_users has failed in the database') return [User.from_dict(user) for user in user_list]
def get_user_by_id(db_id: int): '''Returns a user by their id''' return User.from_dict(_db.users.find_one({'_id': db_id}))
def test_from_dict(self): '''tests the from_dict class method''' _log.debug("Testing User.from_dict()") dictionary = UserTests.user.__dict__ self.assertIsInstance(User.from_dict(dictionary), User, "Should return a User")
def setUp(self): '''set up for an individual test''' UserTests.user = User(1, "username", "password")
return _db.counter.find_one_and_update( {'_id': 'SET_COUNT'}, {'$inc': { 'count': 1 }}, return_document=pymongo.ReturnDocument.AFTER)['count'] if __name__ == '__main__': _db.sets.drop() _db.users.drop() _db.counter.drop() _db.counter.insert_one({'_id': 'SET_COUNT', 'count': 0}) set_list = [] set_list.append( Set( _get_set_id(), 1, 'Which scientist is known for developing the planetary model of the atom?', ['bohr.jpg', 'rutherford.jpg']).to_dict()) _db.sets.insert_one(set_list[0]) user_list = [] user_list.append( User(_get_set_id(), 'username', 'password', 'voter').to_dict()) user_list.append( User(_get_set_id(), 'jotaro', 'star_platinum', 'voter').to_dict()) user_list.append( User(_get_set_id(), 'diavolo', 'king_crimson', 'moderator').to_dict()) _db.users.insert_many(user_list)
def test_calc_acc(self): ''' Tests the fn calculate_set_accuracy''' user_1 = User(1, 'test', 'test', 'voter') user_2 = User(2, 'test', 'test', 'voter') user_3 = User(3, 'test', 'test', 'voter') user_4 = User(4, 'test', 'test', 'voter') user_1.voted_sets = [1, 1, 2, 3, 2, 1, 3] user_1.votes = [0, 1, 1, 1, 1, 0, 1] user_2.voted_sets = [1, 1, 2, 3] user_2.votes = [0, 0, 1, 1] user_3.voted_sets = [1] user_3.votes = [1] user_4.voted_sets = [1, 1, 1] user_4.votes = [1, 0, 0] user_list = [user_1, user_2, user_3, user_4] ret_accuracy = calculate_set_accuracy(user_list, 1) expected_accuracy = (2 / 4) self.assertEqual(ret_accuracy, expected_accuracy)
def get_user_session_id(): return User.get_user_session_id()