diff --git a/README.md b/README.md index 2556fd46..a2c37df2 100644 --- a/README.md +++ b/README.md @@ -480,7 +480,7 @@ For ex: } ``` -#### POST /alias/custom/new +#### POST /api/alias/custom/new Create a new custom alias. @@ -500,7 +500,22 @@ If success, 201 with the new alias, for example } ``` -409 if the alias is already created. +#### POST /api/alias/random/new + +Create a new random alias. + +Input: +- `Authentication` header that contains the api key +- (Optional but recommended) `hostname` passed in query string + +Output: +If success, 201 with the new alias, for example + +```json +{ + "alias": "www_groupon_com@my_domain.com" +} +``` ### Database migration diff --git a/app/api/__init__.py b/app/api/__init__.py index 7ac2561f..612893b0 100644 --- a/app/api/__init__.py +++ b/app/api/__init__.py @@ -1 +1 @@ -from .views import alias_options, new_custom_alias +from .views import alias_options, new_custom_alias, new_random_alias diff --git a/app/api/views/new_random_alias.py b/app/api/views/new_random_alias.py new file mode 100644 index 00000000..7afe1f6d --- /dev/null +++ b/app/api/views/new_random_alias.py @@ -0,0 +1,43 @@ +from flask import g +from flask import jsonify, request +from flask_cors import cross_origin + +from app.api.base import api_bp, verify_api_key +from app.config import EMAIL_DOMAIN, MAX_NB_EMAIL_FREE_PLAN +from app.extensions import db +from app.log import LOG +from app.models import GenEmail, AliasUsedOn +from app.utils import convert_to_id + + +@api_bp.route("/alias/random/new", methods=["POST"]) +@cross_origin() +@verify_api_key +def new_random_alias(): + """ + Create a new random alias + Output: + 201 if success + + """ + user = g.user + if not user.can_create_new_alias(): + LOG.d("user %s cannot create new random alias", user) + return ( + jsonify( + error=f"You have reached the limitation of a free account with the maximum of " + f"{MAX_NB_EMAIL_FREE_PLAN} aliases, please upgrade your plan to create more aliases" + ), + 400, + ) + + scheme = user.alias_generator + gen_email = GenEmail.create_new_random(user_id=user.id, scheme=scheme) + db.session.commit() + + hostname = request.args.get("hostname") + if hostname: + AliasUsedOn.create(gen_email_id=gen_email.id, hostname=hostname) + db.session.commit() + + return jsonify(alias=gen_email.email), 201 diff --git a/tests/api/test_new_random_alias.py b/tests/api/test_new_random_alias.py new file mode 100644 index 00000000..a50f3c1f --- /dev/null +++ b/tests/api/test_new_random_alias.py @@ -0,0 +1,52 @@ +from flask import url_for + +from app.config import EMAIL_DOMAIN, MAX_NB_EMAIL_FREE_PLAN +from app.extensions import db +from app.models import User, ApiKey, GenEmail + + +def test_success(flask_client): + user = User.create( + email="a@b.c", password="password", name="Test User", activated=True + ) + db.session.commit() + + # create api_key + api_key = ApiKey.create(user.id, "for test") + db.session.commit() + + r = flask_client.post( + url_for("api.new_random_alias", hostname="www.test.com"), + headers={"Authentication": api_key.code}, + ) + + assert r.status_code == 201 + assert r.json["alias"].endswith(EMAIL_DOMAIN) + + +def test_out_of_quota(flask_client): + user = User.create( + email="a@b.c", password="password", name="Test User", activated=True + ) + db.session.commit() + + # create api_key + api_key = ApiKey.create(user.id, "for test") + db.session.commit() + + # create 3 random alias to run out of quota + for _ in range(MAX_NB_EMAIL_FREE_PLAN): + GenEmail.create_new(user.id, prefix="test1") + GenEmail.create_new(user.id, prefix="test2") + GenEmail.create_new(user.id, prefix="test3") + + r = flask_client.post( + url_for("api.new_random_alias", hostname="www.test.com"), + headers={"Authentication": api_key.code}, + ) + + assert r.status_code == 400 + assert ( + r.json["error"] + == "You have reached the limitation of a free account with the maximum of 3 aliases, please upgrade your plan to create more aliases" + )