Python- Reading back usernames and passwords into a program to authenticate - python

I am currently writing a program in Python that asks if you have a log in. If no, they proceed to create a username and password. If yes, they log in and their details are checked against a text file. The text file looks like this (Username then password):
whitehallj27
EXpass%20
Username2
EXPASSWORD%%%
james_27
password1234
I am trying to figure out a way of programming this as simply as possible. It seems to work, but isn't nearly as simple and doesn't really work how I thought it would. Here is the code snippet:
logins={}
usernames_passwords=open("UsernamesAndPasswords.txt","r")
count=0
for line in usernames_passwords:
count=count+1
count=count/2
usernames_passwords.close()
usernames_passwords=open("UsernamesAndPasswords.txt","r")
try:
for x in range(count):
username=usernames_passwords.readline()
password=usernames_passwords.readline()
logins[username]=password
except TypeError:
count=int(count+0.5)
for x in range(count):
username=usernames_passwords.readline()
password=usernames_passwords.readline()
logins[username]=password
usernames_passwords.close()
print(logins)
Also, how would I go about authenticating the username and password to check it's correct.
Many thanks,
James Duxbury

Assuming that variables user and passwd have the username and password provided by the user, then just read the file in two lines:
file_contents = []
with open("UsernamesAndPasswords.txt","r") as f: #use "with", it will auotamtically close the file
file_contents = f.readlines()
usernames = file_contents[0::2] #step by 2, take all elements starting at index 0
passwords = file_contents[1::2] #step by 2, take all elements starting at index 1
found_at_index = -1
for i in range(0,len(usernames)):
if user == usernames[i] and passwd == passwrods[i]:
found_at_index = i
break
if found_at_index >= 0 :
#do whatever you want, there is match
else:
#I don't know what you wanted to do in this case
Please read this for the with keyword and this for how to read a file nicelly.
Also this about the [::] syntax.

You could create a dictionary with the user names and passwords like this:
dict = {
'user-name': 'password-hashing',
'another-user': 'another-password'
}
after you've done it you can save this dict in a json file, and load its content when the user asks for login.
the docs for handling json files with python: https://docs.python.org/3/library/json.html
obs.: it will look simpler, but its not the best way of doing this king of thing

Related

How do I add user input to a list and able to see it?

I am trying to make a sign up system in python 3.7 but I don't know how to permanently add a users login to a list and not having to sign up for the same account every time you open the program.
I was not able to make up a solution to this problem.
Usernames = ['User1', 'User2']
Passwords = ['password123', 'password123']
print('Type SU to Sign Up or type LI to Log In!')
UOption = input('Option>> ')
if UOption == 'SU':
SI = True
LI = False
if SI == True:
print('Signing Up!')
SUUsername = input('Username>> ')
SUEmail = input('Email>> ')
SUPassword = input('Password>> ')
Usernames.append(SUUsername)
Emails.append(SUEmail)
Passwords.append(SUPassword)
LI = True
SI = False
I am expecting when I get this working that the user will be able to sign up once then be able to log in if they reopen the program without having to sign up again.
You could use the pickle module:
Firstly, to create the necessary files, run the following code in the folder that your program is saved in:
import pickle
pickle.dump([],open("usernames.dat","wb"))
pickle.dump([],open("emails.dat","wb"))
pickle.dump([],open("passwords.dat","wb"))
In your program, add:
import pickle
at the start of the program
Replace the lines:
Usernames = ['User1', 'User2']
Emails = ['Email1', 'Email2'] # I'm assuming this line has just been missed off your question
Passwords = ['password123', 'password123']
With:
Usernames = pickle.load(open("usernames.dat","rb"))
Emails = pickle.load(open("emails.dat","rb"))
Passwords = pickle.load(open("passwords.dat","rb"))
To read from the files
And finally add these lines at the end of your program to update the files with the new user's details
pickle.dump(Usernames,open("usernames.dat","wb"))
pickle.dump(Emails,open("emails.dat","wb"))
pickle.dump(Passwords,open("passwords.dat","wb"))
This is a link to more details on how to use pickles, if your interested
https://www.tutorialspoint.com/python-pickling
For source code including these edits see here:
https://pastebin.com/H4ryP6cT

Check variable against specific line in a text file | Python 3.6.x

Pretend I am making an email script. The user has already made a username and password, which has been stored in a text file so they can log in later at anytime.
The user needs to be able to log in. I want python to check that the users input matches the information in the text file from earlier, on their corresponding line. Capitalization doesn't matter.
The text file that was created initially reads:
johncitizen
johnspassword
My python script should read something like:
##Reads text file
guessusername = input('What is your username? ')
guesspassword = input('What is your password? ')
if guessusername.lower() = lines[0] and guesspassword = lines[1]:
##Grant access
I don't mind if capitalization is wrong, as long as the string itself matches up
Before first of all, what you are doing with plain text password storage is ill-advised. You should be using hashing+salting, or even better, pick a decent framework to work in and learn from how they do it.
First of all, your data storage format should be more record like:
user_id<tab>username<tab>password
user_id<tab>username<tab>password
user_id<tab>username<tab>password
In that case, you are able to read the file like this:
username = ... #user input
password = ... #user input
found_user_id = None
with open('pass.txt', 'rt') as f:
for line in f:
fields = line.split("\t")
if fields[1] == username and fields[2] == password:
found_user_id = fields[0]
break
#okay, here if found_user_id is not None, then you have found them
#if it is None, then you did not find them.
Truly, a database is much more useful than a text file, but this is how it works!

Why doesn't my code read this line?

so I made a program that reads usernames with passwords (which are salted and hashed) from an SFTP server, and the user can log in securely. Users can also make their own accounts, but I am having a problem with the checking if the username already exists. I have managed to write the code correctly, but for some strange reason I can't find out why my code won't read one for loop, at least it doesn't print the "debug" string, example below. Any help would be appreciated!
def createUser():
f = ftp.open("paroolid.txt", "a+")
passListDecode = f.read().decode("UTF-8")
passList = passListDecode.splitlines()
newName = input("Uus kasutajanimi: ")
if len(newName) <= 0:
print("Nimi peab olema vähemalt 1 täht!")
createUser()
#This is the loop that won't be read
for line in passList:
print("debug")
pp = ""
pp += line.split(",")[1].strip().split("-")[0].strip()
pp += newName
userInFile = hashlib.md5(pp.strip().encode()).hexdigest()
if userInFile == line.split(":")[0].strip():
print("Nimi juba olemas!")
createUser()
#But this line is read successfully, like the above for loop is just being skipped.
newPass = getpass.getpass("Uus parool: ")
Everyone, I got it fixed.
I learned that you cannot use the read() function when you're using the "a+" mode while opening a file, you'll need to use seek(0).
With that the problem is answered, thanks to Mike Scotty for suggesting that the list might be empty, I didn't think of that before.

Program not working correctly (using Python) - Login Program

This is my code:
users = []
users.append([username, password])
usersFile = open("users.txt","w+")
for users in users:
usersFile.write("%s" % users)
usersFile.close()
def loginFunction():
userEntry = ""
foundName = 0
while userEntry == "":
userEntry = raw_input("Enter your username: ")
usersFile = open("users.txt", "r")
lines = usersFile.readlines()
usersLen = len(users)
for index in range (0, usersLen-1):
if userEntry == users[index, 0]:
foundName = 1
passwordEntry = raw_input("Enter your password: ")
if passwordEntry == users[index, 1]:
print "Username and passwords are correct"
else:
print "incorrect"
userEntry = ""
if foundName == 0:
print "Username not recognised"
userEntry = ""
I have produced a program that registers the username and password of a user. I have checked the files and it saves the username and password successfully but when I try to login using the correct username that I know is in the file as a list, it still always comes up "Username not recognised". Any ideas as to why this might be?
It looks like you're writing out the user/passwords, as lists, as single lines in the file. Then when you read it back, each pair is read back as one string. readlines() doesn't automatically convert text back to a list object. If you want to do that, you might use Pickle instead. Pickle should let you save the entire users list of lists object all at once.
Also to be pythonic your for loop should iterate over the list directly. If you need the current index, use for i, user in enumerate(users). Using range(len(users)) is suboptimal in python. You can then use user[0] to get the username and user[1] for the password.
I've made a few changes to your program. Firstly, I've changed it to use the modern print function instead of the print statement. The print function is available in Python 2.6 and later. It's more powerful than the old print statement, and IMHO it's a good idea to start using it in preparation for Python 3 (which doesn't have the print statement).
To simplify reading & writing the username & password data we can use the standard csv module. It's not strictly necessary for this simple task, but it means we don't have to worry about the messy details of parsing the name and password strings. Eg, if the strings contain spaces or quotes, the csv will handle them correctly. Note that in Python 2 CSV files must be opened in binary mode, but in Python 3 they must be opened in text mode. This is rather annoying when you're trying to write code that runs correctly on both versions.
The easy way to look up a password given the username is to use a dictionary with the username as the key and the password as the value. This is much more efficient than scanning through a list row by row looking for a match.
Of course, in a real program we would never store passwords as plain text. That's extremely insecure! The usual procedure is to store a hashed version of the password, using a strong cryptographic hash function applied a very large number of times to make it a time-consuming operation. For further info please see PBKDF2, scrypt, and bcrypt.
Also, it's bad practice to let a potential attacker know that a username is valid but that the password they submitted is invalid. That allows them to easily build a list of valid usernames. Instead, you should always ask for the password, even if the username is invalid.
from __future__ import print_function
import csv
users = [
['Alice', 'aardvark'],
['Bob', 'bobcat'],
['Steve', 'swordfish'],
]
# Save the users list to a CSV file
users_filename = "users.txt"
with open(users_filename, "wb") as f:
writer = csv.writer(f)
writer.writerows(users)
def login_function():
# Load the usernames & passwords into a dictionary
with open(users_filename, "rb") as f:
users = dict(csv.reader(f))
# Give the user 3 chances to login
for i in range(2, -1, -1):
user_entry = raw_input("Enter your username: ")
password_entry = raw_input("Enter your password: ")
if user_entry in users and password_entry == users[user_entry]:
print("Username and password are correct")
return True
else:
print("Username and password are invalid")
print(i, "login attempts remaining")
print("Login failed")
return False
print(login_function())
demo
Enter your username: Alan
Enter your password: runner
Username and password are invalid
2 login attempts remaining
Enter your username: Alice
Enter your password: aardvark
Username and password are correct
True

Username and Password login

I'd like to create a Login in which will open a text/csv file read the "Valid" usernames and passwords from the file and then if whatever the user has added has matched what was in the file then it will allow access to the rest of the program
How would i integrate the code below into one of which opens a file reads valid usernames and passwords and checks it against the users input
Currently i have something which works but there is only one password which i have set in the code.
Password = StringVar()
Username = StringVar()
def EnterPassword():
file = open('Logins.txt', 'w') #Text file i am using
with open('Logins.txt') as file:
data = file.read() #data=current text in text file
UsernameAttempt = Username.get()#how to get value from entry box
PasswordAttempt = Password.get()#how to get value from entry box
if PasswordAttempt == '' and UsernameAttempt == '':
self.delete()
Landlord = LandlordMenu()
else:
PasswordError = messagebox.showerror('Password/Username Entry','Incorrect Username or Password entered.\n Please try again.')
PasswordButton = Button(self.GenericGui,text = 'Landlord Section',height = 3, width = 15, command = EnterPassword, font = ('TkDefaultFont',14),relief=RAISED).place(x=60,y=175)
Some assistance would be appreciated
Please have a look at some documentation. Your question in "Coding Comments" -> #how to get value from entry box is easy to be solved using official documentation.
For reading files there is also official documentation on strings and file operations (reading file line by line into string, using string.split(';') to get arrays instead of row-strings).
Please do read documentation before writing applications. You do not need to know the complete API of all python modules but where to look. It is very exhausting to be dependent on other users / developers when there is no actual need for it (as there is very detailed documentation and tons of howtows for that kind of stuff).
This is not meant to be offensive but to show you how easy you can get documentation. Both results where first-results from a search engine. (ddg)
Please keep in mind that SO is neither a code writing service nor a let-me-google-that-for-you forum.

Categories