I'm using python 2.7.5 and i'm trying to make a simple program that has a username, password, and checks if it exists in a dictionary. If true, it prints welcome + username, and ignores if false.
First: code.
#!/usr/bin/python
import csv
users = {}
with open('C:\\Users\\chef\\Python\\fn.csv', 'wb') as f: # Just use 'w' mode in 3.x
w = csv.DictWriter(f, users.keys())
w.writeheader()
w.writerow(users)
def new_user():
uname = raw_input("Choose a username: ")
while 1:
pwd = raw_input("Choose a password: ")
check = raw_input("Retype password: ")
if pwd == check:
print "Saved."
users[uname] = pwd
break
if uname in users.keys():
pass
def show_users():
for unames in users.keys():
print unames
def login():
uname = raw_input("Username: ")
pwd = raw_input("Password: ")
if uname in users and pwd in users.values():
print "Welcome, " + uname + "! "
def save():
f=open('C:\\Users\\chef\\Python\\fn.csv', "wb")
w = csv.writer(f)
for key, val in users.items():
w.writerow([key, val])
f.close()
def read():
with open('C:\\Users\\chef\\Python\\fn.csv', 'wb') as f: # Just use 'w' mode in 3.x
w = csv.DictWriter(f, users.keys())
w.writeheader()
w.writerow(users)
print "Welcome to Yubin's 'fake' Email server."
while 1:
read()
choice = raw_input("What would you like to do? ")
if choice == "signup":
new_user()
if choice == "login":
login()
if choice == "showusers":
show_users()
if choice == "logout":
print "You have successfully logged out."
if choice == "quit":
x = raw_input("Are you sure? (y/n) ")
if x == "y":
save()
break
else:
pass
else:
print "Please sign up, log in or see who have signed up."
Problems:
When I first "sign up", i can log in perfectly fine. But, after closing the program and running it again, i can't log in. i assume it's because i set the dictionary empty every time i start, but it's supposed to rewrite the contents into the dictionary. i use windows 7 and in the preview, when i rerun the program, the file becomes empty.
After i write either login, signup or showusers, it prints the last line,
"Please sign up, log in or see who have signed up. "
Please i ask for solutions, and thank you in advance.
EDIT: I solved problem #2, but #1 still is there.
The problem is, as hyades stated, that your read-method overwrites the csv-file instead of reading it. The csv-module offers a reader for this purpose. I have changed your read-method like this to make it work:
def read():
with open('C:\\Users\\chef\\Python\\fn.csv', 'r') as f:
usersReader = csv.reader(f)
for row in usersReader:
if row == []:
pass
else:
users[row[0]] = row[1]
f.close();
You can also remove the "with open..."-code block at the begining of the file (after import and users-declaration).
For Problem 1, might be an issue with the mode of the file. Change it to wb+
Opens a file for both writing and reading in binary format. Overwrites
the existing file if the file exists. If the file does not exist,
creates a new file for reading and writing.
Problem 2 will be solved if you use if..elif instead of if
Check this code above. I use only save and read function. I used read function only once, outside while loop (used 'rb' mode istaed 'wb' mode). I used csv.WriteDict and csv.ReadDict classes enter link description here. to read and save data from users dict. I think You can use shelve or json instead csv, propobly these way will by faster and simply ;)
#!/usr/bin/python
import csv
users = {}
'''def write():
with open('/home/marcin/fn.csv', 'wb+') as f: # Just use 'w' mode in 3.x
w = csv.DictWriter(f, users.keys())
w.writeheader()
w.writerow(users)'''
def new_user():
uname = raw_input("Choose a username: ")
while 1:
pwd = raw_input("Choose a password: ")
check = raw_input("Retype password: ")
if pwd == check:
print "Saved."
users[uname] = pwd
break
if uname in users.keys():
pass
def show_users():
for unames in users.keys():
print unames
def login():
uname = raw_input("Username: ")
pwd = raw_input("Password: ")
if uname in users and pwd in users.values():
print "Welcome, " + uname + "! "
def save():
with open('/home/marcin/fn.csv', "wb+") as f:
fieldnames=['user','pwd']
writer = csv.DictWriter(f,fieldnames=fieldnames)
writer.writeheader()
for key, val in users.items():
writer.writerow({'user' : key, 'pwd' : val})
def read():
with open('/home/marcin/fn.csv','rb') as f: # Just use 'w' mode in 3.x
w = csv.DictReader(f)
for row in w:
print row
users[row['user']]=row['pwd']
def main():
print "Welcome to Yubin's 'fake' Email server."
try:
read()
except IOError:
pass
while 1:
choice = raw_input("What would you like to do? ")
if choice == "signup":
new_user()
save()
if choice == "login":
login()
if choice == "showusers":
show_users()
if choice == "logout":
print "You have successfully logged out."
if choice == "quit":
x = raw_input("Are you sure? (y/n) ")
if x == "y":
save()
break
else:
pass
else:
print "Please sign up, log in or see who have signed up."
if __name__ == "__main__":
main()
Related
I'm new to python, an I decided to write a simple password manager to learn. I'm having trouble retrieving one of the values out of the dictionary.
The function add_password write a key with 2 values (user, and password (encrypted))
And the function get_password read the key and supposed to get the values.
I can't get it to pull the value of user.
I have tried multiple methods, but so far no luck.
https://github.com/ae3erdion/Password_Manager/blob/main/main.py
import base64
import os
import string
import random
from unittest import TestCase
from cryptography.fernet import Fernet
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
characters = list(string.ascii_letters + string.digits + "!##$%^&*()")
site = ""
user = ""
password = ""
password_file = {}
encrypted = ""
# Generate key for encryption
def generate_key():
password = input ("Enter password: ")
password = bytes(password, 'utf-8')
salt = b'\xceN\x01s\xabE\x15\x02\xd9pz(1\t\xbc4'
kdf = PBKDF2HMAC(
algorithm=hashes.SHA256(),
length=32,
salt=salt,
iterations=390000,
)
global key
key = base64.urlsafe_b64encode(kdf.derive(password))
# Check for the encryption key hash file exists and validate if the key is the same
if os.path.exists('password.hash'):
with open('password.hash', 'rb') as f:
key_validation = f.read()
if key_validation == key:
print("What would you like to do: ")
menu()
else:
print("Wrong password ")
exit
# If key hash file doesnt exist it create the file and write the encryption key hash to it
else:
with open('password.hash', 'wb') as f:
f.write(key)
with open('password.encode', 'wb') as f:
print("What would you like to do: ")
menu()
# Randon password generator
def generate_password():
length = int(16)
random.shuffle(characters)
random_password = []
for i in range(length):
random_password.append(random.choice(characters))
random.shuffle(random_password)
random_password = ("".join(random_password))
print(random_password)
# Write a new password to the pasword file
def add_password(site, user, password_site):
password_file[site] = password_site
with open('password.encode', 'a+') as f:
encrypted = Fernet(key).encrypt(password_site.encode())
f.write(site + " " + user + ":" + encrypted.decode() + "\n")
# Read password file and get the password
def get_password(site):
with open('password.encode', 'r') as f:
for line in f:
site, encrypted = line. split (":")
password_file[site] = Fernet(key).decrypt(encrypted.encode()).decode()
return password_file[site]
# Check for all files.
def main():
if os.path.exists('password.hash') & os.path.exists('password.encode'):
print ("Welcome Back!")
generate_key()
else:
print ("""
Welcome!
Create password""")
generate_key()
# Menu of options
def menu():
print("""
(1) Generate random password
(2) Add new password
(3) Get login information
(q) Quit""")
done = False
while not done:
choice = input("Enter choice: ")
if choice == "1":
generate_password()
elif choice == "2":
site = input("Enter the site: ")
user = input("Enter User: ")
password = input("Enter the password: ")
add_password(site, user, password)
elif choice == "3":
site = input("Enter site: ")
print(f"Your login information for {site} is ({get_password(site)})")
elif choice == "q":
done = True
print("Bye!")
else:
print("Invalid Choice")
if __name__== "__main__":
main()
If you change you get_password function to:
def get_password(site):
with open('password.encode', 'r') as f:
for line in f:
site, encrypted = line.split (":")
site, user = site.split()
password_file[site] = (user, Fernet(key).decrypt(encrypted.encode()).decode())
return password_file[site]
and change option 3 in your menu function
elif choice == "3":
site = input("Enter site: ")
user, passwd = get_password(site)
print(f"Your login information for {user}#{site} is ({passwd})")
You will still want to implement some error checking but that should will at least get you started.
I am currently making a log in system which stores usernames and passwords in a text file.
This is my code:
import csv
Brugere = open("D:\Filer\Programmering/Profiles.txt","r+",newline="\n")
writer = csv.writer(Brugere, delimiter=",")
print("Welcome to the chat app!")
Brugernavn = "" //means username
Kodeord = "" // means password
def Signup(j,k):
print("Welcome to sign up!\n Please enter your Username")
j = input("")
if j not in Brugere:
print("Hello, " + j + ", please enter a password:")
k = input("")
line1 = [j,k]
writer.writerow(line1)
print("Great! Now you can sign in")
Signin(Brugernavn, Kodeord)
else:
print("Username already taken! try again")
Signup(Brugernavn, Kodeord)
def Signin(U,P):
print("Welcome to sign in!")
print("Do you already have an account?[y/n]")
ans = input("")
if ans == "n":
print("You will now be redirected to sign up")
Signup(Brugernavn, Kodeord)
elif ans == "y":
U = input("Username: ")
if U in Brugere:
P = input("Password: ")
print("WELCOME")
else:
print("Invalid username, try again")
Signin(Brugernavn, Kodeord)
else:
print("Please write 'y' or 'n'")
Signin(Brugernavn, Kodeord)
Signin(Brugernavn, Kodeord)
Brugere.close()
When I run it, the signup function works as it should, but when the signin function is called, it can't find the username and password from the text file. I think it's because they only get appended after the script is done running. However, 'Im not sure.
I've been struggling for a long time with this csv file thing. I want to have it like
this where each line is a list where I can find the username and password
I've heard people calling it "comma seperated values", however I have no idea how to do it.
TL;DR:
I suspect the simplest solution is:
...
if j not in brugere:
...
writer.writerow(line1)
brugere.flush() # Flush pending changes to file.
...
...
However, I've noticed a few things worthy of consideration:
Python help. You can get help on Python things within an interactive Python session:
python
> import csv
> help(csv)
CSV for this sort of usecase isn't a good idea. If it's production grade use a proper DB, if you're just playing around locally to get a feel for Python use a dict() and store as JSON. I.e.:
import json
username = "myuser"
password = "password"
filename = "data.json"
# Reads data. Requires file `data.json` to exist, with content `{}`.
with open(filename, "r") as data_stream:
data = json.load(data_stream)
if username in data:
print(f"User {username} exists.")
else:
data[username] = password # You'd usually hash and salt a password. It's a separate topic.
# Writes data to disk.
with open(filename, "w") as data_stream:
data_stream.write(json.dumps(data, indent=2)) # Makes it look pretty on disk.
Note that open() returns a stream wrapped in class io.TextIOWrapper (see python -c "import io; help(io.TextIOWrapper)"). It's basically an interface to get the data you want, not the data itself. Try open("test.txt").readlines() to actually read data from stream, for example. Note that streams are consumables.
When you call in on the stream Brugere you're calling the __contains__() dunder method on class io.TextIOWrapper which isn't implemented. But Python being Python it returns False (it's not meaningful).
The CSV interfaces are pretty straightforward:
import csv
filename = "test.txt"
f = open(filename, "w")
writer = csv.writer(f)
writer.write(["myuser", "password"])
# Flushes lines to file.
f.flush()
...
f.close()
Creating a CSV is as simple as writing a string with each value separated by a designated character, often a comma as the name implies. You don't really need the csv library for that.
Your Signup method would then look as follows:
def Signup(j,k):
print("Welcome to sign up!\n Please enter your Username")
j = input("")
if j not in Brugere:
print("Hello, " + j + ", please enter a password:")
k = input("")
line1 = [j,k]
# Write a string with a comma between the values
Brugere.write("{}, {}\n".format(j, k))
print("Great! Now you can sign in")
Signin(Brugernavn, Kodeord)
else:
print("Username already taken! try again")
Signup(Brugernavn, Kodeord)
With that being said, using CSVs to store operational data in a an application does not make all that much sense to me. Please see below for a modified version of signup using SQLite, which is much more robust and still simple to use:
import sqlite3
con = sqlite3.connect('brugere.db')
cur = con.cursor()
# Create a user table with bruger and kodeord
# I added an extra field for when the user was created as well
# which defaults to the date and time the user was created
cur.execute("""create table if not exists brugere
(brugernavn text,
kodeord text,
dato_oprettet TIMESTAMP DEFAULT CURRENT_TIMESTAMP)""")
con.close()
def signup():
con = sqlite3.connect('brugere.db')
cur = con.cursor()
with con:
print("Please enter your Username")
bruger = input()
cur.execute("select brugernavn from brugere where brugernavn =?", [bruger])
bruger_eksisterer = cur.fetchone()
if bruger_eksisterer:
print("Username already taken! Try again")
# Signup(Brugernavn, Kodeord)
else:
print("Hello, " + bruger + ", please enter a password:")
kodeord = input()
try:
cur.execute("insert into brugere (brugernavn, kodeord) values (?, ?)", (bruger, kodeord))
print("Great! Now you can sign in")
except sqlite3.Error as Err:
print("Couldn't add user.\nError: {}".format(Err))
# Signin(Brugernavn, Kodeord)
con.close()
signup()
Modifying the signin should be straighforward, but I'll leave that part up to you.
I'm currently learning python and I have a login system that uses a text file called "users" to store the usernames. I want to be able to update this file by reading the text line by line and appending it to an array in python. Then writing the array back into the text file to be appended into the array again the next time I open the program.
But right now, as each username is written in different lines, when I append it to my array it gives me:username = ['testing1\n', 'testing2']
this is my code:
import random
import operator
import shelve
import os
from os import system, name
import time
from time import sleep
users = []
password = []
def clear():
if name == 'nt':
_ = system('cls')
else:
print("thisisweird.")
# start of login system
def loggedOut():
status = input("Are you a registered user? y/n? Press q to quit ")
if status == "y":
oldUser()
elif status == "n":
newUser()
elif status == "q":
quit()
def loggedIn():
menu()
def newUser():
createLogin = input('Create a Username: ')
if createLogin in users:
print("\nUsername is taken")
else:
users.append(createLogin)
createPwd = input("Create a Password: ")
password.append(createPwd)
print("\nRegister successful\n")
loggedOut()
def oldUser():
login = input("Enter username: ")
pwd = input("Enter password:")
if login in users and users[login] == pwd:
print("\nWelcome,", login,"!")
loggedIn()
else:
print("\nUsername or Password invalid\n")
def quit():
print("Goodbye! The program will now exit")
os.remove('./users/login.txt')
f = open('./users/login.txt', 'w')
for ele in users:
f.write(ele+'\n')
f.close()
sleep(2)
clear()
exit()
#end of login system
def loginsys():
folder_check = os.path.isdir('./users')
if (folder_check == True):
file_check = os.path.isfile('./users/login.txt')
if (file_check == True):
f = open('./users/login.txt', 'r+')
f1 = f.readlines()
for ele in f1:
users.append(ele)
f.close()
print(users)
loggedOut()
else:
f = open('./users/login.txt', 'w')
f.write('')
f.close()
loggedOut()
else:
os.mkdir('./users')
loginsys()
def menu():
print("Hello World")
loginsys()
readlines() puts a newline at the end of every text line. You can use rstrip() to remove it:
f = open('./users/login.txt', 'r+')
f1 = f.readlines()
for ele in f1:
users.append(ele.rstrip())
I am trying to make a login system that is looped basically and whenever I try to enter the correct details that are even stored in the .csv file, it outputs as incorrect username/password no matter what I put. This code works for python 3.6 but I need it to work for python 3.2.3.
loop1 = False #for this bit of code (logging in)
loop2 = False #for next bit of code
while loop1 == False:
choice = input("Login/SignUp [TYPE 'L' OR 'S']: ").lower()
if choice == "l":
username = input("Username: ")
password = input("Password: ")
f = open("usernamepassword.csv","r")
for line in f:
details = line.split(",")
if username == details[0] and password == details[1]:
print("Welcome")
break
#this whole bit of code is meant to read from the csv and check if the login details are correct
else:
print("Username/Password [INCORRECT]")
Allow me to refactor your code:
def login(username, password):
with open("usernamepassword.csv", "r") as csv:
all_details =
[[attr.strip() for attr in line.split(",")]
for line in csv]
return any(
username == details[0]
and password == details[1]
for details in all_details)
def login_action():
username = input("Username: ")
password = input("Password: ")
if not login(username, password):
raise ValueError("Username/Password [INCORRECT]")
return True
_USER_ACTIONS = {
'l': login_action
}
def main():
while True:
choice = input("Login/SignUp [TYPE 'L' or 'S']: ").lower()
action = _USER_ACTIONS[choice]
try:
if action():
break
except Exception as err:
print(err.message)
I think your unexpected behavior comes from not stripping the values you get after splitting by ,
Solved by replacing:
if username == details[0] and password == details[1]:
With:
if username == details[0] and (password+"\n") == details[1]:
You may have a bug in line.split(','), try line.strip().split(',')
TL; DR: posted a proper solution there : https://github.com/cgte/stackoverflow-issues/tree/master/47207293-csv-dict
I'll stuff up my answer later if needed.
Furthermore you have a poor code design here, and find yourself debugging in the middle of a loop.
So first of all : load the data file, store content to a dict.
f = open("usernamepassword.csv","r")
for line in f:
details = line.split(",")
if username == details[0] and password == details[1]:
print("Welcome")
break
Should become
user_pass = {}
f = open("usernamepassword.csv","r")
for line in f:
user, password = line.strip().split(",")
user_pass[user] = password
f.close()
or better
with open("usernamepassword.csv","r") as f:
for line in f.readlines():
user, password = line.split().split(",")
user_pass[user] = password
eventually run python -i yourfile.py and type "user_pass" to see what is actually stored when correct go on further code.
Think of using the csv module : https://docs.python.org/3/library/csv.html
Then get username and password from input and check:
if login in user_pass and user_pass[login] = password:
# or better `if user_pass.get(login, None) == password:`
do_stuff()
I'm writing a program that will verify a username:
def user_login():
""" Login and create a username, maybe """
with open('username.txt', 'r') as f:
if f.readline() is "":
username = raw_input("First login, enter a username to use: ")
with open('username.txt', 'a+') as user:
user.write(username)
else:
login_id = raw_input("Enter username: ")
if login_id == str(f.readline()):
return True
else:
print "Invalid username."
return False
if __name__ == '__main__':
if user_login() is not True:
print "Failed to verify"
Everytime I run this it outputs the following:
Enter username: tperkins91
Invalid username.
Failed to verify
How do I compare user input to reading from a file?
Opening the same file again in another nested context is not a good idea. Instead, open the file once in append mode, and use f.seek(0) to return to the start whenever you need to:
def user_login():
""" Login and create a username, maybe """
with open('username.txt', 'a+') as f:
if f.readline() is "":
username = raw_input("First login, enter a username to use: ")
f.seek(0)
f.write(username)
# return True/False --> make the function return a bool in this branch
else:
login_id = raw_input("Enter username: ")
f.seek(0)
if login_id == f.readline():
return True
else:
print "Invalid username."
return False
if __name__ == '__main__':
if user_login() is not True:
print "Failed to verify"
Returning a bool value in the if branch is something you may want to consider so the return type of your function is consistent as bool, and not None as in the current case.
When you use readline() the first time the current file position is moved past the first record. A better way to find if the file is empty is to test it's size:
import os.path
import sys
def user_login():
fname = 'username.txt'
""" Login and create a username, maybe """
if os.path.getsize(fname) == 0:
with open(fname, 'w') as f:
username = raw_input("First login, enter a username to use: ")
f.write(username)
return True #/False --> make the function return a bool in this branch
else:
with open(fname, 'r') as f:
login_id = raw_input("Enter username: ")
if login_id == f.readline().rstrip():
return True
else:
print >>sys.stderr, "Invalid username."
return False
if __name__ == '__main__':
if user_login() is not True:
print "Failed to verify"
f.readline() will include a trailing newline, if there is one in the file, whereas raw_input() will not. While we don't explicitly write one, someone might edit the file and add a newline unintentionally, hence the addition of the rstrip() as a defensive precaution.