Browse Source

add /api/v2/alias/options that flattens the response

Son NK 5 years ago
parent
commit
96da841062
2 changed files with 120 additions and 0 deletions
  1. 75 0
      app/api/views/alias_options.py
  2. 45 0
      tests/api/test_alias_options.py

+ 75 - 0
app/api/views/alias_options.py

@@ -78,3 +78,78 @@ def options():
     ret["custom"]["suffixes"] = list(reversed(ret["custom"]["suffixes"]))
 
     return jsonify(ret)
+
+
+@api_bp.route("/v2/alias/options")
+@cross_origin()
+@verify_api_key
+def options_v2():
+    """
+    Return what options user has when creating new alias.
+    Input:
+        a valid api-key in "Authentication" header and
+        optional "hostname" in args
+    Output: cf README
+        can_create: bool
+        suffixes: [str]
+        prefix_suggestion: str
+        existing: [str]
+        recommendation: Optional dict
+            alias: str
+            hostname: str
+
+
+    """
+    user = g.user
+    hostname = request.args.get("hostname")
+
+    ret = {
+        "existing": [
+            ge.email for ge in GenEmail.query.filter_by(user_id=user.id, enabled=True)
+        ],
+        "can_create": user.can_create_new_alias(),
+        "suffixes": [],
+        "prefix_suggestion": "",
+    }
+
+    # recommendation alias if exist
+    if hostname:
+        # put the latest used alias first
+        q = (
+            db.session.query(AliasUsedOn, GenEmail, User)
+            .filter(
+                AliasUsedOn.gen_email_id == GenEmail.id,
+                GenEmail.user_id == user.id,
+                AliasUsedOn.hostname == hostname,
+            )
+            .order_by(desc(AliasUsedOn.created_at))
+        )
+
+        r = q.first()
+        if r:
+            _, alias, _ = r
+            LOG.d("found alias %s %s %s", alias, hostname, user)
+            ret["recommendation"] = {"alias": alias.email, "hostname": hostname}
+
+    # custom alias suggestion and suffix
+    if hostname:
+        # keep only the domain name of hostname, ignore TLD and subdomain
+        # for ex www.groupon.com -> groupon
+        domain_name = hostname
+        if "." in hostname:
+            parts = hostname.split(".")
+            domain_name = parts[-2]
+            domain_name = convert_to_id(domain_name)
+        ret["prefix_suggestion"] = domain_name
+
+    # maybe better to make sure the suffix is never used before
+    # but this is ok as there's a check when creating a new custom alias
+    ret["suffixes"] = [f".{random_word()}@{EMAIL_DOMAIN}"]
+
+    for custom_domain in user.verified_custom_domains():
+        ret["suffixes"].append("@" + custom_domain.domain)
+
+    # custom domain should be put first
+    ret["suffixes"] = list(reversed(ret["suffixes"]))
+
+    return jsonify(ret)

+ 45 - 0
tests/api/test_alias_options.py

@@ -50,3 +50,48 @@ def test_different_scenarios(flask_client):
     )
     assert r.json["recommendation"]["alias"] == alias.email
     assert r.json["recommendation"]["hostname"] == "www.test.com"
+
+
+def test_different_scenarios_v2(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()
+
+    # <<< without hostname >>>
+    r = flask_client.get(
+        url_for("api.options_v2"), headers={"Authentication": api_key.code}
+    )
+
+    assert r.status_code == 200
+    # {'can_create': True, 'existing': ['my-first-alias.chat@sl.local'], 'prefix_suggestion': '', 'suffixes': ['.meo@sl.local']}
+
+    assert r.json["can_create"]
+    assert len(r.json["existing"]) == 1
+    assert r.json["suffixes"]
+    assert r.json["prefix_suggestion"] == ""  # no hostname => no suggestion
+
+    # <<< with hostname >>>
+    r = flask_client.get(
+        url_for("api.options_v2", hostname="www.test.com"),
+        headers={"Authentication": api_key.code},
+    )
+
+    assert r.json["prefix_suggestion"] == "test"
+
+    # <<< with recommendation >>>
+    alias = GenEmail.create_new(user.id, prefix="test")
+    db.session.commit()
+    AliasUsedOn.create(gen_email_id=alias.id, hostname="www.test.com")
+    db.session.commit()
+
+    r = flask_client.get(
+        url_for("api.options_v2", hostname="www.test.com"),
+        headers={"Authentication": api_key.code},
+    )
+    assert r.json["recommendation"]["alias"] == alias.email
+    assert r.json["recommendation"]["hostname"] == "www.test.com"