1

This is my python password system using pickle. It's bad, I know, but it's my first time with pickle.

import pickle
import os

userlist = {'user1':'userpass1', 'user2':'userpass2'}

users = open ("users.pkl", 'wb')

pickle.dump (userlist, users)

username = input ("Enter your username: ")
password = input ("Enter your password: ")

if (username in userlist) and (password == userlist[username]):
    print ("Access Granted")
else:
   newaccount = input ("User not found. Shall I create a new account? ")
    if newaccount == "yes":
       username = input ("Please enter your username: ")
       password = input ("Please enter yout password: ")
       userlist.update({username:password})
       pickle.dump (userlist, users)
       users.close()

My problem is that, whenever I go to add a new account, using this part:

 newaccount = input ("User not found. Shall I create a new account? ")
    if newaccount == "yes":
        username = input ("Please enter your username: ")
        password = input ("Please enter yout password: ")
        userlist.update({username:password})
        pickle.dump (userlist, users)
        users.close()

It seems to add it (and it looks like it's there in the pickle file using notepad) but, I restart the python file, and it does not see it.

I believe it is something to do with this part:

userlist = {'user1':'userpass1', 'user2':'userpass2'}

users = open ("users.pkl", 'wb')

pickle.dump (userlist, users)

Any help is appreciated! :D

Bob
  • 13
  • 6
  • 2
    passwords belong to a very special category. Even simple things should be done differently with passwords e.g., don't store them in plain text, don't hardcode passwords in the source code. – jfs Feb 24 '15 at 11:14
  • I know, but this is for school - not necessary. – Bob Feb 25 '15 at 10:49

1 Answers1

2

You overwrite each time you run the program with w:

users = open ("users.pkl", 'wb')

If you wanted to get the previously pickled items you would need to see if the file already exists and pickle.load to get the previously pickled items and then dump at the end of your code.

Something like the following:

from tempfile import NamedTemporaryFile

try:
    # see if we have run  this before
    with  open ("users.pkl", 'rb') as users:
       users_dict = pickle.load(users)
except IOError:
    # if not set to defualt
    users_dict = {'user1':'userpass1', 'user2':'userpass2'}


username = input ("Enter your username: ")
password = input ("Enter your password: ")

if users_dict.get(username) == password: # unless a password can be None we can use get
    print ("Access Granted")
else:
    newaccount = input("User not found. Shall I create a new account? ")
    if newaccount == "yes":
       username = input("Please enter your username: ")
       password = input ("Please enter yout password: ")
       users_dict[username] = password # just use key = value

with NamedTemporaryFile("wb",dir=os.path.dirname("users.pkl"),delete=False) as f: # in case we get exception use temp file
    pickle.dump (users_dict, f)
os.replace(f.name,"users.pkl") # update original
Padraic Cunningham
  • 176,452
  • 29
  • 245
  • 321
  • you can't write to a file that is opened using `rb` mode. – jfs Feb 24 '15 at 11:10
  • you should probably use `with`-statement for the `users` file too (I don't know whether you can open an already opened file on Windows). Write to a temporary file and use `os.replace()` at the end -- otherwise the password database will be lost if an error occurs during `pickle.dump`. It won't help if multiple instances of this program may run simultaneously or if [the power is lost suddenly](http://stackoverflow.com/q/2333872/4279) – jfs Feb 24 '15 at 11:24
  • @J.F.Sebastian, yes, I thought I had closed the original file but using with is probably better anyway. – Padraic Cunningham Feb 24 '15 at 11:34
  • I meant [`tempfile.NamedTemporaryFile`](http://stackoverflow.com/a/28522826/4279) (note: it is important to set `dir`). – jfs Feb 24 '15 at 11:43