Add /v3/alias/options

This commit is contained in:
Son NK 2020-03-29 20:25:28 +02:00
parent 64eed21cf0
commit 4c1c02db60
3 changed files with 123 additions and 9 deletions

View File

@ -659,7 +659,7 @@ Output: if api key is correct, return a json with user name and whether user is
If api key is incorrect, return 401. If api key is incorrect, return 401.
#### GET /api/v2/alias/options #### GET /api/v3/alias/options
User alias info and suggestion. Used by the first extension screen when user opens the extension. User alias info and suggestion. Used by the first extension screen when user opens the extension.
@ -671,19 +671,12 @@ Output: a json with the following field:
- can_create: boolean. Whether user can create new alias - can_create: boolean. Whether user can create new alias
- suffixes: list of string. List of alias `suffix` that user can use. If user doesn't have custom domain, this list has a single element which is the alias default domain (simplelogin.co). - suffixes: list of string. List of alias `suffix` that user can use. If user doesn't have custom domain, this list has a single element which is the alias default domain (simplelogin.co).
- prefix_suggestion: string. Suggestion for the `alias prefix`. Usually this is the website name extracted from `hostname`. If no `hostname`, then the `prefix_suggestion` is empty. - prefix_suggestion: string. Suggestion for the `alias prefix`. Usually this is the website name extracted from `hostname`. If no `hostname`, then the `prefix_suggestion` is empty.
- existing: list of string. List of existing alias.
- recommendation: optional field, dictionary. If an alias is already used for this website, the recommendation will be returned. There are 2 subfields in `recommendation`: `alias` which is the recommended alias and `hostname` is the website on which this alias is used before. - recommendation: optional field, dictionary. If an alias is already used for this website, the recommendation will be returned. There are 2 subfields in `recommendation`: `alias` which is the recommended alias and `hostname` is the website on which this alias is used before.
For ex: For ex:
```json ```json
{ {
"can_create": true, "can_create": true,
"existing": [
"my-first-alias.meo@sl.local",
"e1.cat@sl.local",
"e2.chat@sl.local",
"e3.cat@sl.local"
],
"prefix_suggestion": "test", "prefix_suggestion": "test",
"recommendation": { "recommendation": {
"alias": "e1.cat@sl.local", "alias": "e1.cat@sl.local",
@ -844,7 +837,7 @@ Get user aliases.
Input: Input:
- `Authentication` header that contains the api key - `Authentication` header that contains the api key
- `page_id` used for the pagination. The endpoint returns maximum 20 aliases for each page. `page_id` starts at 0. - `page_id` in query. Used for the pagination. The endpoint returns maximum 20 aliases for each page. `page_id` starts at 0.
- (Optional) query: included in request body. Some frameworks might prevent GET request having a non-empty body, in this case this endpoint also supports POST. - (Optional) query: included in request body. Some frameworks might prevent GET request having a non-empty body, in this case this endpoint also supports POST.
Output: Output:

View File

@ -163,3 +163,79 @@ def options_v2():
ret["suffixes"] = list(reversed(ret["suffixes"])) ret["suffixes"] = list(reversed(ret["suffixes"]))
return jsonify(ret) return jsonify(ret)
@api_bp.route("/v3/alias/options")
@cross_origin()
@verify_api_key
def options_v3():
"""
Return what options user has when creating new alias.
Same as v2 but do NOT return existing 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
recommendation: Optional dict
alias: str
hostname: str
"""
user = g.user
hostname = request.args.get("hostname")
ret = {
"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, Alias, User)
.filter(
AliasUsedOn.alias_id == Alias.id,
Alias.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
for domain in ALIAS_DOMAINS:
if DISABLE_ALIAS_SUFFIX:
ret["suffixes"].append(f"@{domain}")
else:
ret["suffixes"].append(f".{random_word()}@{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)

View File

@ -98,3 +98,48 @@ def test_different_scenarios_v2(flask_client):
) )
assert r.json["recommendation"]["alias"] == alias.email assert r.json["recommendation"]["alias"] == alias.email
assert r.json["recommendation"]["hostname"] == "www.test.com" assert r.json["recommendation"]["hostname"] == "www.test.com"
def test_different_scenarios_v3(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_v3"), headers={"Authentication": api_key.code}
)
assert r.status_code == 200
assert r.json["can_create"]
assert r.json["suffixes"]
assert r.json["prefix_suggestion"] == "" # no hostname => no suggestion
# <<< with hostname >>>
r = flask_client.get(
url_for("api.options_v3", hostname="www.test.com"),
headers={"Authentication": api_key.code},
)
assert r.json["prefix_suggestion"] == "test"
# <<< with recommendation >>>
alias = Alias.create_new(user, prefix="test")
db.session.commit()
AliasUsedOn.create(
alias_id=alias.id, hostname="www.test.com", user_id=alias.user_id
)
db.session.commit()
r = flask_client.get(
url_for("api.options_v3", hostname="www.test.com"),
headers={"Authentication": api_key.code},
)
assert r.json["recommendation"]["alias"] == alias.email
assert r.json["recommendation"]["hostname"] == "www.test.com"