def reset_token_commands(args): if args.clear_reset: username = args.clear_reset else: username = args.reset user_info = userdb.get_user_info(username) if not user_info: err_exit("Reset/clear password failed; invalid user: %s" % username) # don't crash on the default config if config.get('lobby_url') is None: config.set('lobby_url', "[insert lobby url here]") if args.clear_reset: ok, msg = userdb.clear_password_token(username) if not ok: err_exit("Error clearing password reset token for %s: %s" % (username, msg)) else: print("Password reset token cleared for account '%s'." % username) else: ok, msg = userdb.generate_forgot_password(username) if not ok: err_exit("Error generating password reset token for %s: %s" % (username, msg)) else: if not user_info[1]: logging.warning("No email set for account '%s', use caution!" % username) print("Setting a password reset token on account '%s'." % username) print("Email: %s\nMessage body to send to user:\n%s\n" % (user_info[1], msg))
def parse_args_main(): parser = argparse.ArgumentParser( description='Dungeon Crawl webtiles server', epilog='Command line options will override config settings. See wtutil.py for database commands.') parser.add_argument('-p', '--port', type=int, help='A port to bind; disables SSL.') # TODO: --ssl-port or something? parser.add_argument('--logfile', help='A logfile to write to; use "-" for stdout.') parser.add_argument('--daemon', action='store_true', default=None, help='Daemonize after start.') parser.add_argument('-n', '--no-daemon', action='store_false', default=None, dest='daemon', help='Do not daemonize after start.') parser.add_argument('--no-pidfile', dest='pidfile', action='store_false', default=None, help='Do not use a PID-file.') # live debug mode is intended to be able to run (more or less) safely with # a concurrent real webtiles server. However, still be careful with this... parser.add_argument('--live-debug', action='store_true', help=('Debug mode for server admins. Will use a separate directory for sockets. ' 'Entails --no-pidfile, --no-daemon, --logfile -, watch_socket_dirs=False. ' '(Further command line options can override these.)')) result = parser.parse_args() if result.live_debug: if not result.logfile: result.logfile = '-' if result.daemon is None: result.daemon = False result.pidfile = False config.set('live_debug', True) return result
def run(): args = parse_args_main() if config.get('chroot'): os.chroot(config.get('chroot')) if config.source_file is None: # we could try to automatically figure this out from server_path, if # it is set? sys.exit("No configuration provided!") # do this here so it can happen before logging init if args.logfile: if args.logfile == "-": config.get('logging_config').pop('filename', None) args.logfile = "<stdout>" # make the log message easier to read else: config.get('logging_config')['filename'] = args.logfile init_logging(config.get('logging_config')) logging.info("Loaded server configuration from: %s", config.source_file) if config.get('live_debug'): logging.info("Starting in live-debug mode.") config.set('watch_socket_dirs', False) if args.logfile: logging.info("Using command-line supplied logfile: '%s'", args.logfile) export_args_to_config(args) try: config.load_game_data() config.validate() except: err_exit("Errors in config. Exiting.", exc_info=True) if config.get('daemon', False): daemonize() signal.signal(signal.SIGTERM, signal_handler) signal.signal(signal.SIGHUP, signal_handler) signal.signal(signal.SIGINT, signal_handler) if config.get('umask') is not None: os.umask(config.get('umask')) write_pidfile() global servers servers = bind_server() ensure_tornado_current() shed_privileges() # is this ever set to False by anyone in practice? dgl_mode = config.get('dgl_mode') if dgl_mode: userdb.ensure_user_db_exists() userdb.upgrade_user_db() userdb.ensure_settings_db_exists() signal.signal(signal.SIGUSR1, usr1_handler) try: IOLoop.current().set_blocking_log_threshold(0.5) # type: ignore logging.info("Blocking call timeout: 500ms.") except: # this is the new normal; still not sure of a way to deal with this. logging.info("Webserver running without a blocking call timeout.") if dgl_mode: ws_handler.status_file_timeout() auth.purge_login_tokens_timeout() ws_handler.start_reading_milestones() if config.get('watch_socket_dirs'): process_handler.watch_socket_dirs() # start the lobby update timeout loop ws_handler.do_periodic_lobby_updates() logging.info("DCSS Webtiles server started with Tornado %s! (PID: %s)" % (tornado.version, os.getpid())) IOLoop.current().start() logging.info("Bye!") remove_pidfile()
def export_args_to_config(args): if args.port: config.set('bind_nonsecure', True) config.set('bind_address', "") # TODO: ?? config.set('bind_port', args.port) if config.get('bind_pairs') is not None: config.pop('bind_pairs') logging.info("Using command-line supplied port: %d", args.port) if config.get('ssl_options'): logging.info(" (Overrides config-specified SSL settings.)") config.set('ssl_options', None) if args.daemon is not None: logging.info("Command line override for daemonize: %r", args.daemon) config.set('daemon', args.daemon) if args.pidfile is not None: if not args.pidfile: if config.get('pidfile'): logging.info( "Command line overrides config-specified PID file!") config.set('pidfile', None)