Hello:
A series of applications I'm writing require that the user be able to read from a filesystem with KLOG authentication. Some functions require the user to have KLOG tokens (i.e., be authenticated) and others don't. I wrote a small Python decorator so that I can refactor the "you must be KLOGed" functionality within my modules:
# this decorator is defined in ``mymodule.utils.decorators``
def require_klog(method):
def require_klog_wrapper(*args, **kwargs):
# run the ``tokens`` program to see if we have KLOG tokens
out = subprocess.Popen('tokens', stdout=subprocess.PIPE)
# the tokens (if any) are located in lines 4:n-1
tokens_list = out.stdout.readlines()[3:-1]
if tokens_list == []:
# this is where I launch KLOG (if the user is not authenticated)
subprocess.Popen('klog')
out = method(*args, **kwargs)
return out
return require_klog_wrapper
# once the decorator is defined, any function can use it as follows:
from mymodule.utils.decorators import require_klog
@require_klog
def my_function():
# do something (if not KLOGed, it SHUOLD ask for the password... but it does not!)
It is all very simple. Except when I tried to apply the following logic: "if the user is not KLOGed, run KLOG and ask for the password".
I do this using subprocess.Popen('klog')
and the password:
prompt does come up to the terminal. However, when I write the password it actually is echoed back to the terminal and, worse, nothing happens upon hitting return.
Edit:
After Alex's fast and correct response I solved the problem as follows:
- I erased all the
*.pyc
files from my module's directory (yes - this made a difference) - I used
getpass.getpass()
to store the password in a local variable - I called the KLOG command with the
-pipe
option - I passed the locally-stored password to the pipe via the pipe's
write
method
Below is the corrected decorator:
def require_klog(method):
def require_klog_wrapper(*args, **kwargs):
# run the ``tokens`` program to see if we have KLOG tokens
out = subprocess.Popen('tokens', stdout=subprocess.PIPE)
# the tokens (if any) are located in lines 4:n-1
tokens_list = out.stdout.readlines()[3:-1]
if tokens_list == []:
args = ['klog', '-pipe']
# this is the custom pwd prompt
pwd = getpass.getpass('Type in your AFS password: ')
pipe = subprocess.Popen(args, stdin=subprocess.PIPE)
# here is where the password is sent to the program
pipe.stdin.write(pwd)
return method(*args, **kwargs)
return require_klog_wrapper