Getting None instead of string - python-3.x

I have a Streamlit application that lets the user login (by checking with SQLite databse) and then do some action. My problem is that I'm trying to print a welcome message with the user's username but I'm getting 'None' instead.
This is my Login function:
def show_login_page():
with loginSection:
if st.session_state['loggedIn'] == False:
username = st.text_input (label="Username", value="", placeholder="Enter your username")
password = st.text_input (label="Password", value="", placeholder="Enter password", type="password")
hashed_password = make_hash(password)
st.button("Login", on_click=LoggedIn_Clicked, args= (username, hashed_password))
return username
Then after clicking the login button, user's information will be checked with the database
def LoggedIn_Clicked(username, password):
# check with database
if login_user(username, password):
st.session_state['loggedIn'] = True
else:
st.session_state['loggedIn'] = False
st.error("Invalid username or password")
After sucessfully logging in, the session_state will change and the user will login to the main page
with headerSection:
st.title("Streamlit Application")
#first run will have nothing in session_state
if 'loggedIn' not in st.session_state:
st.session_state['loggedIn'] = False
show_login_page()
else:
if st.session_state['loggedIn']:
show_logout_button()
# getting the username from login page
# Problem is here
usr = show_login_page()
show_main_page(usr)
else:
show_login_page()
This is the main page function:
def show_main_page(username):
with mainSection:
st.header(f"Hello {username}")
# Do some action
processingClicked = st.button("Start Processing", key="processing")
if processingClicked:
st.balloons()
I've tried many ways was to get the username variable from the login_page to the main_page function to no avail. Help would be appreciated.

Related

How to create login function for different user groups with Flask Session

I'm trying to set up a login function for each user type with Python using Flask Session. For example, there are two user types: employees and supervisors and I want to show different pages when each user type logs in.
I have a csv file (userinfo) that contains the user information including user name and password.
username password
employee employee
supervisor supervisor
I currently have the following block of code to achieve it, but it seems like it's not working. If the employee user logs in, I want to show the employee page and if the supervisor group logs in, I want to show the supervisor page. But it seems like the current code takes the users to the same homepage.
userinfo = pd.read_csv("userinfo.csv")
#app.route("/homepage", methods=["GET", "POST"])
def login():
# get user name and password input from a html form.
username = request.form["username"]
password = request.form['password']
# get user name and password from the csv file.
get_user = userinfo[userinfo["user_name"] == username].to_dict("records")[0]
get_password = userinfo[userinfo["password"] == password].to_dict("records")[0]
# login function
if username and password == get_password:
session["user_name"] = username
session["password"] = password
print("Login Session:", session)
if username == "employee":
return redirect("/employee_page")
elif username == "supervisor":
return redirect("/supervisor_page")
else:
return redirect("/homepage")
else:
return redirect("/homepage")

why user’s session is not expired when the user’s Web browser is closed in Django?

I developed a website using Django. I have used the 'Remember me' checkbox on the login page. If a user logged in to their account/page without checking the 'Remember me' option, the session is not expiring when the browser is closed. I have used request.session.set_expiry(0).But the session is not expiring.
When the user clicks the checkbox(Remember me option), the session works properly.
Also, I used the user_passes_test decorator in order to prevent the login user to go back to the login page and register page, etc.
views.py
#user_passes_test(user_is_not_logged_in, login_url='individual_homes', redirect_field_name=None)
def logins(request):
if request.method == 'POST':
email = request.POST['email']
password = request.POST['password']
remember_me = request.POST.get('remember')
print(remember_me)
user = authenticate(request, email=email, password=password)
if user is not None:
login(request, user)
if user.type == "individual":
details = IndividualProfile.objects.filter(user_id=request.user.id)
if not details:
if not remember_me:
request.session.set_expiry(0)
return redirect("individual_home")
else:
request.session.set_expiry(30)
return redirect("individual_home")
else:
if not remember_me:
request.session.set_expiry(0)
return redirect("individual_homes")
else:
request.session.set_expiry(30)
return redirect("individual_homes")
else:
return render(request, "login.html", {'msg': "Invalid Credentials"})
return render(request, "login.html")
Can anyone suggest a solution for this.

django authenticate not working with user created by api , only work with user created by admin

i'm trying to generated token after login using drf. i'm using emailbackend for login with email and password but its not working with user created by api and with user created by admin its working
backends.py:
class EmailBackend(ModelBackend):
def authenticate(self, request, username=None, password=None, **kwargs):
UserModel = get_user_model()
try:
user = UserModel.objects.get(email=username)
except UserModel.DoesNotExist:
return None
else:
if user.check_password(password):
return user
return None
Token serializers:
class AuthCustomTokenSerializer(serializers.Serializer):
'''
Changing Token auth to use email instead username
'''
email = serializers.EmailField(label=_("Email"))
password = serializers.CharField(
label=_("Password",),
style={'input_type': 'password'},
trim_whitespace=False
)
def validate(self, attrs):
email = attrs.get('email')
password = attrs.get('password')
print(email, password)
if email and password:
user = authenticate(username=email, password=password)
print("this is user", user)
# The authenticate call simply returns None for is_active=False
# users. (Assuming the default ModelBackend authentication
# backend.)
if not user:
msg = _('Unable to log in with provided credentials.')
raise serializers.ValidationError(msg, code='authorization')
else:
msg = _('Must include "username" and "password".')
raise serializers.ValidationError(msg, code='authorization')
attrs['user'] = user
return attrs
login view:
#csrf_exempt
#api_view(["POST"])
#permission_classes((AllowAny,))
def login(request):
serializer = AuthCustomTokenSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
user = serializer.validated_data['user']
token, _ = Token.objects.get_or_create(user=user)
return Response({token: token.key}, status=status.HTTP_200_OK)
with admin login:
user login create by api:
register api:
Thanks, Great.
This means that authenticate(username=email, password=password) does not return a user.
Do you work with a degugger ? or may be add a
print(email, password) just after the auth call.
print what comes back from auth . print(authenticate(username=email, password=password))
My guess is that username is not email or somthing like that :)
Edit
How to debug:
login with admin user stop just before this line:
authenticate(username=email, password=password)
check and print the email and password
Do the same with API user check and print the email and password
see that values are the same .
login to django admin site check all premissions flag groups etc etc that are different between both users
try to login to admin page with the api user (set up the correct flags is_active etc)
try in the django manage.py shell or from admin user page to create new password for the api user and retest

validating user input using flask_wtf and sqlalchemy

Noob question. I am building a login/registration pages, on the registration page, I am using flask_wtf to verify certain things like length of password, email format and whether the two password a user supplies match. Here is the flask_wtf code I am using to do that.
# import statements omitted for brevity
class RegistrationForm(FlaskForm):
username = StringField('Username',
validators=[DataRequired(), Length(min=2, max=20)])
email = StringField('Email',validators=[DataRequired(), Email()])
password = PasswordField('Password', validators=[DataRequired()])
confirm_password = PasswordField('Confirm Password',
validators=[DataRequired(),Length(min=4, max=20), EqualTo('password')])
submit = SubmitField('Sign Up')
After checking the input, I am using sqlalchemy to check if the username and email already exists in my DB. The problem I am facing right now is I cant get flask_wtf to verify the form. I can type whatever I want and it will be converted to a sql query. Here are my two flask routes that handle registration and user input validation.
#app.route('/register',methods=['GET','POST'])
def register():
form = RegistrationForm()
if form.validate_on_submit():
return redirect(url_for('check_user_input'))
return render_template('register.html',form=form)
#app.route('/status',methods=['POST'])
def check_user_input():
name = request.form.get("username")
email = request.form.get("email")
password = request.form.get("password")
if db.execute("SELECT * FROM DB WHERE username= :username",{"username":name}).rowcount==1:
return render_template("404.html", message="Sorry username already exists")
elif db.execute("SELECT * FROM DB WHERE email= :email",
{"email":email}).rowcount==1:
return render_template("404.html", message="Sorry email already exists")
else:
db.execute("INSERT INTO DB (username,email,password) VALUES
(:username,:email,:password)",
{"username":name, "email":email,"password":password})
db.commit()
return render_template("success.html")
How can I get flask_wtf form to do its verification first and then hand the input to check_user_input() function?
My register.html contains the following line.
<form class="form-signin" method="POST" action="{{url_for('check_user_input')}}">
Any help would be greatly appreciated.
A way is to add a custom validation to the form :
class RegistrationForm(FlaskForm):
username = StringField('Username',
validators=[DataRequired(), Length(min=2, max=20)])
email = StringField('Email',validators=[DataRequired(), Email()])
password = PasswordField('Password', validators=[DataRequired()])
confirm_password = PasswordField('Confirm Password',
validators=[DataRequired(),Length(min=4, max=20), EqualTo('password')])
submit = SubmitField('Sign Up')
def validate(self):
rv = FlaskForm.validate(self)
if not rv:
return False
if db.execute("SELECT * FROM DB WHERE username= :username",{"username":self.username.data}).rowcount>0:
self.username.errors.append('Sorry username already exists')
return False
if db.execute("SELECT * FROM DB WHERE email= :email", {"email":self.email.data}).rowcount>0:
self.email.errors.append('Sorry email already exists')
return False
return True

how to find the username of a user from database when email is given in django

i am creating a website where a banks loggs in with its username which is a code but i wanted that bank could log in with its first_name.
i am using default user model for registration.
but authenticate() function works only with username so what i wanted to do is that bank fill their name and function finds the value of username with corrosponding name in the database and then use authenticate() function to log the bank in.
my login function in view.py
def login(request):
if request.method == 'POST':
name = request.POST.get('first_name')
password = request.POST.get('password')
username = ????????
user = authenticate(username=username, password=password)
if user:
if user.is_active and has_role(user,Banker):
auth_login(request,user)
return HttpResponseRedirect(reverse('business:dashboard'))
else:
messages.error(request,"Your account is not active")
return render(request,'accounts/bank_login.html')
else:
messages.error(request,"Invalid Username or Password")
return render(request,'accounts/bank_login.html')
else:
if request.user.is_authenticated:
return HttpResponseRedirect(reverse('business:dashboard'))
else:
return render(request,'accounts/bank_login.html')
so please anybody could tell what should i write in that username to get the value of username from database
**my models.py **
from django.db import models
from django.contrib import auth
# Create your models here.
class User(auth.models.User,auth.models.PermissionsMixin):
def __str__(self):
return self.user.username
This is slightly more complex than doing a simple query. Also, you cannot rule our that two users with the same first name will choose the same password. Here the first user found is taken
Something like this:
from django.contrib.auth.hashers import check_password
firstnameusers = User.objects.filter(first_name=name)
for usr in firstnameusers:
if check_password(password, usr.password):
username = usr.username
break
Note that you will need to write some code to handle the case where a user is not found.
I used this in my views.py file and it works perfectly
def login(request):
if request.method == 'POST':
name = (request.POST.get('name')).upper()
username = (get_user_model().objects.all().filter(first_name = name)).values("username")[0]["username"]
password = request.POST.get('password')
user = authenticate(username=username, password=password)

Resources