1,105,644 Community Members

Tkinter password entry form

Member Avatar
Reputation Points: 818 [?]
Q&As Helped to Solve: 1,056 [?]
Skill Endorsements: 42 [?]
 
0
 

Inspired by password entry discussions, I did this simple entry. You must of course find safe way to store the passwords, for example hashlib (http://stackoverflow.com/questions/4820043/basics-of-python-encryption-w-hashlib-sha1) or PyCrypto and replace the simplistic example match for real life usage.

The print at line 23 is just to check the attempts and to see the text really was received correctly by the program.

try:
    import tkinter as tk
except ImportError:
    import Tkinter as tk
# from http://effbot.org/tkinterbook/entry.htm

failure_max = 3
passwords = [('DaniWeb', 'best1'), ('newbie', 'help!help!')]

def make_entry(parent, caption, width=None, **options):
    tk.Label(parent, text=caption).pack(side=tk.TOP)
    entry = tk.Entry(parent, **options)
    if width:
        entry.config(width=width)
    entry.pack(side=tk.TOP, padx=10, fill=tk.BOTH)
    return entry

def enter(event):
    check_password()

def check_password(failures=[]):
    """ Collect 1's for every failure and quit program in case of failure_max failures """
    print(user.get(), password.get())
    if (user.get(), password.get()) in passwords:
        root.destroy()
        print('Logged in')
        return
    failures.append(1)
    if sum(failures) >= failure_max:
        root.destroy()
        raise SystemExit('Unauthorized login attempt')
    else:
        root.title('Try again. Attempt %i/%i' % (sum(failures)+1, failure_max))
    

root = tk.Tk()
root.geometry('300x160')
root.title('Enter your information')
#frame for window margin
parent = tk.Frame(root, padx=10, pady=10)
parent.pack(fill=tk.BOTH, expand=True)
#entrys with not shown text
user = make_entry(parent, "User name:", 16, show='*')
password = make_entry(parent, "Password:", 16, show="*")
#button to attempt to login
b = tk.Button(parent, borderwidth=4, text="Login", width=10, pady=8, command=check_password)
b.pack(side=tk.BOTTOM)
password.bind('<Return>', enter)

user.focus_set()

parent.mainloop()
Member Avatar
Tony Veijalainen

Specialties:
IT/Science/Contracts/Religious translation/interpreting FIN-ENG-FIN
Python programming

Member Avatar
pyTony
pyMod
6,103 posts since Apr 2010
Reputation Points: 818 [?]
Q&As Helped to Solve: 1,056 [?]
Skill Endorsements: 42 [?]
Moderator
Featured
 
0
 

It looks like magic at first how keyword parameter with list value keeps its value across calls. Here is version of code which use 'function as object' and stores value as attribute of the function, and usage example (practically maybe it would be safer the code to be included in code itself and not used as module, but principle is same, and this is yet intrinsically unsafe as passwords are visible in source code.

try:
    import tkinter as tk
except ImportError:
    import Tkinter as tk
# from http://effbot.org/tkinterbook/entry.htm

failure_max = 3
passwords = [('DaniWeb', 'best1'), ('newbie', 'help!help!')]

def make_entry(parent, caption, width=None, **options):
    tk.Label(parent, text=caption).pack(side=tk.TOP)
    entry = tk.Entry(parent, **options)
    if width:
        entry.config(width=width)
    entry.pack(side=tk.TOP, padx=10, fill=tk.BOTH)
    return entry

def enter(event):
    check_password()

def check_password():
    """ Collect 1's for every failure and quit program in case of failure_max failures """
    #print(user.get(), password.get())
    if (user.get(), password.get()) in passwords:
        check_password.user = user.get()
        root.destroy()
        print('Logged in')
        return
    check_password.failures += 1
    if check_password.failures == failure_max:
        root.destroy()
        raise SystemExit('Unauthorized login attempt')
    else:
        root.title('Try again. Attempt %i/%i' % (check_password.failures + 1, failure_max))
check_password.failures = 0

root = tk.Tk()
root.geometry('300x160')
root.title('Enter your information')
#frame for window margin
parent = tk.Frame(root, padx=10, pady=10)
parent.pack(fill=tk.BOTH, expand=True)
#entrys with not shown text
user = make_entry(parent, "User name:", 16, show='*')
password = make_entry(parent, "Password:", 16, show="*")
#button to attempt to login
b = tk.Button(parent, borderwidth=4, text="Login", width=10, pady=8, command=check_password)
b.pack(side=tk.BOTTOM)
password.bind('<Return>', enter)

user.focus_set()

parent.mainloop()

Usage assuming that above code can be found by import as tkPasswd

import time

try:
    import tk_passwd
except SystemExit as e:
    print(e)
else:   
    user = tk_passwd.check_password.user
    print('Welcome to IRS Tax Database, %s!' % user)
    time.sleep(4)
    print('Just kidding!')
Member Avatar
Enalicho
Junior Poster in Training
62 posts since Aug 2011
Reputation Points: 14 [?]
Q&As Helped to Solve: 13 [?]
Skill Endorsements: 0 [?]
 
0
 

As a note, you probably wouldn't want to hide the user field, and use a class, but a good simple example for people to use.

Member Avatar
pyTony
pyMod
6,103 posts since Apr 2010
Reputation Points: 818 [?]
Q&As Helped to Solve: 1,056 [?]
Skill Endorsements: 42 [?]
Moderator
Featured
 
0
 

You can choose your way but knowing username is making breaking easier. For example internet service of my bank is hiding both user code and single use pin number.

Member Avatar
Enalicho
Junior Poster in Training
62 posts since Aug 2011
Reputation Points: 14 [?]
Q&As Helped to Solve: 13 [?]
Skill Endorsements: 0 [?]
 
0
 

You can choose your way but knowing username is making breaking easier. For example internet service of my bank is hiding both user code and single use pin number.

Just making them stars does very little but providing the *allusion* of protection :) Encrypting them, however, will help (provide it's done correctly)

You
Post:
Start New Discussion
View similar articles that have also been tagged: