def start_fbauth(request): """ Starting point for facebook authentication """ social_auth = SocialAuth(request=request) redirect_url = social_auth.facebook_step1() return HttpResponseRedirect(redirect_url)
def fbauth(request): """ Redirect function after facebook authentication """ social_auth = SocialAuth(request=request) social_auth.facebook_step2() return HttpResponseRedirect(reverse('home'))
def start_twauth(request): """ The view function that initiates the entire handshake. """ social_auth = SocialAuth(request=request) redirect_url = social_auth.twitter_step1() return HttpResponseRedirect(redirect_url)
def googleauth(request): """ Redirect after google auth """ social_auth = SocialAuth(request=request) social_auth.google_step2() return HttpResponseRedirect(reverse('home'))
def twauth(request): """ Redirect function after twitter login """ social_auth = SocialAuth(request=request) social_auth.twitter_step2() return HttpResponseRedirect(reverse('home'))
def start_googleauth(request): """ Starting point for google authentication uses oauth2.0 """ social_auth = SocialAuth(request=request) redirect_url = social_auth.google_step1() return HttpResponseRedirect(redirect_url)
def auth_google(): """ Authenticate user with Facebook Input: google_token: Google 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 google_token = data.get("google_token") device = data.get("device") cred = google.oauth2.credentials.Credentials(token=google_token) build = googleapiclient.discovery.build("oauth2", "v2", credentials=cred) user_info = build.userinfo().get().execute() email = user_info.get("email").strip().lower() user = User.get_by(email=email) if not user: if DISABLE_REGISTRATION: return jsonify(error="registration is closed"), 400 if not email_domain_can_be_used_as_mailbox( email ) or personal_email_already_used(email): return jsonify(error=f"cannot use {email} as personal inbox"), 400 LOG.d("create Google user with %s", user_info) user = User.create(email=email.lower(), name="", activated=True) db.session.commit() email_utils.send_welcome_email(user) if not SocialAuth.get_by(user_id=user.id, social="google"): SocialAuth.create(user_id=user.id, social="google") db.session.commit() return jsonify(**auth_payload(user, device)), 200
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").strip().lower() user = User.get_by(email=email) if not user: if DISABLE_REGISTRATION: return jsonify(error="registration is closed"), 400 if not email_domain_can_be_used_as_mailbox( email) or personal_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 github_callback(): # user clicks on cancel if "error" in request.args: flash("Please use another sign in method then", "warning") return redirect("/") github = OAuth2Session( GITHUB_CLIENT_ID, state=session["oauth_state"], scope=["user:email"], redirect_uri=_redirect_uri, ) token = github.fetch_token( _token_url, client_secret=GITHUB_CLIENT_SECRET, authorization_response=request.url, ) # a dict with "name", "login" github_user_data = github.get("https://api.github.com/user").json() # return list of emails # { # 'email': '*****@*****.**', # 'primary': False, # 'verified': True, # 'visibility': None # } emails = github.get("https://api.github.com/user/emails").json() # only take the primary email email = None for e in emails: if e.get("verified") and e.get("primary"): email = e.get("email") break if not email: LOG.error( f"cannot get email for github user {github_user_data} {emails}") flash( "Cannot get a valid email from Github, please another way to login/sign up", "error", ) return redirect(url_for("auth.login")) email = email.lower() user = User.get_by(email=email) # create user if not user: if DISABLE_REGISTRATION: flash("Registration is closed", "error") return redirect(url_for("auth.login")) if not can_be_used_as_personal_email(email) or email_already_used( email): flash(f"You cannot use {email} as your personal inbox.", "error") return redirect(url_for("auth.login")) LOG.d("create github user") user = User.create(email=email.lower(), name=github_user_data.get("name") or "", activated=True) db.session.commit() login_user(user) email_utils.send_welcome_email(user) flash(f"Welcome to SimpleLogin {user.name}!", "success") if not SocialAuth.get_by(user_id=user.id, social="github"): SocialAuth.create(user_id=user.id, social="github") db.session.commit() # The activation link contains the original page, for ex authorize page next_url = request.args.get("next") if request.args else None return after_login(user, next_url)
def facebook_callback(): # user clicks on cancel if "error" in request.args: flash("Please use another sign in method then", "warning") return redirect("/") facebook = OAuth2Session( FACEBOOK_CLIENT_ID, state=session["oauth_state"], scope=_scope, redirect_uri=_redirect_uri, ) facebook = facebook_compliance_fix(facebook) facebook.fetch_token( _token_url, client_secret=FACEBOOK_CLIENT_SECRET, authorization_response=request.url, ) # Fetch a protected resource, i.e. user profile # { # "email": "*****@*****.**", # "id": "1234", # "name": "First Last", # "picture": { # "data": { # "url": "long_url" # } # } # } facebook_user_data = facebook.get( "https://graph.facebook.com/me?fields=id,name,email,picture{url}" ).json() email = facebook_user_data.get("email") # user choose to not share email, cannot continue if not email: flash("In order to use SimpleLogin, you need to give us a valid email", "warning") return redirect(url_for("auth.register")) email = email.strip().lower() user = User.get_by(email=email) picture_url = facebook_user_data.get("picture", {}).get("data", {}).get("url") if user: if picture_url and not user.profile_picture_id: LOG.d("set user profile picture to %s", picture_url) file = create_file_from_url(user, picture_url) user.profile_picture_id = file.id db.session.commit() else: flash( "Sorry you cannot sign up via Facebook, please use email/password sign-up instead", "error", ) return redirect(url_for("auth.register")) next_url = None # The activation link contains the original page, for ex authorize page if "facebook_next_url" in session: next_url = session["facebook_next_url"] LOG.debug("redirect user to %s", next_url) # reset the next_url to avoid user getting redirected at each login :) session.pop("facebook_next_url", None) if not SocialAuth.get_by(user_id=user.id, social="facebook"): SocialAuth.create(user_id=user.id, social="facebook") db.session.commit() return after_login(user, next_url)
def google_callback(): # user clicks on cancel if "error" in request.args: flash("please use another sign in method then", "warning") return redirect("/") google = OAuth2Session( GOOGLE_CLIENT_ID, state=session["oauth_state"], scope=_scope, redirect_uri=_redirect_uri, ) token = google.fetch_token( _token_url, client_secret=GOOGLE_CLIENT_SECRET, authorization_response=request.url, ) # Fetch a protected resource, i.e. user profile # { # "email": "*****@*****.**", # "family_name": "First name", # "given_name": "Last name", # "id": "1234", # "locale": "en", # "name": "First Last", # "picture": "http://profile.jpg", # "verified_email": true # } google_user_data = google.get( "https://www.googleapis.com/oauth2/v1/userinfo").json() email = google_user_data["email"] user = User.get_by(email=email) picture_url = google_user_data.get("picture") if user: if picture_url and not user.profile_picture_id: LOG.d("set user profile picture to %s", picture_url) file = create_file_from_url(picture_url) user.profile_picture_id = file.id db.session.commit() # create user else: if DISABLE_REGISTRATION: flash("Registration is closed", "error") return redirect(url_for("auth.login")) if not can_be_used_as_personal_email(email) or email_already_used( email): flash(f"You cannot use {email} as your personal inbox.", "error") return redirect(url_for("auth.login")) LOG.d("create google user with %s", google_user_data) user = User.create(email=email.lower(), name=google_user_data["name"], activated=True) if picture_url: LOG.d("set user profile picture to %s", picture_url) file = create_file_from_url(picture_url) user.profile_picture_id = file.id db.session.commit() login_user(user) email_utils.send_welcome_email(user) flash(f"Welcome to SimpleLogin {user.name}!", "success") next_url = None # The activation link contains the original page, for ex authorize page if "google_next_url" in session: next_url = session["google_next_url"] LOG.debug("redirect user to %s", next_url) # reset the next_url to avoid user getting redirected at each login :) session.pop("google_next_url", None) if not SocialAuth.get_by(user_id=user.id, social="google"): SocialAuth.create(user_id=user.id, social="google") db.session.commit() return after_login(user, next_url)
def google_callback(): # user clicks on cancel if "error" in request.args: flash("please use another sign in method then", "warning") return redirect("/") google = OAuth2Session( GOOGLE_CLIENT_ID, # some how Google Login fails with oauth_state KeyError # state=session["oauth_state"], scope=_scope, redirect_uri=_redirect_uri, ) google.fetch_token( _token_url, client_secret=GOOGLE_CLIENT_SECRET, authorization_response=request.url, ) # Fetch a protected resource, i.e. user profile # { # "email": "*****@*****.**", # "family_name": "First name", # "given_name": "Last name", # "id": "1234", # "locale": "en", # "name": "First Last", # "picture": "http://profile.jpg", # "verified_email": true # } google_user_data = google.get( "https://www.googleapis.com/oauth2/v1/userinfo").json() email = sanitize_email(google_user_data["email"]) user = User.get_by(email=email) picture_url = google_user_data.get("picture") if user: if picture_url and not user.profile_picture_id: LOG.d("set user profile picture to %s", picture_url) file = create_file_from_url(user, picture_url) user.profile_picture_id = file.id db.session.commit() else: flash( "Sorry you cannot sign up via Google, please use email/password sign-up instead", "error", ) return redirect(url_for("auth.register")) next_url = None # The activation link contains the original page, for ex authorize page if "google_next_url" in session: next_url = session["google_next_url"] LOG.debug("redirect user to %s", next_url) # reset the next_url to avoid user getting redirected at each login :) session.pop("google_next_url", None) if not SocialAuth.get_by(user_id=user.id, social="google"): SocialAuth.create(user_id=user.id, social="google") db.session.commit() return after_login(user, next_url)
def github_callback(): # user clicks on cancel if "error" in request.args: flash("Please use another sign in method then", "warning") return redirect("/") github = OAuth2Session( GITHUB_CLIENT_ID, state=session["oauth_state"], scope=["user:email"], redirect_uri=_redirect_uri, ) github.fetch_token( _token_url, client_secret=GITHUB_CLIENT_SECRET, authorization_response=request.url, ) # a dict with "name", "login" github_user_data = github.get("https://api.github.com/user").json() # return list of emails # { # 'email': '*****@*****.**', # 'primary': False, # 'verified': True, # 'visibility': None # } emails = github.get("https://api.github.com/user/emails").json() # only take the primary email email = None for e in emails: if e.get("verified") and e.get("primary"): email = e.get("email") break if not email: LOG.e(f"cannot get email for github user {github_user_data} {emails}") flash( "Cannot get a valid email from Github, please another way to login/sign up", "error", ) return redirect(url_for("auth.login")) email = sanitize_email(email) user = User.get_by(email=email) if not user: flash( "Sorry you cannot sign up via Github, please use email/password sign-up instead", "error", ) return redirect(url_for("auth.register")) if not SocialAuth.get_by(user_id=user.id, social="github"): SocialAuth.create(user_id=user.id, social="github") Session.commit() # The activation link contains the original page, for ex authorize page next_url = request.args.get("next") if request.args else None return after_login(user, next_url)
def facebook_callback(): # user clicks on cancel if "error" in request.args: flash("Please use another sign in method then", "warning") return redirect("/") facebook = OAuth2Session( FACEBOOK_CLIENT_ID, state=session["oauth_state"], scope=_scope, redirect_uri=_redirect_uri, ) facebook = facebook_compliance_fix(facebook) token = facebook.fetch_token( _token_url, client_secret=FACEBOOK_CLIENT_SECRET, authorization_response=request.url, ) # Fetch a protected resource, i.e. user profile # { # "email": "*****@*****.**", # "id": "1234", # "name": "First Last", # "picture": { # "data": { # "url": "long_url" # } # } # } facebook_user_data = facebook.get( "https://graph.facebook.com/me?fields=id,name,email,picture{url}" ).json() email = facebook_user_data.get("email") # user choose to not share email, cannot continue if not email: flash("In order to use SimpleLogin, you need to give us a valid email", "warning") return redirect(url_for("auth.register")) user = User.get_by(email=email) picture_url = facebook_user_data.get("picture", {}).get("data", {}).get("url") if user: if picture_url and not user.profile_picture_id: LOG.d("set user profile picture to %s", picture_url) file = create_file_from_url(picture_url) user.profile_picture_id = file.id db.session.commit() # create user else: if DISABLE_REGISTRATION: flash("Registration is closed", "error") return redirect(url_for("auth.login")) if not can_be_used_as_personal_email(email) or email_already_used( email): flash(f"You cannot use {email} as your personal inbox.", "error") return redirect(url_for("auth.login")) LOG.d("create facebook user with %s", facebook_user_data) user = User.create(email=email.lower(), name=facebook_user_data["name"], activated=True) if picture_url: LOG.d("set user profile picture to %s", picture_url) file = create_file_from_url(picture_url) user.profile_picture_id = file.id db.session.commit() login_user(user) email_utils.send_welcome_email(user) flash(f"Welcome to SimpleLogin {user.name}!", "success") next_url = None # The activation link contains the original page, for ex authorize page if "facebook_next_url" in session: next_url = session["facebook_next_url"] LOG.debug("redirect user to %s", next_url) # reset the next_url to avoid user getting redirected at each login :) session.pop("facebook_next_url", None) if not SocialAuth.get_by(user_id=user.id, social="facebook"): SocialAuth.create(user_id=user.id, social="facebook") db.session.commit() return after_login(user, next_url)