add /api/auth/facebook

This commit is contained in:
Son NK 2020-02-27 22:57:24 +07:00
parent c84b9892e0
commit 02d26df292
2 changed files with 74 additions and 2 deletions

View file

@ -738,6 +738,21 @@ Output:
The `api_key` is used in all subsequent requests. It's empty if MFA is enabled. The `api_key` is used in all subsequent requests. It's empty if MFA is enabled.
If user hasn't enabled MFA, `mfa_key` is empty. If user hasn't enabled MFA, `mfa_key` is empty.
#### POST /api/auth/facebook
Input:
- facebook_token: Facebook access token
- device: device name. Used to create the API Key. Should be humanly readable so user can manage later on the "API Key" page.
Output: Same output as for `/api/auth/login` endpoint
- name: user name, could be an empty string
- mfa_enabled: boolean
- mfa_key: only useful when user enables MFA. In this case, user needs to enter their OTP token in order to login.
- api_key: if MFA is not enabled, the `api key` is returned right away.
The `api_key` is used in all subsequent requests. It's empty if MFA is enabled.
If user hasn't enabled MFA, `mfa_key` is empty.
#### GET /api/aliases #### GET /api/aliases
Get user aliases. Get user aliases.

View file

@ -3,12 +3,20 @@ from flask import jsonify, request
from flask_cors import cross_origin from flask_cors import cross_origin
from itsdangerous import Signer from itsdangerous import Signer
from app import email_utils
from app.api.base import api_bp, verify_api_key from app.api.base import api_bp, verify_api_key
from app.config import EMAIL_DOMAIN, MAX_NB_EMAIL_FREE_PLAN, FLASK_SECRET from app.config import (
EMAIL_DOMAIN,
MAX_NB_EMAIL_FREE_PLAN,
FLASK_SECRET,
DISABLE_REGISTRATION,
)
from app.email_utils import can_be_used_as_personal_email, email_already_used
from app.extensions import db from app.extensions import db
from app.log import LOG from app.log import LOG
from app.models import GenEmail, AliasUsedOn, User, ApiKey from app.models import GenEmail, AliasUsedOn, User, ApiKey, SocialAuth
from app.utils import convert_to_id from app.utils import convert_to_id
import facebook
@api_bp.route("/auth/login", methods=["POST"]) @api_bp.route("/auth/login", methods=["POST"])
@ -48,6 +56,55 @@ def auth_login():
return jsonify(**auth_payload(user, device)), 200 return jsonify(**auth_payload(user, device)), 200
@api_bp.route("/auth/facebook", methods=["POST"])
@cross_origin()
def auth_facebook():
"""
Authenticate user with Facebook
Input:
facebook_token: facebook access token
device: to create an ApiKey associated with this device
Output:
200 and user info containing:
{
name: "John Wick",
mfa_enabled: true,
mfa_key: "a long string",
api_key: "a long string"
}
"""
data = request.get_json()
if not data:
return jsonify(error="request body cannot be empty"), 400
facebook_token = data.get("facebook_token")
device = data.get("device")
graph = facebook.GraphAPI(access_token=facebook_token)
user_info = graph.get_object("me", fields="email,name")
email = user_info.get("email")
user = User.get_by(email=email)
if not user:
if DISABLE_REGISTRATION:
return jsonify(error="registration is closed"), 400
if not can_be_used_as_personal_email(email) or email_already_used(email):
return jsonify(error=f"cannot use {email} as personal inbox"), 400
LOG.d("create facebook user with %s", user_info)
user = User.create(email=email.lower(), name=user_info["name"], activated=True)
db.session.commit()
email_utils.send_welcome_email(user)
if not SocialAuth.get_by(user_id=user.id, social="facebook"):
SocialAuth.create(user_id=user.id, social="facebook")
db.session.commit()
return jsonify(**auth_payload(user, device)), 200
def auth_payload(user, device) -> dict: def auth_payload(user, device) -> dict:
ret = { ret = {
"name": user.name, "name": user.name,