Ряд приложений, которые я пишу, требует, чтобы пользователь мог читать из файловой системы с KLOG аутентификацией. Некоторые функции требуют, чтобы у пользователя были токены KLOG (т.е. проходить аутентификацию), а другие - нет. Я написал небольшой Python-декоратор, чтобы я мог реорганизовать функциональность «вы должны быть KLOGed» в моих модулях:
# 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!)
Это все очень просто. За исключением случаев, когда я пытался применить следующую логику: «если пользователь не является KLOGed, запустите KLOG и запросите пароль».
Я делаю это, используя subprocess.Popen('klog')
, и приглашение password:
подходит к терминалу. Тем не менее, когда я пишу пароль, он на самом деле возвращается в терминал, и, что еще хуже, ничего не происходит при нажатии возврата.
Редактировать:
После быстрого и правильного ответа Алекса я решил проблему следующим образом:
- Я удалил все файлы
*.pyc
из каталога моего модуля (да - это имело значение)
- Я использовал
getpass.getpass()
для хранения пароля в локальной переменной
- Я вызвал команду KLOG с опцией
-pipe
- Я передал локально сохраненный пароль в канал с помощью метода
write
канала
Ниже приведен исправленный декоратор:
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