Facebook and linkedin not filling email field properly - python-social-auth

Google and github logins are working properly but for some reason I cant get the facebook and linkedin accounts to properly fill the email fields.
Here are the involved files
__init__.py
db = SQLAlchemy(app)
login_manager=LoginManager()
login_manager.init_app(app)
# Import blueprints from app (example: from app.posts import posts)
from app.users import users
# Register all blueprints to the main app (example: app.register_blueprint(posts))
app.register_blueprint(users)
app.register_blueprint(social_auth)
#3rd part db interaction
init_social(app, db)
# Import main views from app
from app import views
#Set login bootback
login_manager.login_view ='/login'
app.context_processor(backends)
Settings.py configuration, keys have been removed from post
#Flask
SECRET_KEY = ''
SESSION_COOKIE_NAME = ''
### Python Social Auth ###
DEBUG_TB_INTERCEPT_REDIRECTS = False
SESSION_PROTECTION = 'strong'
#Redirects and Paths
SOCIAL_AUTH_LOGIN_URL = '/login'
SOCIAL_AUTH_LOGIN_REDIRECT_URL = '/'
SOCIAL_AUTH_BACKEND_ERROR_URL = '/login'
SOCIAL_AUTH_USER_MODEL = 'app.users.models.User'
SOCIAL_AUTH_USERNAME_IS_FULL_EMAIL = True
#Facebook
SOCIAL_AUTH_FACEBOOK_KEY=''
SOCIAL_AUTH_FACEBOOK_SECRET=''
#Google
SOCIAL_AUTH_GOOGLE_KEY=''
SOCIAL_AUTH_GOOGLE_SECRET=''
#LinkedIn
SOCIAL_AUTH_LINKEDIN_KEY=''
SOCIAL_AUTH_LINKEDIN_SECRET=''
#Github
SOCIAL_AUTH_GITHUB_KEY=''
SOCIAL_AUTH_GITHUB_SECRET=''
SOCIAL_AUTH_AUTHENTICATION_BACKENDS = (
'social.backends.google.GoogleOpenId',
'social.backends.google.GoogleOAuth2',
'social.backends.google.GoogleOAuth',
'social.backends.facebook.FacebookOAuth2',
'social.backends.linkedin.LinkedinOAuth',
'social.backends.github.GithubOAuth2',
)
Here is the model itself, follows pretty closely the example provided by omab
models.py
from __future__ import absolute_import, print_function
from time import time
import functools
import uuid
import pbkdf2
from marshmallow import Serializer, fields
from app import db
ROLE_USER=0
ROLE_ADMIN=1
ROLE_GOD=2
default_img = '/assets/images/avatars/default.jpg'
class User(db.Model):
#meat n' potatoes
id = db.Column(db.Integer, primary_key=True)
img=db.Column(db.String(255), default=default_img)
username = db.Column(db.String(255))
email = db.Column(db.String(200), unique=True)
first_name = db.Column(db.String(30))
last_name = db.Column(db.String(40))
created_at = db.Column(db.BigInteger, default=time())
#controls
role = db.Column(db.SmallInteger, default=ROLE_USER)
is_active = db.Column(db.Boolean, default=True)
is_authenticated= db.Column(db.Boolean, default=True)
#password
salt = db.Column(db.String(50))
pass_hash = db.Column(db.String(255))
def __unicode__(self):
return self.email
def __repr__(self):
return '<User %r>' % self.email
def is_authenticated(self):
return self.is_authenticated
def is_anonymous(self):
return False
def is_active(self):
return self.is_active
def get_id(self):
return unicode(self.id)
def _check_password(self, password):
hash_check = pbkdf2.crypt(password, self.salt, 1000)
if hash_check ==self.pass_hash:
valid=True
else:
valid=False
return valid
def validate_user(self,password):
p=self.check_password(password=password)
if p:
return True;
else:
return False;
meta = {
'allow_inheritance': True,
'indexes': ['-created_at'],
'ordering': ['-created_at']
}
class UserSerializer(Serializer):
id=fields.Integer()
img=fields.String()
email=fields.String()
first_name=fields.String()
last_name=fields.String()

Found this in the docs silly of me not to realize that they would have different request parameters:
http://psa.matiasaguirre.net/docs/backends/index.html
UPDATE:
See this answer from Babken Vardanyan
https://stackoverflow.com/a/46807907/2529583

Related

How to use database models in Python Flask?

I'm trying to learn Flask and use postgresql with it. I'm following this tutorial https://realpython.com/flask-by-example-part-2-postgres-sqlalchemy-and-alembic/, but I keep getting error.
Cannot import name 'AorticStenosis' from partially initialized module 'models' (most likely due to a circular import)
I understand the problem, but I can't figure out how to fix it. So, I started playing around and try to use the steps by step tutorial on something that I'm working on, but I still get the same problem.
Here's my attempt:
Models.py
from app import db
class AorticStenosis(db.Model):
__tablename__ = 'wvu-model'
id = db.Column(db.Integer, primary_key=True)
ip_address = db.Column(db.String())
date_created = db.Column(db.DateTime, default=datetime.utcnow)
e_prime = db.Column(db.Float())
LVMi = db.Column(db.Float())
A = db.Column(db.Float())
LAVi = db.Column(db.Float())
E_e_prime = db.Column(db.Float())
EF = db.Column(db.Float())
E = db.Column(db.Float())
E_A = db.Column(db.Float())
TRV = db.Column(db.Float())
prediction = db.Column(db.String())
def __init__(self, ip_address, e_prime, LVMi, A, E_e_prime, EF, E, E_A, TRV, prediction):
print('initialized')
self.ip_address = ip_address
self.e_prime = e_prime
self.LVMi = LVMi
self.A = A
self.LAVi = LAVi
self.E_e_prime = E_e_prime
self.EF = EF
self.E = E
self.E_A = E_A
self.TRV = TRV
self.prediction = prediction
def __repr__(self):
return '<id {}>'.format(self.id)
app.py
import os
import ast
import bcrypt
from flask import Flask, redirect, render_template, request, session, url_for
import flask_login
from flask_sqlalchemy import SQLAlchemy
from bigml.deepnet import Deepnet
from bigml.api import BigML
import pickle as pkl
import sklearn
app = Flask(__name__)
if app.config['ENV'] == 'production':
app.config.from_object('as_config.ProductionConfig')
else:
app.config.from_object("config.DevelopmentConfig")
# app.config.from_pyfile('as_config.py')
# app.config.from_object(os.environ['APP_SETTINGS'])
# app.config.from_object('as_config.DevelopmentConfig')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
from models import AorticStenosis
login_key = app.config['LOGIN_KEY']
api_key = app.config['API_KEY']
model = app.config['MODEL']
api = BigML(login_key, api_key)
deepnet = Deepnet(model, api=api)
scaler = pkl.load(open("scaler.pkl", "rb"))
#app.route("/", methods=["GET", "POST"])
def home():
prediction = None
if request.method == "POST":
form_data = [
float(request.form.get("e_prime")),
float(request.form.get("LVMi")),
float(request.form.get("A")),
float(request.form.get("LAVi")),
float(request.form.get("E_e_prime")),
float(request.form.get("EF")),
float(request.form.get("E")),
float(request.form.get("E_A")),
float(request.form.get("TRV"))
]
form_data = scaler.transform([form_data])[0]
print(form_data)
prediction = str(deepnet.predict({
"e_prime": form_data[0],
"LVMi": form_data[1],
"A": form_data[2],
"LAVi": form_data[3],
"E_e_prime": form_data[4],
"EF": form_data[5],
"E": form_data[6],
"E_A": form_data[7],
"TRV": form_data[8]
}, full=True))
prediction = ast.literal_eval(prediction)
print(prediction)
## get ip address from the user
ip_address = request.environ['REMOTE_ADDR']
print("ip_address: ", ip_address)
try:
aorticStenosis = AorticStenosis(
ip_address = ip_address,
e_prime = form_data[0],
LVMi = form_data[1],
A = form_data[2],
LAVi = form_data[3],
E_e_prime = form_data[4],
EF = form_data[5],
E = form_data[6],
E_A = form_data[7],
TRV = form_data[8]
)
db.session.add(aorticStenosis)
db.session.commit()
except Exception as e:
print(str(e))
if prediction["prediction"] == "1":
prediction["prediction"] = "Low Risk"
prediction["probability"] = round(
1 - prediction["probability"], 6)
elif prediction["prediction"] == "2":
prediction["prediction"] = "High Risk"
else:
prediction["prediction"] = "No prediction was made!"
return render_template("home.html",
prediction=prediction["prediction"],
probability=prediction["probability"])
else:
return render_template("home.html")
if __name__ == "__main__":
app.run(host="0.0.0.0", port="8000")
I made a new file database.py and defined db there.
database.py
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
def init_app(app):
db.init_app(app)
app.py
import database
...
database.init_app(app)
models.py
from database import db
...

Generate SQLite database in Flask REST API code

I am new to REST API and starting building first REST API app using Flask, SQLAlchemy & Marshmallow. This is my app.py file:
from flask import Flask, request, jsonify
from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow
import os
# Initialize App
app = Flask(__name__)
basedir = os.path.abspath(os.path.dirname(__file__))
# Database Setup
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(basedir, 'db.sqlite')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
# Init db
db = SQLAlchemy(app)
# Init marshmallow
ma = Marshmallow(app)
# Product Class/Model
class Product(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100), unique=True)
description = db.Column(db.String(200))
price = db.Column(db.Float)
qty = db.Column(db.Integer)
def __init__(self, name, description, price, qty):
self.name = name
self.description = description
self.price = price
self.qty = qty
# Product Schema
class ProductSchema(ma.Schema):
class Meta:
fields = ('id', 'name', 'description', 'price', 'qty')
# Init Schema
product_schema = ProductSchema()
products_schema = ProductSchema(many=True)
# Create Product
#app.route('/product', methods=['POST'])
def add_product():
name = request.json['name']
description = request.json['description']
price = request.json['price']
qty = request.json['qty']
new_product = Product(name, description, price, qty)
db.session.add(new_product)
db.session.commit()
return product_schema.jsonify(new_product)
# Get All Products
#app.route('/receive', methods=['GET'])
def get_products():
all_products = Product.query.all()
result = products_schema.dump(all_products)
return jsonify(result)
# Run the Server
if __name__ == '__main__':
app.run(debug=True)
For generating SQLite database, I have to open python interactive shell and then there I have to do this:
from app import db
db.create_all()
But I have to genreate database from app.py itself so I am inserting the same commands inside app.py, but it's giving me error:
OperationalError: (sqlite3.OperationalError) no such table: product
How do I generate a database from app.py?
Where are you placing your db.create_all()? The error may simply be a result of placement. When I copy and paste your code into PyCharm (running Python 3.7) it creates the DB fine when I place
db.create_all()
immediately before
# Run the Server
if __name__ == '__main__':
app.run(debug=True)
If you try to run db.create_all() before you instantiate the db object it will throw an error because db does not exist yet.
You should not need to use "from app import db" at all because the db object is declared up top.

how to store bcrypt hashpw result in db correctly?

I am in the process of creating a login system.
I use python flask and as database the Prostgresql.
I think I just store the hash value wrong.
I have saved it as vachar 255 so far
My code:
from flask import Flask, render_template, redirect, request, url_for, session
from flask_sqlalchemy import SQLAlchemy
import bcrypt
import psycopg2
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://postgres:PostGreSQL_13#localhost/test'
sql = SQLAlchemy(app)
#app.route('/')
def home():
return render_template("home.html")
#app.route('/register', methods=["GET","POST"])
def register():
if request.method == "GET":
return render_template("register.html")
else:
name = request.form['name']
email = request.form['email']
password = request.form['password'].encode('utf-8')
hash_password = bcrypt.hashpw(password, bcrypt.gensalt())
t_host = 'localhost'
t_port = "5432"
t_dbname = "test"
t_user = "postgres"
t_pw = "password"
db_conn = psycopg2.connect(host=t_host, port=t_port, dbname=t_dbname, user=t_user, password=t_pw)
db_cursor = db_conn.cursor()
db_cursor.execute("INSERT INTO users (UserName,UserEmail,UserPassword) VALUES (%s,%s,%s)",(name,email,hash_password,))
db_conn.commit()
session['name'] = name
session['email'] = email
return redirect(url_for("home"))
#app.route('/login', methods=["GET","POST"])
def login():
if request.method == "POST":
email = request.form['email']
password = request.form['password'].encode('utf-8')
t_host = 'localhost'
t_port = "5432"
t_dbname = "test"
t_user = "postgres"
t_pw = "password"
db_conn = psycopg2.connect(host=t_host, port=t_port, dbname=t_dbname, user=t_user, password=t_pw)
db_cursor = db_conn.cursor()
db_cursor.execute("SELECT username, useremail, userpassword FROM users WHERE useremail=%s",(email,))
user = db_cursor.fetchone()
db_conn.close()
if len(user) > 0:
name = user[0]
if bcrypt.hashpw(password, user[2].encode('utf-8')) == user[2].encode('utf-8'):
session['name'] = user[0]
session['email'] = user[1]
return render_template("home.html")
else:
return "Versuch es doch Nochmal"
else:
return render_template("login.html")
#app.route('/logout')
def logout():
session.clear()
return render_template("home.html")
if __name__ == '__main__':
app.secret_key = '012#!ApaAjaBoleh)(*^%'
app.run(debug=True)
the procedure I got from the Youtube video. see attachment.
I need a login system and this was recommended to me, it works pretty good.
The last one has to work somehow and if it works I would be very happy.
Can anyone tell me what I'm doing wrong or if my appendix with the database is right or wrong?
I know nothing about this language you're using, but any bcrypt implementation will output a string similar to:
$2a$12$ieXy2Rj/TEGqVRx0JihGFesujNFCdmlQWpUaTNvwQ0XuB3lzOcTWK
Yes, you should store that varchar string in your database.

Unable to query data from MongoAlchemy with Flask app

So I'm trying to learn Flask and MongoDB using MongoAlchemy and I'm running into an issue when trying to query my app for data, I'm not sure what I'm doing wrong. I've searched through the MongoAlchemy documentation and followed a few StackOverflow posts to no real avail. Here's my code:
from flask import Flask, jsonify, request
from flask_mongoalchemy import MongoAlchemy
app = Flask(__name__)
app.config['MONGOALCHEMY_DATABASE'] = 'user'
app.config['MONGOALCHEMY_SERVER_AUTH'] = False
db = MongoAlchemy(app)
class User(db.Document):
user_name = db.StringField()
password = db.StringField()
first_name = db.StringField()
last_name = db.StringField()
phone_number = db.StringField()
def init_app():
app = Flask(__name__)
db.init_app(app)
return app
user_1 = User(user_name = "user1",
password = "password",
first_name = "John",
last_name = "Doe",
phone_number = "123-456-7890")
user_1.save()
#app.route('/', methods=['GET', 'POST'])
def index():
return "Hello, world!"
#app.route('/user/<user_name>', methods=['GET', 'POST'])
def findUser(user_name=None):
uName = request.args.get('user_name', user_name)
user = User.query.filter({User.user_name:uName}).first()
return jsonify(user)
##=====================================================================
if __name__ == '__main__':
app.run(debug=True)
When I go to localhost:5000/user/user1 it returns null, I'm not sure what I'm doing wrong? Thanks in advance!
Referenced Posts:
MongoAlchemy query embedded documents
Flask Value error view function did not return a response
http://www.mongoalchemy.org/api/schema/document.html

Flask BCrypt check_password_hash return False after saving via MongoEngine

I run into a weird situation, which is similar to this . This is my model:
class User(db.Document):
email = db.EmailField(required=True, unique=True)
username = db.StringField(max_length=50, required=True, unique=True )
password = db.StringField(required=True)
first_name = db.StringField(max_length=100, required=False)
last_name = db.StringField(max_length=100, required=False)
role = db.IntField(required = True, choices = role_choices, default = 5)
status = db.IntField(required = True, choices = status_choices, default = 1)
last_login = db.DateTimeField(required=False)
#property
def is_authenticated(self):
return True
#property
def is_active(self):
return True
#property
def is_anonymous(self):
return False
def __unicode__(self):
return self.username
def set_password(self, password):
self.password = bcrypt.generate_password_hash(password)
def __init__(self, *args, **kwargs):
username = kwargs.pop('username', None)
password = kwargs.pop('password', None)
email = kwargs.pop('email', None)
super(User, self).__init__(*args, **kwargs)
self.username = username
self.set_password(password)
self.email = email
meta = {
'allow_inheritance': False,
'indexes': ['-username'],
'ordering': ['-username']
}
def check_password(self, password):
return bcrypt.check_password_hash(self.password, password)
When I first create an instance of this User class, everything works as expected:
an = User(username="annguyen", first_name="An", last_name="Nguyen", password="janet78", email="an#gmail.com")
>>> an.password
'$2b$12$Ho9Q0/n4FPERytHKxA3szu8gzRZE4J9FxuZots8FFxJUKP6ULmqpe'
>>> an.save()
<User: annguyen>
>>> len(an.password)
60
>>> an.check_password('janet78')
True
However, when I retrieve this user from the database, the check_password method always return False.
>>> an_new = User.objects.get(username='annguyen')
>>> an_new.password
'$2b$12$j9VfNiySMKN19cYIEjuAseiamREUmGbB2ZFM4faoLJySB6uZfaCj2'
>>> len(an.password)
60
>>> len(an_new.password)
60
>>> an_new.check_password('janet78')
False
It is very clear that the password retrieved from the database is very different from what it was before being saved to the database, and therefore it always returns False. I spent a whole day trying to figure out what's wrong but couldn't come up with any clue. Can someone help point out how I can fix it.
I am developing on Windows 10 with Python 2.7, Flask 0.10.1, MongoDB 3.2, flask-mongoengine==0.7.5, mongoengine==0.10.6
Thanks a lot.