I cant add more then one user in database - python

I want to add users in group table, i'm checking user in all group member if and then if he is already in table i flash the message and if not i add user to the group. but it only does for the first user. and the rest the logic evaluate false
#main.route('/join-classroom/<int:classroom_id>/<int:user_id>/')
#login_required
def join_classroom(classroom_id, user_id):
classroom = Classroom.query.filter_by(id=classroom_id).first()
if classroom is None:
flash('Invalid classname')
return redirect(url_for('main.classrooms'))
else:
# check if user aleady added or on request
classroomMembers = ClassroomMember.query.filter_by(user_id=user_id).all()
for classroomMember in classroomMembers:
if (classroomMember.user_id == user_id) and (classroomMember.classroom_id == classroom_id):
flash('You are already in Group ')
return redirect(url_for('main.classrooms'))
elif (classroomMember.user_id != user_id) and (classroomMember.classroom_id != classroom_id):
classroomMember = ClassroomMember(classroom_id=classroom_id, user_id=user_id)
db.session.add(classroomMember)
db.session.commit()
flash('Your request has been sent successfully')
return redirect(url_for('main.classrooms'))
elif classroomMember.user_id is None:
classroomMember = ClassroomMember(classroom_id=classroom_id, user_id=user_id)
db.session.add(classroomMember)
db.session.commit()
flash('Your request has been sent successfully')
return redirect(url_for('main.classrooms'))

When you request
classroomMembers = ClassroomMember.query.filter_by(user_id=user_id).all()
you get in classroomMembers records with user_id=user_id and only such records.
That's way only the first if clause can be True and code in two other elif will never be executed.
So you need to check if a person in a group and add there if not. And if a person does not exist create a new one. For instance like so:
classroomMembers = ClassroomMember.query.filter_by(user_id=user_id).all()
if classroomMembers:
classroomMember = classroomMembers[0]
if classroomMember.classroom_id == classroom_id:
flash('You are already in Group ')
return redirect(url_for('main.classrooms'))
else:
classroomMember.classroom_id = classroom_id
db.session.add(classroomMember)
db.session.commit()
flash('You were added to the Group')
return redirect(url_for('main.classrooms'))
else:
classroomMember = ClassroomMember(classroom_id=classroom_id, user_id=user_id)
db.session.add(classroomMember)
db.session.commit()
flash('Your request has been sent successfully')
return redirect(url_for('main.classrooms'))

I solved the problem with
#main.route('/join-classroom/<int:classroom_id>/<int:user_id>/')
#login_required
def join_classroom(classroom_id, user_id):
classroom = Classroom.query.filter_by(id=classroom_id).first()
if classroom is None:
flash('Invalid classname')
return redirect(url_for('main.classrooms'))
else:
classroomMember = ClassroomMember.query.filter_by(user_id=user_id).filter_by(classroom_id=classroom_id).first()
if classroomMember is None:
classroomMemberUser = ClassroomMember(classroom_id=classroom_id, user_id=user_id)
db.session.add(classroomMemberUser)
db.session.commit()
flash('Your request has been sent successfully')
return redirect(url_for('main.classrooms'))
else:
flash("You are already in the Group")
return redirect(url_for('main.classrooms'))

Related

JSON Token won't load the value after being verified

Once I get to the verify_token function it keeps executing the except statement instead of returning the value in 'id_user' and I'm not sure why. I am using these libraries. flask-login, sqlalchemy, itsdangerous for jsonwebserializer, and wtforms.
Functions
def get_reset_token(user):
serial = Serializer(app.config['SECRET_KEY'], expires_in=900) # 15 mins in seconds
return serial.dumps({'id_user':user.id}).decode('utf-8')
def verify_token(token):
serial = Serializer(app.config['SECRET_KEY'])
try:
user_id = serial.load(token)['id_user']
except:
return None
return Users.query.get('id_user')
def send_mail(user):
token = get_reset_token(user)
message = Message('Password Reset Request', recipients = [user.email], sender='noreply#gmail.com')
message.body= f'''
To Reset your password, click the following link:
{url_for('reset_token', token = token, _external = True)}
If you did not send this email, please ignore this message.
'''
mail.send(message)
ROUTES
#app.route('/password_reset', methods = ['GET', 'POST'])
def password_reset():
form = Password_request()
if request.method == "POST":
if form.validate_on_submit:
user = Users.query.filter_by(email = form.email.data).first()
send_mail(user)
flash('Check your email. Password change request has been sent')
return redirect(url_for('login'))
else:
flash('Your email was not linked to an account')
return render_template('password_reset.html', form = form)
#app.route('/password_reset/<token>', methods = ['GET', 'POST'])
def reset_token(token):
user = verify_token(token)
if user == None:
flash('The token is invalid or expired')
return redirect(url_for('password_reset'))
form = Password_success()
if form.validate_on_submit:
hashed_password=generate_password_hash(form.password.data, method = 'sha256')
user.password = hashed_password
db.session.commit()
flash('Your password has been updated!')
return redirect(url_for('signup'))
def verify_token(token):
serial = Serializer(app.config['SECRET_KEY'])
try:
user_id = serial.load(token)['id_user']
except:
return None
return Users.query.get('id_user') # this looks wrong
Shouldn't the last line of verify_token be return Users.query.get(user_id)? You're assigning the value of the token to that variable , then ignoring it and telling SQLAlchemy to find a record with the ID of the string value 'id_user' which I doubt is what you're intending to do.
def verify_token(token):
serial = Serializer(app.config['SECRET_KEY'])
try:
user_id = serial.load(token)['id_user']
except:
return None
return Users.query.get(user_id) # What happens when you change this?

Change user's boolean when signing out on Flask

Every time a new user is connected to the server I got a list of the users that refresh to show them in my page. I'm using a boolean for that, every time a user is connecting their boolean changes to True and my list is looking for users with the boolean True only. I'm trying now to change the boolean back to False when they sign out. How can I do this?
#app.route("/sign-in", methods=["GET", "POST"])
def signin():
form = forms.SignInForm()
if flask.request.method == "POST":
if form.validate_on_submit():
username = form.username.data
password = form.password.data
# Retrieve the user that matches this username
user = models.User.query.filter_by(name=username).first()
print(user.boolean)
# Check the provided password against the user's one
if user is not None and user.password == password:
flask_login.login_user(user)
flask.flash(f"{user.name} logged in successfully !", "success")
idn = user.id
user.boolean = True
db.session.commit()
print(user.boolean)
return flask.render_template('user_page.html', user=user)
else:
flask.flash("Something went wrong.", "danger") # Put the message into the flashed messages
# To retrieve those messages: flask.get_flashed_messages()
return flask.render_template("signin.html", form=form)
#app.route("/sign-out", methods=["GET"])
def signout():
flask_login.logout_user()
return flask.redirect('/sign-in')
Put it in the signout route:
#app.route("/sign-out", methods=["GET"])
def signout():
user = models.User.query.filter_by(id=current_user.id).first()
user.boolean = False
db.session.commit()
flask_login.logout_user()
return flask.redirect('/sign-in')

Next parameter in url not showing but is printing correctly in django

This is my signup view:
def signup(request):
next = request.GET.get('next', '')
print(next)
if request.user.is_authenticated:
return redirect('/')
else:
if request.method == "POST":
first_name=request.POST['first_name']
email=request.POST['email']
password=request.POST['password']
cpassword=request.POST['cpassword']
signup_uri = f'/signup?next={next}'
if password==cpassword:
if User.objects.filter(email=email).exists():
messages.info(request,'Email already in use')
return redirect(signup_uri)
elif User.objects.filter(mobile=mobile).exists():
messages.info(request,'Mobile Number already in use')
return redirect(signup_uri)
else:
user=User.objects.create_user(first_name=first_name,email=email,password=password)
user.save();
return redirect(f'/login?next={next}')
else:
messages.info(request,'Passwords not matching')
return redirect('signup_uri')
else:
return render(request,'signup.html')
The problem I am facing is that when I am printing next under def signup it is printing it correctly but when it has to redirect it redirects without showing anything as next in url. That is signup_uri = f'/signup?next={next}' and return redirect(f'/login?next={next}') are showing the {next} as empty.What could be the reason?Any help would be appriciated.
Based on the definition of the signup method, you are only retrieving the value of the next parameter only for the GET request. But when you are trying for a POST request, you do not retrieve the value of the next parameter. For this reason, the value of the next variable is set to "" and hence, the value of the signup_uri variable is being set as "/signup?next=" as well as for the login redirecting url ("/login?next=") too. In order to get rid of this problem, your code should be similar to as follows.
def signup(request):
next = request.GET.get('next', '')
print(next)
if request.user.is_authenticated:
return redirect('/')
else:
if request.method == "POST":
first_name = request.POST['first_name']
email = request.POST['email']
password = request.POST['password']
cpassword = request.POST['cpassword']
next = request.POST.get("next", "")
signup_uri = f'/signup?next={next}'
if password == cpassword:
if User.objects.filter(email=email).exists():
messages.info(request,'Email already in use')
return redirect(signup_uri)
elif User.objects.filter(mobile=mobile).exists():
messages.info(request,'Mobile Number already in use')
return redirect(signup_uri)
else:
user = User.objects.create_user(first_name=first_name, email=email, password=password)
user.save();
return redirect(f'/login?next={next}')
else:
messages.info(request, 'Passwords not matching')
return redirect('signup_uri')
else:
return render(request, 'signup.html')

How to stop Pyrebase set() from overriding existing data?

I am creating a simple directory with Flask & Pyrebase; I have managed to create the login ok, and the registration form. The user is redirected to their profile page once signed in & registered.
My issue that I have is when I try to add a new entry my existing data is overwritten. When I create a new db entry I use set() instead of push() I am thinking this could be why?
I have shortened the code us much as possible
creating account & registering business:
#app.route('/register', methods=['GET', 'POST'])
def register():
unsuccessful = 'Please check your credentials'
successful = 'Registraion successful'
if request.method == 'POST':
email = request.form.get('email')
confirmEmail = request.form('confirmEmail')
password = request.form.get('pass')
userName = request.form.get('inputName')
businessName = request.form.get('businessName')
startYear = request.form.get('startYear')
selectCategory = request.form.get('selectCategory')
businessDescription = request.form.get('businessDescription')
businessAddress = request.form.get('businessAddress')
businessTown = request.form.get('businessTown')
businessCity = request.form.get('businessCity')
businessPostcode = request.form.get('businessPostcode')
businessNumber = request.form.get('businessNumber')
businessEmail = request.form.get('businessEmail')
bameRegister = dict(
userName = userName,
confirmationEmail = confirmEmail,
businessName = businessName,
businessStartYear = startYear,
businessCategory = selectCategory,
businessDescription = businessDescription,
businessAddress = [businessAddress, businessTown, businessCity, businessPostcode],
businessNumber = businessNumber,
businessEmail = businessEmail,
)
if selectCategory == "arts":
try:
user = auth.create_user_with_email_and_password(email, password)
auth.send_email_verification(user['idToken'])
db.child("Bame_Buisness").child("business").child("arts").set(bameRegister, user['idToken'])
return render_template('homepage.html', x=successful)
except:
return render_template('homepage.html', y=unsuccessful)
elif selectCategory == "food":
try:
user = auth.create_user_with_email_and_password(email, password)
auth.send_email_verification(user['idToken'])
db.child("Bame_Business").child("business").child("food").set(bameRegister, user['idToken'])
return render_template('homepage.html', x=successful)
except:
return render_template('homepage.html', y=unsuccessful)
elif selectCategory == "health":
try:
user = auth.create_user_with_email_and_password(email, password)
auth.send_email_verification(user['idToken'])
db.child("Bame_Business").child("business").child("health").set(bameRegister, user['idToken'])
return render_template('homepage.html', x=successful)
except:
return render_template('homepage.html', y=unsuccessful)
return render_template('homepage.html')
Creating the login:
#app.route('/login', methods=['GET', 'POST'])
def login():
unsuccessful = 'Please check your credentials'
if request.method == 'POST':
try:
user = auth.sign_in_with_email_and_password(email, password)
signed_in_user = auth.get_account_info(user['idToken'])
artCategory = db.child("Bame_Business").child("business").child("arts").get(user['idToken']).val()
foodCategory = db.child("Bame_Business").child("business").child("food").get(user['idToken']).val()
healthCategory = db.child("Bame_Business").child("business").child("health").get(user['idToken']).val()
if signed_in_user['users'][0]['email'] == artCategory['confirmationEmail']:
return render_template('profile.html', artCategory=artCategory)
elif signed_in_user['users'][0]['email'] == foodCategory['confirmationEmail']:
return render_template('profile.html', foodCategory=foodCategory)
elif signed_in_user['users'][0]['email'] == healthCategory['confirmationEmail']:
return render_template('profile.html', healthCategory=heathCategory)
except:
return render_template('homepage.html')
return render_template('homepage.html')
This is the route to create a new business once logged in:
#app.route('newBusiness', methods=['GET', 'POST'])
def newBusiness():
if request.method == 'POST':
email = request.form.get('email')
confirmEmail = request.form.get('confirmEmail')
password = request.form.get('pass')
userName = request.form.get('userName')
businessName = request.form.get('businessName')
startYear = request.form.get('startYear')
selectCategory = request.form.get('selectCategory')
businessDescription = request.form.get('businessDescription')
businessAddress = request.form.get('businessAddress')
businessTown = request.form.get('businessTown')
businessCity = request.form.get('businessCity')
businessPostcode = request.get('businessPostcode')
businessNumber = request.form.get('businessNumber')
businessEmail = request.form.get('businessEmail')
bameRegister = dict(
userName = userName,
confirmationEmail = confirmEmail,
businessName = businessName,
businessStartYear = startYear,
businessCategory = businessCategory,
businessDescription = businessDescription,
businessAddress = [businessAddress, businessTown, businessCity, businessPostcode],
businessNumber = businessNumber,
businessEmail = businessEmail,
)
if selectCategory == "arts":
try:
user = auth.sign_in_with_email_and_password(email, password)
user = auth.refresh(user['refreshToken'])
db.child("Bame_Business").child("business").child("arts").set(bameRegister, user['idToken'])
signed_in_user = auth.get_account_info(user['idToken'])
artCategory = db.child("Bame_Business").child("business").child("arts").get(user['idToken']).val()
if signed_in_user['users'][0]['email'] == artCategory['confirmationEmail']:
return render_template('profile.html', artCategory=artCategory)
except:
return render_template('homepage.html')
elif selectCategory == "food":
try:
user = auth.sign_in_with_email_and_password(email, password)
user = auth.refresh(user['refreshToken'])
db.child("Bame_Business").child("business").child("food").set(bameRegister, user['idToken'])
signed_in_user = auth.get_account_info(user['idToken'])
foodCategory = db.child("Bame_Business").child("business").child("food").get(user['idToken']).val()
if signed_in_user['users'][0]['email'] == foodCategory['confirmationEmail']:
return render_template('profile.html', foodCategory=foodCategory)
except:
return render_template('homepage.html')
elif selectCategory == "health":
try:
user = auth.sign_in_with_emal_and_password(email, password)
user = auth.refresh(user['refreshToken'])
db.child("Bame_Business").child("business").child("health").set(bameRegister, user['idToken'])
signed_in_user = auth.get_account_info(user['idToken'])
healthCategory = db.child("Bame_Business").child("business").child("health").get(user['idToken']).val()
if signed_in_user['users'][0]['email'] == healthCategory['confirmationEmail']:
return render_template('profile.html', healthCategory=healthCategory)
except:
return render_template('homepage.html')
return render_template('homepage.html')
After the user has logged in, lets say they register their 1st business in the arts category, when they register their 2nd different business in the arts category the original collection is overwritten in Firebase. This happens even when selecting a different category. This is definitely not ideal as someone could overwrite someone else's data - which then leads to all sorts of problems!
I understand you can use push & set to create new entries in pyrebase; I chose set because when I used push it creates a unique tag which I found it hard to get individual access from a users account. With the set method it is easy to call out the part of the dictionary I want with artCategory['businessName'] or artCategory['businessDescription'] or artCategory['confirmationEmail'] etc
I just need to create a new business registration after login in without overriding any existing data, if anyone could help me come up with a solution that would be much appreciated.
Kind regards
.set() overrides. .update() updates only the fields that have changed.

Flask-login error , python

I'm new to python/flask and am trying to build app using flask-login. I can't get my head around the error I'm getting "object has no attribute 'get_id'" Appreciate your help.
class User(UserMixin):
def __init__(self, email, id, active=True):
self.email = email
self.id = id
#self.active = active
def get_id(self):
return self.id
def is_active(self):
# Here you should write whatever the code is
# that checks the database if your user is active
return True
def is_anonymous(self):
return False
def is_authenticated(self):
return True
login_manager = LoginManager()
login_manager.init_app(app)
# load_user .. never makes it till here
#login_manager.user_loader
def load_user(userid):
try:
print 'this gets executed:--', userid
return User.get(User.id==userid)
except User.DoesNotExist:
return None
#app.route('/confirm/<token>', methods=['GET', 'POST'])
def confirm_email(token):
try:
email = confirm_token(token)
print email
except:
flash('The confirmation link is invalid or has expired.', 'danger')
userExists = db.userExists(email)
if userExists:
flash('Account already confirmed. Please login.', 'success')
login_user(userExists, force=True, remember=True)
else:
flash('You have confirmed your account. Thanks!', 'success')
confirm_login()
login_user(userExists, force=True, remember=True)
return redirect(url_for('Hello'))
code for db
def userExists(email):
SQL = """SELECT * FROM all_users WHERE email = %s"""
data = (email,)
records = runQuery(SQL, data)
if records and records[0]:
return records[0][0]
else:
records
Error that I'm getting:
File "/Documents/Dev/Ottawa-Final/ottawa-final/app/network_of_innovators.py", line 310, in confirm_email
login_user(userExists, force=True, remember=True)
File "/Documents/Dev/lib/python2.7/site-packages/flask_login.py", line 678, in login_user
user_id = getattr(user, current_app.login_manager.id_attribute)()
AttributeError: 'str' object has no attribute 'get_id'
In confirm_email, userExists is a string (I'm guessing the users email returned by your userExists() method). login_user() expects its first parameter to be an object but you're passing a string, hence your error.
The solution is to create a User object first and then pass that to login_user()
Ex. You should be doing something like:
userExists = db.userExists(email)
if userExists:
flash('Account already confirmed. Please login.', 'success')
user_id = db.getUserId(email) # Get the User's id somehow
user = User(email, user_id)
login_user(user, force=True, remember=True)

Categories

Resources