Accessing specific item in sqlite3 database when user and password matches - python

I've created a login GUI with sqlite in python and i've got it working correctly, however I want it to do something else as well when it logs in.
My sqlite database currently has the following columns;
Username, Email, Password, Workstation, Directory
I've found that you can take an item string in the table by using something like;
connection.fetchall()[index]
However, I don't know how to implement it into my code to check for the user that logged in.
username = "username"
password = "password"
# database information
connection = sqlite3.connect(databasepath+'\login.db')
result = connection.execute("SELECT * FROM USERS WHERE USERNAME = ? AND PASSWORD = ?", (username, password))
if (len(result.fetchall()) > 0):
#some code#
I want to access the 'Directory' item for the user that logged in

Related

Changing user's password using Flask and SQLite

I am trying to implement a function to change the user's password. I am storing only the hash in DB not the password and I want to ask the user to enter the old password first then the new one. I want to check if the old password's hash is matching the one stored in DB and if so, to update it with the new one. I am doing something wrong as the code is not passing the validation checks and I am having an error: "Invalid password".
Any help, would be appreciated.
#app.route("/change_password", methods=["GET", "POST"])
#login_required
def change_password():
user_id=session["user_id"]
if request.method=="POST":
password = request.form.get("password")
hash = generate_password_hash(password)
new_password = request.form.get("new_password")
confirm_new_password = request.form.get("confirm_new_password")
new_hash = generate_password_hash(new_password)
#Validations:
if not password:
return apology("must provide password", 400)
if not new_password:
return apology("must provide a new password", 400)
#Ensure password confirmation is provided
if not confirm_new_password:
return apology("must confirm new password", 400)
#Check if new password matches
if new_password!= confirm_new_password:
return apology("password does not match", 400)
# Query database for the current password
rows = db.execute("SELECT * FROM users WHERE hash = ?", hash)
# Ensure username exists and password is correct
if len(rows) != 1:
return apology("invalid password", 400)
#Update DB with the new_hash
else:
db.execute ("UPDATE users SET hash=:new_hash WHERE id=:id", new_hash = new_hash, id = user_id)
return redirect("/")
else:
return render_template("change_password.html")
There are quite some problems with your code...
The biggest problem
rows = db.execute("SELECT * FROM users WHERE hash = ?", hash)
You have to search for the user name, not for the hash!!! Imagine, two users have the same password, or a user enters the wrong password, but that is the password of another user...
I never used direct access to sqlite, only via sqlalchemy, but from a quick look at the docs ( https://docs.python.org/3/library/sqlite3.html#sqlite3.Cursor.executemany ) db.execute does not return e.g. rows, but you need to query it.
e.g. after your db.execute you need to do a db.fetchone or db.fetchall, see above linked documentation.
Also, the order of your code could be improved.
e.g. first, you generate the hash of a new password, and then afterwards you check whether there is a password at all - this should be switched.
Speaking of validation, much of it could be done via e.g. flask-wtforms, so you don't need so much validation code on your own.

Updating a Table by using Sqlite3 Module in Python

I am working on a project where i need to update the password column of a user table pointing userid as the primary key, whenever the user reset his/her password. I am passing username and password to update_table function based on the values entered by the user from console and below is my code snippet -
def sql_update_table(conn, username, reset_password):
c = conn.cursor()
#value = (username, reset_password)
#c.execute('''UPDATE user SET password = ? WHERE userid = ? ''', value)
c.execute('''UPDATE user SET password = reset_password WHERE userid = username''')
conn.commit()
I tried both case passing values with a tuple as mentioned in # and directly as mentioned without a #. However, for first case, there is no error but the table is not getting updated with the new value of password and for later one i am getting below error -
sqlite3.OperationalError: no such column: reset_password
Please help me to solve this.
Thanks in advance !
Can you please try replacing
c.execute('''UPDATE user SET password = reset_password WHERE userid = username''')
with
c.execute('''UPDATE user SET password = ? WHERE userid = ? ''', (username,reset_password))

locating a password that corresponds to a username within an sqlite table

I am running a website using Flask microframework and sqlite3 to store user logins. Currently, I am having trouble with matching the username and password entered by the user from an HTML form, with the existing records within my database.
I am using the flask-login extension to help me with this, and when I try and match, I am receiving a TypeError:
list indices must be integers or slices, not str
here is my python code that is turning the SQLite table into a variable:
con = sql.connect("table.db")
cur = con.cursor()
cur.execute('SELECT * FROM users')
names = cur.fetchall()
I then have this code which is taking the password from the HTML form, and trying to match it with the password linked to the username in the table
user_name = request.form['username']
if request.form['password'] == names[user_name]['password']:
user = User()
user.id = user_name
flask_login.login_user(user)
this is what 'names' returns:
[(7, 'ValidName', 'ValidTest', 'User#test.com'), (8, 'User2', 'password2', 'User#test2.com')]
What needs to happen is the program will check the form input for 'password' and will match it with the 'password' that is related to the username. So as an example, if ValidName and ValidTest were entered into the form, they would be requested by the program, and matched with the records found in 'names'.
I assume you have not hashed your password which is something you should do. Without security in mind
here is my dirty approach
cur.execute('SELECT * FROM users WHERE name = %s AND password = %s', (request.form['username'], request.form['password']))
user = cur.fetchone()
This can be helpful
Here is the guilty: names[user_name]['password']
names is the return value of fetchall and hence is a plain list. To use it in above expression, it should be a mapping of mappings.
You should construct it that way:
names = {row[1]: {'id': row[0], 'password': row[2], 'mail': row[3]}
for row in cur.fetchall()}
But beware: this loads the full user database in memory. It only makes sense if you have few users...

Is it possible to deny access to copied password field in database?

My Django app password in database looks like this:
pbkdf2_sha256$100000$XXXXXXXXXX$XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
But if I duplicate it to another user, I could log in to that user's account.
Assuming a database breach or some kind of injection, can I detect if password was somehow duplicated/copied so that I can deny access to the account or alert admins?
as Selcuk says if some one has access to write into your database, he/she can do anything like generate password as your system want.
but you can make it harder to change password.
if you want to deny password copy from database you must create your own user model and update hashing algorithm like this.
first create a user model:
from django.contrib.auth.hashers import make_password, check_password
class MyUser(User):
def set_password(self, raw_password):
self.password = make_password(self.username + raw_password)
self._password = raw_password
def check_password(raw_password):
def setter(raw_password):
self.set_password(raw_password)
self._password = None
self.save(update_fields=['password'])
return check_password(self.username + raw_password, self.password. setter)
by these changes user password hashes are contain username and copy hash for other user does not works correctly

mongoDB: python code issue

could it be the wrong bottle version?
I lookeed in the sessionDAO file provided by the admins, and they do it the same as i do it;
the code:
def __init__(self, db):
self.db = db
self.users = self.db.users
self.SECRET = 'verysecret'
says:
[1] connect to the blog db
[2] select the users collection
and in the login code i have:
def validate_login(self, username, password):
user = None
try:
# XXX HW 2.3 Students Work Here
# you will need to retrieve right document from the users collection.
password = self.make_pw_hash(password)
user = self.users.find({"_id":username,"password":password})
I know self, username and password; it should be a simple find by document, as i wrote it; I now see that there might be a indentation problem, wich i can see it only on stackoverflow, in notepad++ it's not there;
and:
def add_user(self, username, password, email):
password_hash = self.make_pw_hash(password)
user = {'_id': username, 'password': password_hash}
if email != "":
user['email'] = email
try:
# XXX HW 2.3 Students work here
# You need to insert the user into the users collection.
# Don't over think this one, it's a straight forward insert.
self.users.insert(user)
I know self, username, password and email;
The document is prepared by default: user = {'_id': username, 'password': password_hash}
It should be a simple insert: self.users.insert(user)
Whenever you make any change to the source code, you need to restart the server for those changes to take effect.
Change the line
user = self.users.find({"_id":username,"password":password})
to
user = self.users.find_one({"_id":username})

Categories

Resources