Handle authentication errors better.
[fulbank.git] / fulbank / auth.py
1 import sys, os, io, termios
2
3 class autherror(Exception):
4     pass
5
6 class conv(object):
7     msg_notice = 0
8     msg_info = 1
9     msg_debug = 2
10
11     def error(self, msg):
12         pass
13     def message(self, msg, level=0):
14         pass
15     def prompt(self, prompt, echo, default=None):
16         return default
17
18 class termconv(conv):
19     def __init__(self, ifp, ofp):
20         self.ifp = ifp
21         self.ofp = ofp
22
23     def error(self, msg):
24         self.ofp.write("%s\n" % (msg,))
25         self.ofp.flush()
26     def message(self, msg, level=0):
27         if level <= self.msg_info:
28             self.ofp.write("%s\n" % (msg,))
29             self.ofp.flush()
30     def prompt(self, prompt, echo, default=None):
31         if echo:
32             self.ofp.write(prompt)
33             self.ofp.flush()
34             ret = self.ifp.readline()
35             assert ret[-1] == '\n'
36             return ret[:-1]
37         else:
38             attr = termios.tcgetattr(self.ifp.fileno())
39             bka = list(attr)
40             try:
41                 attr[3] &= ~termios.ECHO
42                 termios.tcflush(self.ifp.fileno(), termios.TCIOFLUSH)
43                 termios.tcsetattr(self.ifp.fileno(), termios.TCSANOW, attr)
44                 self.ofp.write(prompt)
45                 self.ofp.flush()
46                 ret = self.ifp.readline()
47                 self.ofp.write("\n")
48                 assert ret[-1] == '\n'
49                 return ret[:-1]
50             finally:
51                 termios.tcsetattr(self.ifp.fileno(), termios.TCSANOW, bka)
52
53 class ctermconv(termconv):
54     def __init__(self, fp):
55         super().__init__(fp, fp)
56         self.cfp = fp
57
58     def close(self):
59         self.cfp.close()
60     def __enter__(self):
61         return self
62     def __exit__(self, *excinfo):
63         self.close()
64         return False
65
66 null = conv()
67 stdioconv = termconv(sys.stdin, sys.stdout)
68
69 def ttyconv():
70     return ctermconv(io.TextIOWrapper(io.FileIO(os.open("/dev/tty", os.O_RDWR | os.O_NOCTTY), "r+")))
71
72 def default():
73     return null