pythonauthenticationpasswordsdatabase-connectioncx-oracle

Prompt user to retry password when unsuccessful in cx_Oracle connect method


I ma using the cx_Oracle module in python to connect and query an oracle database.

import cx_Oracle

I have built a tkinter widget so the user can be prompted for their username and password which, in turn, will get passed into the user/password portion of the connect method:

username = 'user'
password = 'password'
db = cx_Oracle.connect('{0}/{1}@//random.company:1234/db1.company.com'.format(username, password))

This all works well when the user inputs their correct username and password in the first try however when they don't, I need some logic to iteratively re-try their username and/or password.

The error that is thrown when the wrong credentials are entered is this:

cx_Oracle.DatabaseError: ORA-01017: invalid username/password; logon denied

I've been digging around the interweb for a while now and I can't really seem to find something that works for me. It seems like a lot of the things I've come across involves checking username and passwords against a known dictionary or something along those lines. I don't have the luxury of doing that. I'm probably at a point where I am over thinking this anyways, so I wanted to post up. I feel like it's just some sort of easy 'while' loop I need. Something like:

while connection_throws_error_:
    keep_trying_to_log_in

Here is my general code:

import Tkinter
from Tkinter import *
import cx_Oracle, pprint

master = Tk()
Label(master, text="Username").grid(row=0)
Label(master, text="Password").grid(row=1)

e1 = Entry(master)
e2 = Entry(master, fg = 'red', show="*")

e1.grid(row=0, column=1)
e2.grid(row=1, column=1)

Button(master, text='Login', command=master.quit).grid(row=3, column=1, sticky=W, pady=4)

master.title("MEMPRD Login")
master.mainloop()

# This is where I need to iteratively prompt user to enter crentials if they are incorrect.
db = cx_Oracle.connect('{0}/{1}@//random.company:1234/db1.company.com'.format(e1.get(), e2.get())

UPDATE

Thanks to Alex below, I've used his code, made a few customizations for my own use and it works. Here's the working code:

master = Tk()
Label(master, text="Username").grid(row=0)
Label(master, text="Password").grid(row=1)

e1 = Entry(master)
e2 = Entry(master, fg = 'red', show="*")

e1.grid(row=0, column=1)
e2.grid(row=1, column=1)

Button(master, text='Login', command=master.quit).grid(row=3, column=1, sticky=W, pady=4)
#Button(master, text='Show', command=show_entry_fields).grid(row=3, column=1, sticky=W, pady=4)



master.title("Login")
master.mainloop()

#show_entry_fields()



print e1.get()
print e2.get()

while True:
    try:
        db = cx_Oracle.connect('{0}/{1}@//random.company:1234/db1.company.com'.format(e1.get(), e2.get())
    except cx_Oracle.DatabaseError as e:
        error, = e.args
        if error.code == 1017:
            print('Please check your credentials.')
            e2.delete(0, 'end')
            master.mainloop()        
        else:        
            raise
    else:
        print 'success!'
        break

Solution

  • This is how it would look in a simple console application:

    while True:
        username = input('Username:')
        password = getpass('Password:')
        try:
            db = cx_Oracle.connect('{0}/{1}@//random.company:1234/db1.company.com'.format(username, password))
        except cx_Oracle.DatabaseError as e:
            # I'm guessing here, you will have to inspect the exception to decide
            # how to check what kind of error it is
            if 'username/password invalid' in e.message.lower(): 
                print('Invalid login')
            else:
                raise
        else:
            print('Success!')
            break
    

    I don't know how tkinter works so you will probably have to restructure it for that, but the point is to use try/except in a loop.