def test_auth_activate_wrong_code(flask_client): r = flask_client.post( url_for("api.auth_register"), json={ "email": "*****@*****.**", "password": "******" }, ) assert r.status_code == 200 assert r.json["msg"] # get the activation code act_code = AccountActivation.get(1) assert act_code assert len(act_code.code) == 6 assert act_code.tries == 3 # make sure to create a wrong code wrong_code = act_code.code + "123" r = flask_client.post( url_for("api.auth_activate"), json={ "email": "*****@*****.**", "code": wrong_code }, ) assert r.status_code == 400 # make sure the nb tries decrements act_code = AccountActivation.get(1) assert act_code.tries == 2
def auth_activate(): """ User enters the activation code to confirm their account. Input: email code Output: 200: user account is now activated, user can login now 400: wrong email, code 410: wrong code too many times """ data = request.get_json() if not data: return jsonify(error="request body cannot be empty"), 400 email = sanitize_email(data.get("email")) code = data.get("code") user = User.get_by(email=email) # do not use a different message to avoid exposing existing email if not user or user.activated: # Trigger rate limiter g.deduct_limit = True return jsonify(error="Wrong email or code"), 400 account_activation = AccountActivation.get_by(user_id=user.id) if not account_activation: # Trigger rate limiter g.deduct_limit = True return jsonify(error="Wrong email or code"), 400 if account_activation.code != code: # decrement nb tries account_activation.tries -= 1 db.session.commit() # Trigger rate limiter g.deduct_limit = True if account_activation.tries == 0: AccountActivation.delete(account_activation.id) db.session.commit() return jsonify(error="Too many wrong tries"), 410 return jsonify(error="Wrong email or code"), 400 LOG.debug("activate user %s", user) user.activated = True AccountActivation.delete(account_activation.id) db.session.commit() return jsonify(msg="Account is activated, user can login now"), 200
def test_auth_activate_success(flask_client): r = flask_client.post( url_for("api.auth_register"), json={ "email": "*****@*****.**", "password": "******" }, ) assert r.status_code == 200 assert r.json["msg"] # get the activation code act_code = AccountActivation.get(1) assert act_code assert len(act_code.code) == 6 r = flask_client.post( url_for("api.auth_activate"), json={ "email": "*****@*****.**", "code": act_code.code }, ) assert r.status_code == 200
def test_auth_register_success(flask_client): assert AccountActivation.get(1) is None r = flask_client.post(url_for("api.auth_register"), json={ "email": "[email protected]", "password": "******" }) assert r.status_code == 200 assert r.json["msg"] # make sure an activation code is created act_code = AccountActivation.get(1) assert act_code assert len(act_code.code) == 6 assert act_code.tries == 3
def auth_register(): """ User signs up - will need to activate their account with an activation code. Input: email password Output: 200: user needs to confirm their account """ data = request.get_json() if not data: return jsonify(error="request body cannot be empty"), 400 email = sanitize_email(data.get("email")) password = data.get("password") if DISABLE_REGISTRATION: return jsonify(error="registration is closed"), 400 if not email_can_be_used_as_mailbox(email) or personal_email_already_used( email): return jsonify(error=f"cannot use {email} as personal inbox"), 400 if not password or len(password) < 8: return jsonify(error="password too short"), 400 if len(password) > 100: return jsonify(error="password too long"), 400 LOG.d("create user %s", email) user = User.create(email=email, name="", password=password) Session.flush() # create activation code code = "".join([str(random.randint(0, 9)) for _ in range(6)]) AccountActivation.create(user_id=user.id, code=code) Session.commit() send_email( email, "Just one more step to join SimpleLogin", render("transactional/code-activation.txt.jinja2", code=code), render("transactional/code-activation.html", code=code), ) return jsonify(msg="User needs to confirm their account"), 200
def test_auth_reactivate_success(flask_client): User.create(email="*****@*****.**", password="******", name="Test User") db.session.commit() r = flask_client.post(url_for("api.auth_reactivate"), json={"email": "*****@*****.**"}) assert r.status_code == 200 # make sure an activation code is created act_code = AccountActivation.get(1) assert act_code assert len(act_code.code) == 6 assert act_code.tries == 3
def auth_reactivate(): """ User asks for another activation code Input: email Output: 200: user is going to receive an email for activate their account """ data = request.get_json() if not data: return jsonify(error="request body cannot be empty"), 400 email = sanitize_email(data.get("email")) user = User.get_by(email=email) # do not use a different message to avoid exposing existing email if not user or user.activated: return jsonify(error="Something went wrong"), 400 account_activation = AccountActivation.get_by(user_id=user.id) if account_activation: AccountActivation.delete(account_activation.id) db.session.commit() # create activation code code = "".join([str(random.randint(0, 9)) for _ in range(6)]) AccountActivation.create(user_id=user.id, code=code) db.session.commit() send_email( email, "Just one more step to join SimpleLogin", render("transactional/code-activation.txt", code=code), render("transactional/code-activation.html", code=code), ) return jsonify(msg="User needs to confirm their account"), 200
def test_auth_activate_too_many_wrong_code(flask_client): r = flask_client.post(url_for("api.auth_register"), json={ "email": "[email protected]", "password": "******" }) assert r.status_code == 200 assert r.json["msg"] # get the activation code act_code = AccountActivation.get(1) assert act_code assert len(act_code.code) == 6 assert act_code.tries == 3 # make sure to create a wrong code wrong_code = act_code.code + "123" for _ in range(2): r = flask_client.post(url_for("api.auth_activate"), json={ "email": "[email protected]", "code": wrong_code }) assert r.status_code == 400 # the activation code is deleted r = flask_client.post(url_for("api.auth_activate"), json={ "email": "[email protected]", "code": wrong_code }) assert r.status_code == 410 # make sure the nb tries decrements assert AccountActivation.get(1) is None