def admin(password): """ Creates an admin account if one doesn't exist :param password: password for the admin account. In the command line interface, you can specify this by giving the -p or --password argument, defaults to 'test' :type password: str, optional """ usr = User.query.first() if not usr: # If the first row in the table doesn't exist # Creates account with login "admin" and password "test"(both fields may be changed) try: admin = User(username="******", password=password) admin.save_to_db() # If everything is okay a message with the login and password from the admin account # will be displayed in the console print("Successfully created.\nLogin: {0}\nPassword: {1}".format( "admin", password)) except Exception as e: # If there is troubles with saving to database print("Unable to create: {0}".format(e)) else: # If admin already exists - do nothing print("Already exists.")
def test_password_hash(setup_database): """Compare the string with user password hash""" usr = User( name="Some Name Surname", email="*****@*****.**", username="******", password="******", ) assert not usr.check_password("cat")
def register_view(): """ New user registration view. Access only for admin. If the user tries to enter this route without logging in, he will be automatically redirected to the login page. If the user tries to enter this route without permission(user is not admin), he will be automatically redirected to the cabinet page. Methods: GET, POST """ if current_user.username != "admin": # If current user is not admin redirect him to the cabinet return redirect(url_for("cabinet.cabinet_view")) register_form = RegisterForm() # Set selector options register_form.tariff_select.choices = [ tariff.value["tariff_name"] for tariff in list(Tariffs) ] if request.method == "POST": data = request.form if register_form.validate_on_submit() or (data and current_app.testing): # if admin click the 'Register' button or there is data in the request while testing app # Create new user new_user = User( name=data.get("name"), phone=data.get("phone"), email=data.get("email"), username=data.get("username"), password=data.get("password"), tariff=data.get("tariff_select"), address=data.get("address"), state=State.activated_state.value, ) try: # if everything is okay - admin will be redirected to the admin page # and user will be created new_user.save_to_db() flash(messages["success_register"], "info") return redirect(url_for("admin.admin_view")) except ValueError as e: # error saving to the database # otherwise admin will be redirected to the register page # the user will not be created current_app.logger.info( "Error while saving new user to the database - {0}".format( e)) flash(messages["failure"], "warning") return redirect(url_for("admin.register_view")) return render_template("auth/register.html", title="Register new user", form=register_form)
def test_repr_user(setup_database): """Checks whether the user is correctly represented""" usr = User( name="Some Name Surname", phone="+380961122333", email="*****@*****.**", username="******", password="******", ) assert usr.__repr__() == "User: john"
def dataset(setup_database): """ Populate in-memory database. :param setup_database: pytest fixture """ db = setup_database # Creates users john = User(username="******", password="******") andre = User(username="******", password="******") db.session.add(john) db.session.add(andre) db.session.commit() yield db
def get(self): """ Creates access_token and refresh_token for the user if user exists and login, password from the request match. """ data = LoginSchema().load(request.get_json()) login = data.get("login") password = data.get("password") user = User.get_user_by_username(login) if user and user.check_password( password ): # if login and password from the request match - return access_token access_token = create_access_token(identity=user.uuid, fresh=True) refresh_token = create_refresh_token(user.uuid) decoded = decode_token(access_token) return { "access_token": access_token, "refresh_token": refresh_token, "fresh": decoded["fresh"], "expires_in": decoded["exp"], }, 200 # if user doesn't exist or login and password don't match - return 401 return {"message": "Unable to login."}, 401
def get(self, uuid: str): """Returns info about user""" curr_user = User.get_by_uuid(get_jwt_identity()) if curr_user.username != "admin" and curr_user.uuid != uuid: # if current user is not admin or account owner return 403 return {"message": messages["access_denied"]}, 403 user_schema = AdminUserInfoSchema( ) if curr_user.username == "admin" else FullUserInfoSchema() user = User.get_by_uuid(uuid) if user: return user_schema.dump(user), 200 return { "message": messages["user_not_found"] }, 404 # if uuid is wrong return 404
def test_users_resource(init_app): """Tests UsersResource""" app = init_app user_john = User.get_user_by_username("john") with app.test_client() as client: response_get_route_no_auth = client.get( url_for("api_user_history", uuid=user_john.uuid)) assert response_get_route_no_auth.status_code == 401 login_payload_john = json.dumps({"login": "******", "password": "******"}) access_token_john = get_access_token(client, login_payload_john) response_get_users_not_admin = client.get( url_for("api_users"), headers={"Authorization": "Bearer {0}".format(access_token_john)}, ) assert response_get_users_not_admin.status_code == 200 assert isinstance(response_get_users_not_admin.json, dict) assert response_get_users_not_admin.json.get("username") == "john" login_payload_admin = json.dumps({ "login": "******", "password": "******" }) access_token_admin = get_access_token(client, login_payload_admin) response_get_users_admin = client.get( url_for("api_users"), headers={"Authorization": "Bearer {0}".format(access_token_admin)}, ) assert response_get_users_admin.status_code == 200 assert isinstance(response_get_users_admin.json, list)
def post(self): """Logout user. The user must be logged in first.""" jti = get_jwt()["jti"] user = User.get_by_uuid(get_jwt_identity()) token = TokenBlocklist(user_id=user.id, jti=jti, reason="Logout") token.save_to_db() return {"message": messages["success"]}, 200
def init_app(): """Init and return app in test mode with in-memory database""" # Init runner = App(testing=True) runner.register_blueprints(login_bp, cabinet_bp, admin_bp) app = runner.get_flask_app() db = runner.db app_context = app.app_context() # Setup app_context.push() db.create_all() adm_usr = User(username="******", password="******") db.session.add(adm_usr) to_test_del = User(username="******", password="******") db.session.add(to_test_del) usr = User(username="******", password="******") db.session.add(usr) usr1 = User(username="******", password="******") db.session.add(usr1) for i in range(2): card = Card(amount=200, code=str(i).rjust(6, "0")) db.session.add(card) for i in range(2, 4): card = Card(amount=400, code=str(i).rjust(6, "0")) db.session.add(card) db.session.commit() with app.test_request_context(): yield app # Teardown db.session.remove() db.drop_all() app_context.pop()
def get(self, uuid: str): """Returns user payment history(This route is not protected: each user can see the story of another)""" curr_user = User.get_by_uuid(uuid) used_cards_schema = UsedCardSchema(many=True) if curr_user: # if uuid is correct return history history = curr_user.get_history() return used_cards_schema.dump(history), 200 return { "message": messages["user_not_found"] }, 404 # otherwise return 404
def get(self): """Returns list of users if current user is admin, else user's account info""" curr_user = User.get_by_uuid(get_jwt_identity()) if curr_user.username == "admin": # if current user is admin show common user information(AdminUserInfoSchema) users_schema = AdminUserInfoSchema(many=True) all_users = User.query.all() return users_schema.dump(all_users), 200 else: # if current user is account owner show full user information(FullUserInfoSchema) user_schema = FullUserInfoSchema() user = curr_user return user_schema.dump(user), 200
def post(self): """Creates new user and save it to the database. Available only for admin""" curr_user = User.get_by_uuid(get_jwt_identity()) if curr_user.username != "admin": return {"message": messages["access_denied"]}, 403 data = request.get_json() user = RegisterSchema().load(data) if User.get_user_by_username(data["username"]): return {"message": "This user already exists."}, 400 try: user.save_to_db() return {"message": messages["success_register"]}, 201 except ValueError as e: return { "message": messages["failure"] + " Error - {0}".format(e) }, 500
def post(self, uuid): """Work with user account""" curr_user = User.get_by_uuid(get_jwt_identity()) if curr_user.username != "admin": # if current is not admin return {"message": messages["access_denied"]}, 403 data = AdminChoiceSchema().load(request.get_json()) user_to_work = User.get_by_uuid(uuid) if data["choice"] == "activate": user_to_work.change_state() return {"message": messages["activate_state_success"]}, 200 elif data["choice"] == "deactivate": user_to_work.change_state(deactivate=True) return {"message": messages["deactivate_state_success"]}, 200 elif data["choice"] == "delete": try: # if everything is okay - user will be deleted from the database user_to_work.delete_from_db() return {"message": messages["success"]}, 200 except Exception as e: return {"message": messages["failure"] + " Error: {0}".format(e)}, 500
def test_change_state_and_set_ip(setup_database): """Test state change method""" usr = User(username="******", password="******", state=State.activated_state.value) # Activate usr.change_state(deactivate=False) assert usr.state == State.activated_state.value # Deactivate usr.change_state(deactivate=True) assert usr.state == State.deactivated_state.value # Set new ip prev_ip = usr.ip assert not usr.ip or prev_ip usr.set_ip() assert usr.ip and usr.ip != prev_ip and len(usr.ip.split(".")) == 4 # Set new UNIQUE ip test_ip = usr.ip usr.set_ip(test_ip=test_ip) assert usr.ip != test_ip
def post(self, uuid: str): """Use card""" curr_user = User.get_by_uuid(get_jwt_identity()) if curr_user.uuid != uuid: # if current user is not account owner return 403 return {"message": messages["access_denied"]}, 403 data = InputCardSchema().load(request.get_json()) if Card.get_card_by_code( data["code"] ): # if card code is correct - replenish user account curr_user.use_card(data["code"]) return {"message": messages["card_success_code"]}, 200 return { "message": messages["card_wrong_code"] }, 404 # if card code is wrong return 404
def test_create_and_add_user(dataset): """Creating an user object with parameters""" db = dataset # User object usr = User( name="Some Name Surname", phone="+380961122333", email="*****@*****.**", username="******", password="******", tariff="50m", ) assert usr is not None # Add to database assert len(db.session.query(User).all()) == 2 db.session.add(usr) db.session.commit() assert len(db.session.query(User).all()) == 3 assert db.session.query(User).get(3).username == "michael"
def test_user_history_resource(init_app): """Tests UserHistoryResource""" app = init_app user_john = User.get_user_by_username("john") with app.test_client() as client: response_get_route_no_auth = client.get( url_for("api_user_history", uuid=user_john.uuid)) assert response_get_route_no_auth.status_code == 401 login_payload_john = json.dumps({"login": "******", "password": "******"}) access_token = get_access_token(client, login_payload_john) response_get_user_history_wrong_uuid = client.get( url_for("api_user_history", uuid=uuid4()), headers={"Authorization": "Bearer {0}".format(access_token)}, ) assert response_get_user_history_wrong_uuid.status_code == 404 response_get_user_history_wrong_uuid = client.get( url_for("api_user_history", uuid=user_john.uuid), headers={"Authorization": "Bearer {0}".format(access_token)}, ) assert response_get_user_history_wrong_uuid.status_code == 200
def create_new_user(self, data, **kwargs): return User(**data)
def test_user_resource(init_app): """Tests UserResource""" app = init_app user_john = User.get_user_by_username("john") user_andre = User.get_user_by_username("andre") with app.test_client() as client: # GET response_get_route_no_headers_no_auth = client.get( url_for("api_user_details", uuid=user_john.uuid)) assert response_get_route_no_headers_no_auth.status_code == 401 login_payload_john = json.dumps({"login": "******", "password": "******"}) access_token = get_access_token(client, login_payload_john) response_get_user_route_john_uuid_andre = client.get( url_for("api_user_details", uuid=user_andre.uuid), headers={"Authorization": "Bearer {0}".format(access_token)}, ) assert response_get_user_route_john_uuid_andre.status_code == 403 response_get_user_route_john_uuid_john = client.get( url_for("api_user_details", uuid=user_john.uuid), headers={"Authorization": "Bearer {0}".format(access_token)}, ) assert response_get_user_route_john_uuid_john.status_code == 200 for key_ in ["name", "email", "phone"]: assert key_ in response_get_user_route_john_uuid_john.json.keys() login_payload_admin = json.dumps({ "login": "******", "password": "******" }) access_token = get_access_token(client, login_payload_admin) response_get_user_route_admin_uuid_john = client.get( url_for("api_user_details", uuid=user_john.uuid), headers={"Authorization": "Bearer {0}".format(access_token)}, ) assert response_get_user_route_admin_uuid_john.status_code == 200 for key_ in ["name", "email", "phone"]: assert key_ not in response_get_user_route_admin_uuid_john.json.keys( ) response_get_user_route_admin_uuid_john = client.get( url_for("api_user_details", uuid=uuid4()), headers={"Authorization": "Bearer {0}".format(access_token)}, ) assert response_get_user_route_admin_uuid_john.status_code == 404 # POST response_get_route_no_headers_no_auth = client.post( url_for("api_user_details", uuid=user_john.uuid)) assert response_get_route_no_headers_no_auth.status_code == 401 login_payload_john = json.dumps({"login": "******", "password": "******"}) access_token = get_access_token(client, login_payload_john) response_post_user_route_john_uuid_andre = client.post( url_for("api_user_details", uuid=user_andre.uuid), headers={"Authorization": "Bearer {0}".format(access_token)}, ) assert response_post_user_route_john_uuid_andre.status_code == 403 response_post_user_route_john_uuid_john_no_content = client.post( url_for("api_user_details", uuid=user_john.uuid), headers={"Authorization": "Bearer {0}".format(access_token)}, ) assert response_post_user_route_john_uuid_john_no_content.status_code == 400 response_post_user_route_john_uuid_john_invalid_card_code = client.post( url_for("api_user_details", uuid=user_john.uuid), headers={ "Authorization": "Bearer {0}".format(access_token), "Content-Type": "application/json", }, data=json.dumps({"code": "invalid"}), ) assert response_post_user_route_john_uuid_john_invalid_card_code.status_code == 404 assert User.get_user_by_username("john").balance == 0 response_post_user_route_john_uuid_john_valid_card_code = client.post( url_for("api_user_details", uuid=user_john.uuid), headers={ "Authorization": "Bearer {0}".format(access_token), "Content-Type": "application/json", }, data=json.dumps({"code": "000001"}), ) assert response_post_user_route_john_uuid_john_valid_card_code.status_code == 200 assert User.get_user_by_username("john").balance != 0
def test_auth_resource(init_app): """Tests AuthResource""" app = init_app with app.test_client() as client: # GET response_get_route_no_headers = client.get(url_for("api_auth")) assert response_get_route_no_headers.status_code == 400 login_payload_john = json.dumps({"login": "******", "password": "******"}) response_get_route = client.get( url_for("api_auth"), headers={"Content-Type": "application/json"}, data=login_payload_john, ) assert response_get_route.status_code == 200 for key_ in ["access_token", "refresh_token", "fresh", "expires_in"]: assert key_ in response_get_route.json.keys() assert response_get_route.json.get("fresh") login_payload_not_found = json.dumps({ "login": "******", "password": "******" }) response_get_route_404 = client.get( url_for("api_auth"), headers={"Content-Type": "application/json"}, data=login_payload_not_found, ) assert response_get_route_404.status_code == 401 # POST register_payload = json.dumps({ "address": "St.Test", "name": "Test Test", "email": "*****@*****.**", "password": "******", "phone": "+380967711222", "tariff": "50m", "username": "******", }) register_payload_non_unique = json.dumps({ "address": "St.Test", "name": "Test Test", "email": "*****@*****.**", "password": "******", "phone": "+380967711222", "tariff": "50m", "username": "******", }) login_payload_admin = json.dumps({ "login": "******", "password": "******" }) login_payload_john = json.dumps({"login": "******", "password": "******"}) response_login_john = client.get( url_for("api_auth"), headers={"Content-Type": "application/json"}, data=login_payload_john, ) assert response_login_john.status_code == 200 response_post_route_auth_not_admin = client.post( url_for("api_auth"), headers={ "Authorization": "Bearer {0}".format( response_login_john.json.get("access_token")), "Content-Type": "application/json", }, data=register_payload, ) assert response_post_route_auth_not_admin.status_code == 403 response_login_admin = client.get( url_for("api_auth"), headers={"Content-Type": "application/json"}, data=login_payload_admin, ) assert response_login_admin.status_code == 200 access_token_admin = response_login_admin.json.get("access_token") assert not User.get_user_by_username("test") response_post_route_auth = client.post( url_for("api_auth"), headers={ "Authorization": "Bearer {0}".format(access_token_admin), "Content-Type": "application/json", }, data=register_payload, ) assert response_post_route_auth.status_code == 201 assert User.get_user_by_username("test") response_post_route_auth_user_exists = client.post( url_for("api_auth"), headers={ "Authorization": "Bearer {0}".format(access_token_admin), "Content-Type": "application/json", }, data=register_payload, ) assert response_post_route_auth_user_exists.status_code == 400 response_post_route_auth_user_exists = client.post( url_for("api_auth"), headers={ "Authorization": "Bearer {0}".format(access_token_admin), "Content-Type": "application/json", }, data=register_payload_non_unique, ) assert response_post_route_auth_user_exists.status_code == 500
def test_saving_deleting_to_db(setup_database): """Save and delete user from the database""" db = setup_database usr = User(username="******", password="******") assert not db.session.query(User).filter_by(username="******").first() usr.save_to_db() assert User.get_user_by_username("susan") usr.save_to_db() assert len(db.session.query(User).filter_by(username="******").all()) == 1 usr.delete_from_db() assert not User.get_user_by_username("susan") prev_num_objects = len(db.session.query(User).all()) try: usr_not_exist = User(username="******", password="******") usr_not_exist.delete_from_db() assert False # If user was deleted - something goes wrong except ValueError: # Exception was raised - everything is OK assert len(db.session.query(User).all()) == prev_num_objects
def test_admin_tools_resource(init_app): """Tests AdminToolsResource""" app = init_app user = User.get_user_by_username("john") user_to_del = User.get_user_by_username("test_del") with app.test_client() as client: response_get_route_no_auth = client.post( url_for("api_admin_tools", uuid=user.uuid)) assert response_get_route_no_auth.status_code == 401 login_payload_john = json.dumps({"login": "******", "password": "******"}) login_payload_admin = json.dumps({ "login": "******", "password": "******" }) access_token_john = get_access_token(client, login_payload_john) response_get_route_not_admin_auth = client.post( url_for("api_admin_tools", uuid=user.uuid), headers={"Authorization": "Bearer {0}".format(access_token_john)}, ) assert response_get_route_not_admin_auth.status_code == 403 access_token_admin = get_access_token(client, login_payload_admin) response_get_route_admin_auth_no_content_type = client.post( url_for("api_admin_tools", uuid=user.uuid), headers={"Authorization": "Bearer {0}".format(access_token_admin)}, ) assert response_get_route_admin_auth_no_content_type.status_code == 400 response_get_route_admin_deactivate = client.post( url_for("api_admin_tools", uuid=user.uuid), headers={ "Authorization": "Bearer {0}".format(access_token_admin), "Content-Type": "application/json", }, data=json.dumps({"choice": "deactivate"}), ) assert response_get_route_admin_deactivate.status_code == 200 assert user.state == State.deactivated_state.value response_get_route_admin_activate = client.post( url_for("api_admin_tools", uuid=user.uuid), headers={ "Authorization": "Bearer {0}".format(access_token_admin), "Content-Type": "application/json", }, data=json.dumps({"choice": "activate"}), ) assert response_get_route_admin_activate.status_code == 200 assert user.state == State.activated_state.value response_get_route_admin_delete = client.post( url_for("api_admin_tools", uuid=user_to_del.uuid), headers={ "Authorization": "Bearer {0}".format(access_token_admin), "Content-Type": "application/json", }, data=json.dumps({"choice": "delete"}), ) assert response_get_route_admin_delete.status_code == 200 assert not User.get_user_by_username("test_del") response_get_route_admin_delete_no_user = client.post( url_for("api_admin_tools", uuid=user_to_del.uuid), headers={ "Authorization": "Bearer {0}".format(access_token_admin), "Content-Type": "application/json", }, data=json.dumps({"choice": "delete"}), ) assert response_get_route_admin_delete_no_user.status_code == 500