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.
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 user aliases.

View File

@ -3,12 +3,20 @@ from flask import jsonify, request
from flask_cors import cross_origin
from itsdangerous import Signer
from app import email_utils
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.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
import facebook
@api_bp.route("/auth/login", methods=["POST"])
@ -48,6 +56,55 @@ def auth_login():
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:
ret = {
"name": user.name,