def iter_userlist(): handles = sorted(list_users(), key=unicode.lower) timenow = time.time() return (user_record(handle=user.handle, location=user.location, timeago=timenow - user.lastcall) for user in (get_user(handle) for handle in handles))
def lc_retrieve(): """ Returns tuple of ([nicknames,] u'text'), where 'text' describes in Ansi color the last callers to the system, and 'nicknames' is simply a list of last callers (for lightbar selection key). """ # pylint: disable=R0914 # Too many local variables from x84.bbs import list_users, get_user, ini, timeago, getterminal import time term = getterminal() udb = dict() for handle in list_users(): user = get_user(handle) udb[(user.lastcall, handle)] = (user.calls, user.location) padd_handle = (ini.CFG.getint('nua', 'max_user') + 2) padd_origin = (ini.CFG.getint('nua', 'max_location') + 2) rstr = u'' nicks = [] for ((tm_lc, handle), (_nc, origin)) in (reversed(sorted(udb.items()))): is_sysop = 'sysop' in get_user(handle).groups rstr += (term.bold_red(u'@') if is_sysop else u'' ) + (handle.ljust(padd_handle - (2 if is_sysop else 1))) rstr += term.red(origin.ljust(padd_origin)) rstr += timeago(time.time() - tm_lc) rstr += u'\n' nicks.append(handle) return (nicks, rstr.rstrip())
def prompt_recipient(term, msg, colors, public=True): """ Prompt for recipient of message. """ xpos = max(0, (term.width // 2) - (80 // 2)) echo(term.move_x(xpos) + term.clear_eos) echo(u'Enter handle{0}.\r\n'.format( u', empty to address to all' if public else u'')) echo(term.move_x(xpos) + ':: ') inp = LineEditor(username_max_length, msg.recipient, colors={ 'highlight': colors['backlight'] }).read() if inp is None: echo(u''.join((term.move_x(xpos), colors['highlight']('Canceled.'), term.clear_eol))) term.inkey(1) return False elif not inp.strip(): # empty, recipient is None msg.recipient = None if public: return True return False inp = inp.strip() # validate/find user userlist = list_users() if inp in userlist: # exact match, msg.recipient = inp echo(u'\r\n') return True # nearest match for match in difflib.get_close_matches(inp.strip(), userlist): echo(u''.join( (term.move_x(xpos), u'{0} [yn]'.format(colors['highlight'](match)), term.clear_eol, u' ?\b\b'))) while True: inp = term.inkey() if inp.code == term.KEY_ESCAPE: # escape/cancel return False elif inp.lower() == u'y': # accept match msg.recipient = match echo(u'\r\n') return True elif inp.lower() == u'n': # next match break echo(u''.join( (term.move_x(xpos), colors['highlight']('No match.'), term.clear_eol))) term.inkey(1) return False
def prompt_recipient(msg): """ Prompt for recipient of message. """ # pylint: disable=R0914 # Too many local variables from x84.bbs import getterminal, LineEditor, echo, ini, list_users from x84.bbs import Selector import difflib term = getterminal() echo(u"ENtER %s, OR '%s' tO AddRESS All. %s to exit" % ( term.bold_yellow(u'hANdlE'), term.bold_yellow(u'None'), term.bold_yellow_underline('Escape'),)) echo(u'\r\n\r\n') max_user = ini.CFG.getint('nua', 'max_user') lne = LineEditor(max_user, msg.recipient or u'None') lne.highlight = term.yellow_reverse echo(term.clear_eol + u' RECiPiENt: ') recipient = lne.read() if recipient is None or lne.quit: return False userlist = list_users() if recipient in userlist: msg.recipient = recipient return True elif len(recipient) != 0 and recipient != 'None': for match in difflib.get_close_matches(recipient, userlist): blurb = u'did YOU MEAN: %s ?' % (match,) inp = Selector(yloc=term.height - 1, xloc=term.width - 22, width=20, left=u'YES', right=u'NO') echo(u''.join(( u'\r\n', term.move(inp.yloc, inp.xloc - len(blurb)), term.clear_eol, term.bold_yellow(blurb)))) selection = inp.read() echo(term.move(inp.yloc, 0) + term.clear_eol) if selection == u'YES': msg.recipient = match return True if selection is None or inp.quit: return False else: blurb = u' NO RECiPiENT; POSt tO PUbliC? ' inp = Selector(yloc=term.height - 1, xloc=term.width - 22, width=20, left=u'YES', right=u'NO') echo(u''.join(( u'\r\n', term.move(inp.yloc, inp.xloc - len(blurb)), term.clear_eol, term.bold_yellow(blurb)))) selection = inp.read() echo(term.move(inp.yloc, 0) + term.clear_eol) if selection == u'YES': msg.recipient = None return True
def iter_userlist(): handles = sorted(list_users(), key=unicode.lower) timenow = time.time() user_record = collections.namedtuple('userlist', [ 'handle', 'location', 'timeago']) return (user_record(handle=user.handle, location=user.location, timeago=timenow - user.lastcall) for user in (get_user(handle) for handle in handles))
def migrate_105lc(): # migrating lastcallers database for 1.0.5 upgrade from x84.bbs import echo, DBProxy, list_users, get_user lc = DBProxy('lastcalls') for handle in list_users(): user = get_user(handle) lc[(handle)] = (user.lastcall, user.calls, user.location) echo(u'\r\n' + user.handle + '.') echo('\r\n\r\nlast callers db rebuilt!')
def locate_user(term, point): """ Prompt for search pattern and return discovered User. """ _color1, _color2, _color3 = [ getattr(term, _color) for _color in (color_lowlight, color_highlight, color_field_edit) ] # show help width = term.width - (point.x * 2) help_txt = (u'Enter username or glob pattern. Press escape to cancel.') y_offset = 0 for y_offset, txt in enumerate(term.wrap(help_txt, width=width)): echo(term.move(point.y + y_offset, point.x)) echo(_color1(txt) + term.clear_eol) point_prompt = Point(y=point.y + y_offset + 2, x=point.x) editor = LineEditor(nua.username_max_length, colors={'highlight': _color3}) while True: # prompt for handle echo(term.move(*point_prompt)) echo(u'handle: ' + term.clear_eol) inp = editor.read() point = Point(y=point_prompt.y + 2, x=point.x) if inp is None: # canceled (escape) return elif u'*' in inp or u'?' in inp: # a glob pattern, fetch all usernames handles = fnmatch.filter(list_users(), inp) if len(handles) == 0: echo(u''.join((term.move(*point), u'No matches for {0}.'.format(_color2(inp)), term.clear_eos))) elif len(handles) == 1: return get_user(handles[0]) else: matches_text = ( u'{0} accounts matched, chose one: {1}.'.format( _color2(str(len(handles))), u', '.join(_color2(handle) for handle in handles))) echo(term.move(*point)) for y_offset, txt in enumerate( term.wrap(matches_text, width=width)): echo(term.move(point.y + y_offset, point.x)) echo(txt + term.clear_eol) if point.y + y_offset > term.height - 3: # we simply cannot display anymore break echo(term.clear_eos) else: handle = find_user(inp) if handle is not None: return get_user(handle) echo(u''.join( (term.move(*point), u'No matches for {0}.'.format(_color2(inp)), term.clear_eos)))
def migrate_105lc(): from x84.bbs import echo, DBProxy, list_users, get_user # migrating lastcallers database for 1.0.5 upgrade lc = DBProxy('lastcalls') for handle in list_users(): user = get_user(handle) lc[(handle)] = (user.lastcall, user.calls, user.location) echo('\r\n' + user.handle + '.') echo('\r\n\r\nlast callers db rebuilt!')
def iter_userlist(): handles = sorted(list_users(), key=unicode.lower) timenow = time.time() user_record = collections.namedtuple('userlist', ['handle', 'location', 'timeago']) return (user_record(handle=user.handle, location=user.location, timeago=timenow - user.lastcall) for user in (get_user(handle) for handle in handles))
def locate_user(term, point): """ Prompt for search pattern and return discovered User. """ _color1, _color2, _color3 = [ getattr(term, _color) for _color in ( color_lowlight, color_highlight, color_field_edit)] # show help width = term.width - (point.x * 2) help_txt = (u'Enter username or glob pattern. Press escape to cancel.') y_offset = 0 for y_offset, txt in enumerate(term.wrap(help_txt, width=width)): echo(term.move(point.y + y_offset, point.x)) echo(_color1(txt) + term.clear_eol) point_prompt = Point(y=point.y + y_offset + 2, x=point.x) editor = LineEditor(nua.username_max_length, colors={'highlight': _color3}) while True: # prompt for handle echo(term.move(*point_prompt)) echo(u'handle: ' + term.clear_eol) inp = editor.read() point = Point(y=point_prompt.y + 2, x=point.x) if inp is None: # canceled (escape) return elif u'*' in inp or u'?' in inp: # a glob pattern, fetch all usernames handles = fnmatch.filter(list_users(), inp) if len(handles) == 0: echo(u''.join((term.move(*point), u'No matches for {0}.'.format(_color2(inp)), term.clear_eos))) elif len(handles) == 1: return get_user(handles[0]) else: matches_text = ( u'{0} accounts matched, chose one: {1}.'.format( _color2(str(len(handles))), u', '.join( _color2(handle) for handle in handles))) echo(term.move(*point)) for y_offset, txt in enumerate( term.wrap(matches_text, width=width)): echo(term.move(point.y + y_offset, point.x)) echo(txt + term.clear_eol) if point.y + y_offset > term.height - 3: # we simply cannot display anymore break echo(term.clear_eos) else: handle = find_user(inp) if handle is not None: return get_user(handle) echo(u''.join((term.move(*point), u'No matches for {0}.'.format(_color2(inp)), term.clear_eos)))
def prompt_recipient(msg): """ Prompt for recipient of message. """ # pylint: disable=R0914 # Too many local variables from x84.bbs import getterminal, LineEditor, echo, ini, list_users from x84.bbs import Selector import difflib term = getterminal() echo(u"ENtER %s, OR '%s' tO AddRESS All. %s to exit" % ( term.bold_yellow(u'hANdlE'), term.bold_yellow(u'None'), term.bold_yellow_underline('Escape'), )) echo(u'\r\n\r\n') max_user = ini.CFG.getint('nua', 'max_user') lne = LineEditor(max_user, msg.recipient or u'None') lne.highlight = term.yellow_reverse echo(term.clear_eol + u' RECiPiENt: ') recipient = lne.read() if recipient is None or lne.quit: return False userlist = list_users() if recipient in userlist: msg.recipient = recipient return True elif len(recipient) != 0 and recipient != 'None': for match in difflib.get_close_matches(recipient, userlist): blurb = u'did YOU MEAN: %s ?' % (match, ) inp = Selector(yloc=term.height - 1, xloc=term.width - 22, width=20, left=u'YES', right=u'NO') echo(u''.join((u'\r\n', term.move(inp.yloc, inp.xloc - len(blurb)), term.clear_eol, term.bold_yellow(blurb)))) selection = inp.read() echo(term.move(inp.yloc, 0) + term.clear_eol) if selection == u'YES': msg.recipient = match return True if selection is None or inp.quit: return False else: blurb = u' NO RECiPiENT; POSt tO PUbliC? ' inp = Selector(yloc=term.height - 1, xloc=term.width - 22, width=20, left=u'YES', right=u'NO') echo(u''.join((u'\r\n', term.move(inp.yloc, inp.xloc - len(blurb)), term.clear_eol, term.bold_yellow(blurb)))) selection = inp.read() echo(term.move(inp.yloc, 0) + term.clear_eol) if selection == u'YES': msg.recipient = None return True
def toplist(parameter): session, term = getsession(), getterminal() handle = session.user.handle counter = 0 user_handles = list_users() username = {} feature = {} location = {} database = {} echo(term.red + u' crunching data..') for handle in user_handles: user_record = get_user(handle) if u'sysop' in user_record.groups: continue if parameter == 'calls': database[user_record.handle.encode('utf8')] = user_record.calls if parameter == 'msgs': database[user_record.handle.encode('utf8')] = user_record.get( 'msgs_sent', 0) for name in sorted(database, key=database.get, reverse=True): username[counter] = name user_record = get_user(name) location[counter] = user_record.location feature[counter] = str(database[name]) counter = counter + 1 if counter > 10: counter = 10 # we only want to display the top ten users echo(term.clear()) showansi('topten.ans') if parameter == 'calls': echo(term.yellow + term.move(7, 1) + u'[ % ] - tOP tEN cALLERS [ % ]') if parameter == 'msgs': echo(term.yellow + term.move(7, 1) + u'[ % ] - tOP tEN wRITERS [ % ]') echo(term.cyan + term.move(9, 3) + u'username' + term.move_x(27) + u'group/location' + term.move_x(67) + parameter + u'\n\n') for i in range(0, counter): echo(term.white + term.move_x(3) + username[i] + term.move_x(27) + location[i] + term.move_x(67) + feature[i] + u'\r\n') waitprompt()
def toplist(parameter): session, term = getsession(), getterminal() handle = session.user.handle counter = 0 user_handles = list_users() username = {} feature = {} location = {} database = {} echo(term.red+u' crunching data..') for handle in user_handles: user_record = get_user(handle) if u'sysop' in user_record.groups: continue if parameter == 'calls': database[user_record.handle.encode('utf8')] = user_record.calls if parameter == 'msgs': database[user_record.handle.encode('utf8')] = user_record.get('msgs_sent',0) for name in sorted(database, key=database.get, reverse=True): username[counter] = name user_record = get_user(name) location[counter] = user_record.location feature[counter] = str(database[name]) counter = counter + 1 if counter > 10: counter = 10 # we only want to display the top ten users echo(term.clear()) showansi('topten.ans') if parameter == 'calls': echo(term.yellow+term.move(7,1)+u'[ % ] - tOP tEN cALLERS [ % ]') if parameter == 'msgs': echo(term.yellow+term.move(7,1)+u'[ % ] - tOP tEN wRITERS [ % ]') echo(term.cyan+term.move(9,3)+u'username'+term.move_x(27)+u'group/location'+term.move_x(67)+parameter+u'\n\n') for i in range (0, counter): echo(term.white+term.move_x(3)+username[i]+term.move_x(27)+location[i]+term.move_x(67)+feature[i]+u'\r\n') waitprompt()
def prompt_recipient(term, msg, colors, public=True): """ Prompt for recipient of message. """ xpos = max(0, (term.width // 2) - (80 // 2)) echo(term.move_x(xpos) + term.clear_eos) echo(u"Enter handle{0}.\r\n".format(u", empty to address to all" if public else u"")) echo(term.move_x(xpos) + ":: ") inp = LineEditor(username_max_length, msg.recipient, colors={"highlight": colors["backlight"]}).read() if inp is None: echo(u"".join((term.move_x(xpos), colors["highlight"]("Canceled."), term.clear_eol))) term.inkey(1) return False elif not inp.strip(): # empty, recipient is None msg.recipient = None if public: return True return False inp = inp.strip() # validate/find user userlist = list_users() if inp in userlist: # exact match, msg.recipient = inp echo(u"\r\n") return True # nearest match for match in difflib.get_close_matches(inp.strip(), userlist): echo(u"".join((term.move_x(xpos), u"{0} [yn]".format(colors["highlight"](match)), term.clear_eol, u" ?\b\b"))) while True: inp = term.inkey() if inp.code == term.KEY_ESCAPE: # escape/cancel return False elif inp.lower() == u"y": # accept match msg.recipient = match echo(u"\r\n") return True elif inp.lower() == u"n": # next match break echo(u"".join((term.move_x(xpos), colors["highlight"]("No match."), term.clear_eol))) term.inkey(1) return False
def get_next_user(tgt_user): """ Get next user in sorted order. """ handles = sorted(list_users()) try: current_idx = handles.index(tgt_user.handle) except ValueError: # what if we just deleted the target user? # inject it back into `handles' list and try again handles = sorted(handles + [tgt_user.handle]) current_idx = handles.index(tgt_user.handle) idx = min(current_idx + 1, len(handles) - 1) try: return get_user(handles[idx]) except KeyError: # and what if we deleted the last user of the list? # take the previous one. return get_user(handles[idx - 1])
def get_prev_user(tgt_user): """ Get previous user in sorted order. """ handles = sorted(list_users()) idx = max(handles.index(tgt_user.handle) - 1, 0) return get_user(handles[idx])
def prompt_recipient(term, msg, colors, public=True): """ Prompt for recipient of message. """ xpos = max(0, (term.width // 2) - (80 // 2)) echo(term.move_x(xpos) + term.clear_eos) echo(u'Enter handle{0}.\r\n'.format( u', empty to address to all' if public else u'')) echo(term.move_x(xpos) + ':: ') inp = LineEditor(username_max_length, msg.recipient, colors={'highlight': colors['backlight']} ).read() if inp is None: echo(u''.join((term.move_x(xpos), colors['highlight']('Canceled.'), term.clear_eol))) term.inkey(1) return False elif not inp.strip(): # empty, recipient is None msg.recipient = None if public: return True return False inp = inp.strip() # validate/find user userlist = list_users() if inp in userlist: # exact match, msg.recipient = inp echo(u'\r\n') return True # nearest match for match in difflib.get_close_matches(inp.strip(), userlist): echo(u''.join(( term.move_x(xpos), u'{0} [yn]'.format(colors['highlight'](match)), term.clear_eol, u' ?\b\b'))) while True: inp = term.inkey() if inp.code == term.KEY_ESCAPE: # escape/cancel return False elif inp.lower() == u'y': # accept match msg.recipient = match echo(u'\r\n') return True elif inp.lower() == u'n': # next match break echo(u''.join((term.move_x(xpos), colors['highlight']('No match.'), term.clear_eol))) term.inkey(1) return False
def dummy_pager(last_callers): """ Dummy pager for displaying last callers """ # pylint: disable=R0914 # Too many local variables from x84.bbs import getterminal, getsession, echo, getch, ini from x84.bbs import LineEditor, Ansi, list_users, get_user, gosub session, term = getsession(), getterminal() msg_prompt = ( u'\r\n%sONtiNUE, %stOP, %sON-StOP %siEW .PlAN%s ?\b\b' % ( term.bold(u'[c]'), term.bold(u'[s]'), term.bold(u'n'), term.bold(u'[v]'), u' [e]dit USR' if ( 'sysop' in session.user.groups) else u'',)) msg_partial = u'PARtiAl MAtChES' msg_prompt_handle = u'ViEW .PlAN ::- ENtER hANdlE: ' redraw() echo(u'\r\n\r\n') nonstop = False row = 10 # after-art, for txt in last_callers: echo(Ansi(txt).ljust(term.width / 2).center(term.width)) echo(u'\r\n') row += 1 if ((not nonstop and row > 0 and 0 == (row % (term.height - 3))) or (row == len(last_callers) - 1)): echo(msg_prompt) inp = getch() row = 2 if inp in (u's', u'S', u'q', u'Q', term.KEY_EXIT): return if inp in (u'v', u'V') or 'sysop' in session.user.groups and ( inp in (u'e', u'E')): echo(u'\r\n\r\n') echo(msg_prompt_handle) handle = LineEditor(ini.CFG.getint('nua', 'max_user')).read() usrlist = list_users() if handle is None or 0 == len(handle.strip()): continue handle = handle.strip() if handle.lower() in [nick.lower() for nick in list_users()]: user = get_user((nick for nick in usrlist if nick.lower() == handle.lower()).next()) if 'sysop' in session.user.groups and ( inp in (u'e', u'E')): gosub('profile', user.handle) else: view_plan(user.handle) else: misses = [nick for nick in usrlist.keys() if nick.lower().startswith(handle[:1].lower())] if len(misses) > 0: echo(u'%s:\r\n\r\n%s\r\n' % (msg_partial, Ansi(', '.join(misses)).wrap(term.width))) continue if inp in ('n', u'N'): nonstop = True echo(u'\r\n\r\n') pak()
def dummy_pager(last_callers): """ Dummy pager for displaying last callers """ # pylint: disable=R0914 # Too many local variables from x84.bbs import getterminal, getsession, echo, getch, ini, find_user from x84.bbs import LineEditor, Ansi, list_users, get_user, gosub session, term = getsession(), getterminal() msg_prompt = ( u'\r\n%sONtiNUE, %stOP, %sON-StOP %siEW .PlAN%s ?\b\b' % ( term.bold(u'[c]'), term.bold(u'[s]'), term.bold(u'n'), term.bold(u'[v]'), u' [e]dit USR' if ( 'sysop' in session.user.groups) else u'',)) msg_partial = u'PARtiAl MAtChES' msg_prompt_handle = u'ViEW .PlAN ::- ENtER hANdlE: ' redraw() echo(u'\r\n\r\n') nonstop = False row = 10 # after-art, for txt in last_callers: echo(Ansi(txt).ljust(term.width / 2).center(term.width)) echo(u'\r\n') row += 1 if ((not nonstop and row > 0 and 0 == (row % (term.height - 3))) or (row == len(last_callers) - 1)): echo(msg_prompt) inp = getch() row = 2 if inp in (u's', u'S', u'q', u'Q', term.KEY_EXIT): return if inp in (u'v', u'V') or 'sysop' in session.user.groups and ( inp in (u'e', u'E')): echo(u'\r\n\r\n') echo(msg_prompt_handle) handle = LineEditor(ini.CFG.getint('nua', 'max_user')).read() usrlist = list_users() if handle is None or 0 == len(handle.strip()): continue handle = handle.strip() if handle.lower() in [nick.lower() for nick in list_users()]: nick = ((_nick for _nick in usrlist if _nick.lower() == handle.lower()).next()) if find_user(nick): user = get_user(nick) if 'sysop' in session.user.groups and ( inp in (u'e', u'E')): gosub('profile', user.handle) else: view_plan(user.handle) else: misses = [nick for nick in usrlist.keys() if nick.lower().startswith(handle[:1].lower())] if len(misses) > 0: echo(u'%s:\r\n\r\n%s\r\n' % (msg_partial, Ansi(', '.join(misses)).wrap(term.width))) continue if inp in ('n', u'N'): nonstop = True echo(u'\r\n\r\n') pak()
def main(handle): """ Main procedure. """ # pylint: disable=R0914,R0915,R0911 # Too many local variables # Too many statements # Too many return statements # by request from midget; a password reset form session, term = getsession(), getterminal() session.activity = 'resetting password for %s' % (handle,) user = get_user(handle) logger = logging.getLogger() prompt_email = u'\r\n\r\nENtER E-MAil fOR %r: ' msg_nfound = u'\r\n\r\n%r NOt fOUNd iN USERbASE.' msg_cancelled = u'\r\n CANCEllEd.' msg_wrong = u'\r\n\r\nWRONG' msg_mailsubj = u'passkey for %s' % (ini.CFG.get('system', 'bbsname')) msg_mailbody = u'Your passkey is %r' msg_mailfrom = ini.CFG.get('system', 'mail_addr') msg_sent = u'\r\n\r\nPASSkEY hAS bEEN SENt tO %s.' prompt_passkey = u'\r\n\r\nENtER PASSkEY: ' msg_verified = u'\r\n\r\nYOU hAVE bEEN VERifiEd.' echo(term.normal) if not handle in list_users(): echo(term.bold_red(msg_nfound)) getch() return False width = ini.CFG.getint('nua', 'max_email') email = None tries = 0 while True: tries += 1 if tries > 5: logger.warn('%r email retries exceeded', handle) return False echo(prompt_email % (handle,)) try_email = LineEditor(width).read() if try_email is None or 0 == len(try_email): echo(term.normal + msg_cancelled) return False # fetch user record email email = get_user(handle).email if email is None or 0 == len(email): logger.warn('%r missing email address, cannot send', handle) echo(term.bold_red(msg_wrong)) elif email.lower() != try_email.lower(): logger.warn('%r failed email %r (try: %r)', handle, email, try_email) echo(term.bold_red(msg_wrong)) else: logger.info('%r requests password reset to %r', handle, email) break # generate a 'passkey' and e-mail out of band, and request input passkey = base64.encodestring( os.urandom(ini.CFG.getint('nua', 'max_pass')) )[:ini.CFG.getint('nua', 'max_pass')] msg = MIMEText(msg_mailbody % (passkey,)) msg['From'] = msg_mailfrom msg['To'] = email msg['Subject'] = msg_mailsubj # pylint: disable=W0703 # Catching too general exception Exception err = None try: smtp = smtplib.SMTP(ini.CFG.get('system', 'mail_smtphost')) smtp.sendmail(msg_mailfrom, [email], msg.as_string()) smtp.quit() except Exception as err: logger.exception(err) echo('u\r\n\r\n' + term.bold_red(str(err)) + u'\r\n') getch(2) return False echo(msg_sent % (email,)) width = len(passkey) email = None tries = 0 while True: tries += 1 if tries > 5: logger.warn("passkey retries exceeded for user '%s'", handle) return False echo(term.normal + u'\r\n\r\n') echo(prompt_passkey) try_passkey = LineEditor(width).read() if try_passkey is None or 0 == len(try_passkey): echo(term.normal + msg_cancelled) logger.warn("cancelled passkey for user '%s'", handle) return False if passkey == try_passkey: echo(term.bold_green(msg_verified)) echo(u'\r\n\r\n') break logger.warn("failed passkey for user '%s': '%s', tried '%s')", handle, passkey, try_passkey) echo(term.bold_red(msg_wrong)) set_password(user) user.save() return True
def main(handle): """ Main procedure. """ # pylint: disable=R0914,R0915,R0911 # Too many local variables # Too many statements # Too many return statements # by request from midget; a password reset form session, term = getsession(), getterminal() session.activity = 'resetting password for %s' % (handle, ) user = get_user(handle) logger = logging.getLogger() prompt_email = u'\r\n\r\nENtER E-MAil fOR %r: ' msg_nfound = u'\r\n\r\n%r NOt fOUNd iN USERbASE.' msg_cancelled = u'\r\n CANCEllEd.' msg_wrong = u'\r\n\r\nWRONG' msg_mailsubj = u'passkey for %s' % (ini.CFG.get('system', 'bbsname')) msg_mailbody = u'Your passkey is %r' msg_mailfrom = ini.CFG.get('system', 'mail_addr') msg_sent = u'\r\n\r\nPASSkEY hAS bEEN SENt tO %s.' prompt_passkey = u'\r\n\r\nENtER PASSkEY: ' msg_verified = u'\r\n\r\nYOU hAVE bEEN VERifiEd.' echo(term.normal) if not handle in list_users(): echo(term.bold_red(msg_nfound)) getch() return False width = ini.CFG.getint('nua', 'max_email') email = None tries = 0 while True: tries += 1 if tries > 5: logger.warn('%r email retries exceeded', handle) return False echo(prompt_email % (handle, )) try_email = LineEditor(width).read() if try_email is None or 0 == len(try_email): echo(term.normal + msg_cancelled) return False # fetch user record email email = get_user(handle).email if email is None or 0 == len(email): logger.warn('%r missing email address, cannot send', handle) echo(term.bold_red(msg_wrong)) elif email.lower() != try_email.lower(): logger.warn('%r failed email %r (try: %r)', handle, email, try_email) echo(term.bold_red(msg_wrong)) else: logger.info('%r requests password reset to %r', handle, email) break # generate a 'passkey' and e-mail out of band, and request input passkey = base64.encodestring(os.urandom(ini.CFG.getint( 'nua', 'max_pass')))[:ini.CFG.getint('nua', 'max_pass')] msg = MIMEText(msg_mailbody % (passkey, )) msg['From'] = msg_mailfrom msg['To'] = email msg['Subject'] = msg_mailsubj # pylint: disable=W0703 # Catching too general exception Exception err = None try: smtp = smtplib.SMTP(ini.CFG.get('system', 'mail_smtphost')) smtp.sendmail(msg_mailfrom, [email], msg.as_string()) smtp.quit() except Exception as err: logger.exception(err) echo('u\r\n\r\n' + term.bold_red(str(err)) + u'\r\n') getch(2) return False echo(msg_sent % (email, )) width = len(passkey) email = None tries = 0 while True: tries += 1 if tries > 5: logger.warn("passkey retries exceeded for user '%s'", handle) return False echo(term.normal + u'\r\n\r\n') echo(prompt_passkey) try_passkey = LineEditor(width).read() if try_passkey is None or 0 == len(try_passkey): echo(term.normal + msg_cancelled) logger.warn("cancelled passkey for user '%s'", handle) return False if passkey == try_passkey: echo(term.bold_green(msg_verified)) echo(u'\r\n\r\n') break logger.warn("failed passkey for user '%s': '%s', tried '%s')", handle, passkey, try_passkey) echo(term.bold_red(msg_wrong)) set_password(user) user.save() return True