0

I want to make a login system with a username and password for each user. How do I save their data when they login? I don't know how to do it using .csv and don't wanna get into any of that SQL business as this is for a school project and I have a very limited deadline.

Here is a snippet from my code:

import getpass

#Function to add new users, still don't know how I'll save it. grrrrr!
def signUp()
 print("\nTo make a new account you must create your own unique username and password\n\n***\n\n")
 while True:    
  newUsername = str(input("Enter your username:\n"))
  newPassword = getpass.getpass(prompt = "Enter your password: ", stream = None)
  passConfirm = getpass.getpass(prompt = "Confirm your password: ", stream = None)

  if passConfirm == newPassword:
    print("\n Great! Your data has been confirmed and will now be saved to the database. To play the game restart the program then login.")
    #Here the user data should be saved some way that makes sure it is not deleted and can be retrieved when restarting program
 else:
    print("Please re-enter your credentials.")  

2 Answers2

1

If you have 0 security concern you could just store the data as json file. Everything is explained there if you want to use json.

Create a dictionary and store it in a file like this:

import json
credentials = {"username1": "password1", "username2": "password2"} #and so on

with open('data.json', 'w') as fp:
    json.dump(credentials, fp)

Then to open this file and extract the dictionary use:

with open('data.json', 'r') as fp:
    credentials = json.load(fp)

And you can access any password using a username like this:

password = credentials[username]

json is a built-in library so no compatibility issue and probably correct for your teacher.

Jao
  • 558
  • 2
  • 12
1

I programmed it with ALL the security because you shall do thing right from the start.

Here the code:

import getpass
import hashlib
import sqlite3
import os
# init new db
try:
    os.mkdir("./saves")
except FileExistsError: pass
con = sqlite3.connect('saves/db.sqlite')
cur = con.cursor()
try:
    cur.execute('''CREATE TABLE auth
        (username text, password text, salt text)''')
except: pass
con.commit()
con.close()

# static Password Salt: appendet to each password before hashing, from os.urandom(64)
static_passwd_salt = b'%\x89\x08-\x82\xb9\xdf\x07\xbd\xbb\x88]\xa2q\x08\x90\xfb\x97\xa7R\xd5\xfc\xfda\x8b\xdd\xcb\x1c\x00\x84\x0e\xdc\xc4\xc0|1\x02-\xb0y\xff`0!gn\xa7\xdf)=\xba.w\x9f\x0b\x9a\xe6n\x9c\xa6\xc5S\xa0\xa0'

# return user or not found
def Query_user(user):
    con = sqlite3.connect('saves/db.sqlite')
    cur = con.cursor()
    db = [i for i in cur.execute("SELECT * FROM auth")]
    dbpasswd_hash = None
    for i in range(len(db)):
        if db[i][0] == user:
            return db[i]
    return "nf"
    
# Initialising peppers against bruteforce attacks
peppers = []
for i in range(256):
    peppers.append(chr(i))
# generate a random pepper for new user
def rand_pepper():
    bits = bin(ord(os.urandom(1))).replace("0b", "")
    while len(bits) <= 7:
        bits += "0"
    return peppers[int(bits, 2)]
    
# Check password of user
def check_passwd(user, raw_passwd):     
    uq = Query_user(user)
    if uq == "nf":
        return "nf"
    dbpasswd_hash = uq[1]
    usersalt = uq[2]
    for i in peppers:
        passwd = raw_passwd + i
        if hashlib.scrypt(password=passwd.encode("UTF-8"), salt=static_passwd_salt+usersalt, n=16, r=16, p=16).hex() == dbpasswd_hash:
            return True
    return False
#Function to add new users
def signUp():
    print("\nTo make a new account you must create your own unique username and password\n\n***\n\n")
    cont = True
    while cont:    
        newUsername = str(input("Enter your username:\n"))
        newPassword = getpass.getpass(prompt = "Enter your password: ", stream = None)
        passConfirm = getpass.getpass(prompt = "Confirm your password: ", stream = None)

        if passConfirm == newPassword:
            print("\n Great! Your data has been confirmed and will now be saved to the database. To play the game restart the program then login.")
            con = sqlite3.connect('saves/db.sqlite')
            otsalt = os.urandom(63)
            passwd = newPassword + rand_pepper()
            cur = con.cursor()
            if Query_user(newUsername) == "nf":
                cur.execute("INSERT INTO auth VALUES (:user, :passwd, :salt)", {"user":newUsername, "passwd":hashlib.scrypt(password=passwd.encode("UTF-8"), salt=static_passwd_salt + otsalt, n=16, r=16, p=16).hex(), "salt":otsalt})
            else:
                print("User already exists")
            con.commit()
            con.close()
            cont = False
        else:
            print("Please re-enter your credentials.")  
            
# log the user in            
def LogIn():
    Username = str(input("Username:\n\n"))
    if Query_user(Username) == "nf":
        print("That User doesn't exist")
    else:
        Password = getpass.getpass(prompt = "Enter your password: ", stream = None)
        if check_passwd(Username, Password) == True:
            print("You're logged in")
        else:
            print("Incorrect Password")

#signUp()
#LogIn()

Or WITHOUT any security (use at own risk):

import getpass
import sqlite3
import os
# init new db
try:
    os.mkdir("./saves")
except FileExistsError: pass
con = sqlite3.connect('saves/db.sqlite')
cur = con.cursor()
try:
    cur.execute('''CREATE TABLE auth
        (username text, password text)''')
except: pass
con.commit()
con.close()
def Query_user(user):
    con = sqlite3.connect('saves/db.sqlite')
    cur = con.cursor()
    db = [i for i in cur.execute("SELECT * FROM auth")]
    for i in range(len(db)):
        if db[i][0] == user:
            return db[i]
    return "nf"
def check_passwd(user, raw_passwd):     
    uq = Query_user(user)
    if uq == "nf":
        return "nf"
    passwd = uq[1]
    if raw_passwd == passwd:
        return True
    return False
#Function to add new users
def signUp():
    print("\nTo make a new account you must create your own unique username and password\n\n***\n\n")
    cont = True
    while cont:    
        newUsername = str(input("Enter your username:\n"))
        newPassword = getpass.getpass(prompt = "Enter your password: ", stream = None)
        passConfirm = getpass.getpass(prompt = "Confirm your password: ", stream = None)

        if passConfirm == newPassword:
            print("\n Great! Your data has been confirmed and will now be saved to the database. To play the game restart the program then login.")
            con = sqlite3.connect('saves/db.sqlite')
            cur = con.cursor()
            if Query_user(newUsername) == "nf":
                cur.execute("INSERT INTO auth VALUES (:user, :passwd)", {"user":newUsername, "passwd":newPassword})
            else:
                print("User already exists")
            con.commit()
            con.close()
            cont = False
        else:
            print("Please re-enter your credentials.")  
            
# log the user in            
def LogIn():
    Username = str(input("Username:\n\n"))
    if Query_user(Username) == "nf":
        print("That User doesn't exist")
    else:
        Password = getpass.getpass(prompt = "Enter your password: ", stream = None)
        if check_passwd(Username, Password) == True:
            print("You're logged in")
        else:
            print("Incorrect Password")

#signUp()
#LogIn()

And SQL isn't that bad is it?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
awdr
  • 64
  • 1
  • 8