def handle_error(self, request, client_address): if issubclass(sys.exc_info()[0], socket.timeout): logger.info("client timed out", exc_info=True) else: logger.error("An exception occurred during request: %s", sys.exc_info()[1], exc_info=True)
def __call__(self, environ, start_response): with log.register_stream(environ["wsgi.errors"]): try: status, headers, answers = self._handle_request(environ) except Exception as e: try: method = str(environ["REQUEST_METHOD"]) except Exception: method = "unknown" try: path = str(environ.get("PATH_INFO", "")) except Exception: path = "" logger.error( "An exception occurred during %s request on %r: " "%s", method, path, e, exc_info=True) status, headers, answer = httputils.INTERNAL_SERVER_ERROR answer = answer.encode("ascii") status = "%d %s" % (status.value, client.responses.get(status, "Unknown")) headers = [("Content-Length", str(len(answer))) ] + list(headers) answers = [answer] start_response(status, headers) return answers
def exception_cm(sane_path, href=None): nonlocal item_errors, collection_errors try: yield except Exception as e: if href: item_errors += 1 name = "item %r in %r" % (href, sane_path) else: collection_errors += 1 name = "collection %r" % sane_path logger.error("Invalid %s: %s", name, e, exc_info=True)
def verify(cls): item_errors = collection_errors = 0 @contextlib.contextmanager def exception_cm(sane_path, href=None): nonlocal item_errors, collection_errors try: yield except Exception as e: if href: item_errors += 1 name = "item %r in %r" % (href, sane_path) else: collection_errors += 1 name = "collection %r" % sane_path logger.error("Invalid %s: %s", name, e, exc_info=True) remaining_sane_paths = [""] while remaining_sane_paths: sane_path = remaining_sane_paths.pop(0) path = pathutils.unstrip_path(sane_path, True) logger.debug("Verifying collection %r", sane_path) with exception_cm(sane_path): saved_item_errors = item_errors collection = None uids = set() has_child_collections = False for item in cls.discover(path, "1", exception_cm): if not collection: collection = item collection.get_meta() continue if isinstance(item, storage.BaseCollection): has_child_collections = True remaining_sane_paths.append(item.path) elif item.uid in uids: logger.error("Invalid item %r in %r: UID conflict %r", item.href, sane_path, item.uid) else: uids.add(item.uid) logger.debug("Verified item %r in %r", item.href, sane_path) if item_errors == saved_item_errors: collection.sync() if has_child_collections and collection.get_meta("tag"): logger.error( "Invalid collection %r: %r must not have " "child collections", sane_path, collection.get_meta("tag")) return item_errors == 0 and collection_errors == 0
def verify(cls): item_errors = collection_errors = 0 @contextlib.contextmanager def exception_cm(sane_path, href=None): nonlocal item_errors, collection_errors try: yield except Exception as e: if href: item_errors += 1 name = "item %r in %r" % (href, sane_path) else: collection_errors += 1 name = "collection %r" % sane_path logger.error("Invalid %s: %s", name, e, exc_info=True) remaining_sane_paths = [""] while remaining_sane_paths: sane_path = remaining_sane_paths.pop(0) path = pathutils.unstrip_path(sane_path, True) logger.debug("Verifying collection %r", sane_path) with exception_cm(sane_path): saved_item_errors = item_errors collection = None uids = set() has_child_collections = False for item in cls.discover(path, "1", exception_cm): if not collection: collection = item collection.get_meta() continue if isinstance(item, storage.BaseCollection): has_child_collections = True remaining_sane_paths.append(item.path) elif item.uid in uids: logger.error("Invalid item %r in %r: UID conflict %r", item.href, sane_path, item.uid) else: uids.add(item.uid) logger.debug("Verified item %r in %r", item.href, sane_path) if item_errors == saved_item_errors: collection.sync() if has_child_collections and collection.get_meta("tag"): logger.error("Invalid collection %r: %r must not have " "child collections", sane_path, collection.get_meta("tag")) return item_errors == 0 and collection_errors == 0
def _notify(self, notification_item, recall): try: self._channel.basic_publish( exchange='', routing_key=self._topic, body=notification_item.to_json().encode( encoding=self._encoding)) except Exception as e: if (isinstance(e, ChannelWrongStateError) or isinstance(e, StreamLostError)) and recall: self._make_connection_synced() self._notify(notification_item, False) return logger.error( "An exception occurred during " "publishing hook notification item: %s", e, exc_info=True)
def __call__(self, environ, start_response): with log.register_stream(environ["wsgi.errors"]): try: status, headers, answers = self._handle_request(environ) except Exception as e: try: method = str(environ["REQUEST_METHOD"]) except Exception: method = "unknown" try: path = str(environ.get("PATH_INFO", "")) except Exception: path = "" logger.error("An exception occurred during %s request on %r: " "%s", method, path, e, exc_info=True) status, headers, answer = httputils.INTERNAL_SERVER_ERROR answer = answer.encode("ascii") status = "%d %s" % ( status, client.responses.get(status, "Unknown")) headers = [ ("Content-Length", str(len(answer)))] + list(headers) answers = [answer] start_response(status, headers) return answers
def login(self, login, password): if login == "" or password == "": return "" server = ldap3.Server(self.ldap_url, get_info=ldap3.ALL) conn = ldap3.Connection(server=server, user=self.ldap_binddn, password=self.ldap_password, check_names=True, lazy=False, raise_exceptions=False) conn.open() conn.bind() if conn.result["result"] != 0: logger.error(conn.result) return "" final_search_filter = self.ldap_filter.replace("%username", login) conn.search(search_base=self.ldap_base, search_filter=final_search_filter, attributes=ldap3.ALL_ATTRIBUTES) if conn.result["result"] != 0: logger.error(conn.result) return "" if len(conn.response) == 0: return "" final_user_dn = conn.response[0]["dn"] conn.unbind() # new connection to check the password as we cannot rebind here conn = ldap3.Connection(server=server, user=final_user_dn, password=password, check_names=True, lazy=False, raise_exceptions=False) conn.open() conn.bind() if conn.result["result"] != 0: logger.error(conn.result) return "" return login
def log_error(self, format, *args): msg = format % args logger.error("An error occurred during request: %s" % msg)
def log_exception(self, exc_info): logger.error("An exception occurred during request: %s", exc_info[1], exc_info=exc_info)
def log_error(self, format_, *args): logger.error("An error occurred during request: %s", format_ % args)
def run(): """Run Radicale as a standalone server.""" log.setup() # Get command-line arguments parser = argparse.ArgumentParser(usage="radicale [OPTIONS]") parser.add_argument("--version", action="version", version=VERSION) parser.add_argument("--verify-storage", action="store_true", help="check the storage for errors and exit") parser.add_argument("-C", "--config", help="use a specific configuration file") parser.add_argument("-D", "--debug", action="store_true", help="print debug information") groups = {} for section, values in config.INITIAL_CONFIG.items(): group = parser.add_argument_group(section) groups[group] = [] for option, data in values.items(): kwargs = data.copy() long_name = "--{0}-{1}".format(section, option.replace("_", "-")) args = kwargs.pop("aliases", []) args.append(long_name) kwargs["dest"] = "{0}_{1}".format(section, option) groups[group].append(kwargs["dest"]) del kwargs["value"] if "internal" in kwargs: del kwargs["internal"] if kwargs["type"] == bool: del kwargs["type"] kwargs["action"] = "store_const" kwargs["const"] = "True" opposite_args = kwargs.pop("opposite", []) opposite_args.append("--no{0}".format(long_name[1:])) group.add_argument(*args, **kwargs) kwargs["const"] = "False" kwargs["help"] = "do not {0} (opposite of {1})".format( kwargs["help"], long_name) group.add_argument(*opposite_args, **kwargs) else: group.add_argument(*args, **kwargs) args = parser.parse_args() # Preliminary configure logging if args.debug: args.logging_level = "debug" if args.logging_level is not None: log.set_level(args.logging_level) if args.config is not None: config_paths = [args.config] if args.config else [] ignore_missing_paths = False else: config_paths = [ "/etc/radicale/config", os.path.expanduser("~/.config/radicale/config") ] if "RADICALE_CONFIG" in os.environ: config_paths.append(os.environ["RADICALE_CONFIG"]) ignore_missing_paths = True try: configuration = config.load(config_paths, ignore_missing_paths=ignore_missing_paths) except Exception as e: log.error("Invalid configuration: %s", e, exc_info=True) exit(1) # Update Radicale configuration according to arguments for group, actions in groups.items(): section = group.title for action in actions: value = getattr(args, action) if value is not None: configuration.set(section, action.split('_', 1)[1], value) # Configure logging log.set_level(configuration.get("logging", "level")) if args.verify_storage: logger.info("Verifying storage") try: Collection = storage.load(configuration) with Collection.acquire_lock("r"): if not Collection.verify(): logger.error("Storage verifcation failed") exit(1) except Exception as e: logger.error( "An exception occurred during storage verification: " "%s", e, exc_info=True) exit(1) return try: serve(configuration) except Exception as e: logger.error("An exception occurred during server startup: %s", e, exc_info=True) exit(1)