def process_django_allauth(self, settings_dict): if (not settings_dict["USE_ALL_AUTH"] and not settings_dict["ALLAUTH_PROVIDER_APPS"]): return [] try: get_distribution("django-allauth") except DistributionNotFound: settings_check_results.append( missing_package("django-allauth", " to use OAuth2 or OpenID authentication")) return [] if "django.contrib.sites" not in self.default_apps: settings_check_results.append( Error( '"django.contrib.sites" app must be enabled.', obj="configuration", id="djangofloor.E001", )) return [] result = [ "allauth", "allauth.account", "allauth.socialaccount", ] if settings_dict["ALLAUTH_PROVIDER_APPS"]: result += [ k for k in settings_dict["ALLAUTH_PROVIDER_APPS"] if k in self.social_apps ] return result
def check_commandline(self): if settings.DEBUG: settings_check_results.append( Warning( "The DEBUG mode is activated. You should disable it in production", obj="configuration", ))
def check_commandline(self): if settings.DEBUG: settings_check_results.append( Warning( "The DEBUG mode is activated. You should disable it in production", obj="configuration", ) )
def from_str(value): if value not in choices: valid = ", ".join(['"%s"' % x for x in choices]) settings_check_results.append( Error( 'Invalid value "%s". Valid choices: %s.' % (value, valid), obj="configuration", ) ) return choices.get(value)
def from_str(value): if value not in choices: valid = ", ".join(['"%s"' % x for x in choices]) settings_check_results.append( Error( 'Invalid value "%s". Valid choices: %s.' % (value, valid), obj="configuration", )) return choices.get(value)
def process_radius(self, settings_dict): if not settings_dict["RADIUS_SERVER"]: return [] try: get_distribution("django-radius") except DistributionNotFound: settings_check_results.append( missing_package("django-radius", " to use RADIUS authentication") ) return [] return ["radiusauth.backends.RADIUSBackend"]
def process_django_ldap(self, settings_dict): if not settings_dict["AUTH_LDAP_SERVER_URI"]: return [] try: get_distribution("django-auth-ldap") except DistributionNotFound: settings_check_results.append( missing_package("django-auth-ldap", " to use LDAP authentication")) return [] return ["django_auth_ldap.backend.LDAPBackend"]
def process_radius(self, settings_dict): if not settings_dict["RADIUS_SERVER"]: return [] try: get_distribution("django-radius") except DistributionNotFound: settings_check_results.append( missing_package("django-radius", " to use RADIUS authentication")) return [] return ["radiusauth.backends.RADIUSBackend"]
def process_django_ldap(self, settings_dict): if not settings_dict["AUTH_LDAP_SERVER_URI"]: return [] try: get_distribution("django-auth-ldap") except DistributionNotFound: settings_check_results.append( missing_package("django-auth-ldap", " to use LDAP authentication") ) return [] return ["django_auth_ldap.backend.LDAPBackend"]
def process_third_parties(self, settings_dict): result = [] for k, v in self.common_third_parties.items(): package_name = v.partition(".")[0] if not settings_dict[k]: continue elif not is_package_present(package_name): settings_check_results.append(missing_package(package_name, "")) continue result.append(v) return result
def check_commandline(self): if psutil is None: return for y in psutil.disk_partitions(all=True): if y.mountpoint in self.excluded_mountpoints: continue # noinspection PyBroadException try: usage = psutil.disk_usage(y.mountpoint) if usage.total > 0 and usage.percent > 95: msg = "%s is almost full (%s %%)." % (y.mountpoint, usage.percent) settings_check_results.append(Info(msg, obj="system")) except Exception: pass
def get_value(self, merger, provider_name: str, setting_name: str): """ Return the value :param merger: merger object, with all interpreted settings :type merger: :class:`djangofloor.utils.SettingMerger` :param provider_name: name of the provider containing this value :param setting_name: name of the setting containing this value """ value = merger.analyze_raw_value(self.value, provider_name, setting_name) value = os.path.normpath(value) if not os.path.isfile(value): settings_check_results.append( Warning("'%s' does not exist." % value, obj="configuration")) return value
def get_value(self, merger, provider_name: str, setting_name: str): """ Return the value :param merger: merger object, with all interpreted settings :type merger: :class:`djangofloor.utils.SettingMerger` :param provider_name: name of the provider containing this value :param setting_name: name of the setting containing this value """ value = merger.analyze_raw_value(self.value, provider_name, setting_name) value = os.path.normpath(value) if not os.path.isfile(value): settings_check_results.append( Warning("'%s' does not exist." % value, obj="configuration") ) return value
def get_requirements(package_name, parent=None): try: yield str(package_name) d = get_distribution(package_name) for r in d.requires(): for required_package in get_requirements(r, parent=package_name): yield str(required_package) except DistributionNotFound: settings_check_results.append( missing_package(str(package_name), " by %s" % parent) ) except VersionConflict: settings_check_results.append( missing_package(str(package_name), " by %s" % parent) )
def allauth_provider_apps(settings_dict): parser = RawConfigParser() config = settings_dict["ALLAUTH_APPLICATIONS_CONFIG"] if not os.path.isfile(config): return [] # noinspection PyBroadException try: parser.read([config]) except Exception: settings_check_results.append( Error("Invalid config file. %s" % config, obj="configuration")) return [] return [ parser.get(section, "django_app") for section in parser.sections() if parser.has_option(section, "django_app") ]
def get_value(self, merger, provider_name: str, setting_name: str): """ Return the value :param merger: merger object, with all interpreted settings :type merger: :class:`djangofloor.utils.SettingMerger` :param provider_name: name of the provider containing this value :param setting_name: name of the setting containing this value """ value = merger.analyze_raw_value(self.value, provider_name, setting_name) value = os.path.normpath(value) if not value.endswith("/"): value += "/" if not os.path.isdir(value): settings_check_results.append( Warning( "'%s' is not a directory. Run the 'collectstatic' command to fix this problem." % value, obj="configuration", )) return value
def process_pam(self, settings_dict): if not settings_dict["USE_PAM_AUTHENTICATION"]: return [] try: get_distribution("django_pam") except DistributionNotFound: settings_check_results.append( missing_package("django-pam", " to use PAM authentication")) return [] # check if the current user is in the shadow group username = pwd.getpwuid(os.getuid()).pw_name if not any(x.gr_name == "shadow" and username in x.gr_mem for x in grp.getgrall()): settings_check_results.append( Error( 'The user "%s" must belong to the "shadow" group to use PAM ' "authentication." % username, obj="configuration", )) return [] return ["django_pam.auth.backends.PAMBackend"]
def get_value(self, merger, provider_name: str, setting_name: str): """ Return the value :param merger: merger object, with all interpreted settings :type merger: :class:`djangofloor.utils.SettingMerger` :param provider_name: name of the provider containing this value :param setting_name: name of the setting containing this value """ value = merger.analyze_raw_value(self.value, provider_name, setting_name) value = os.path.normpath(value) if not value.endswith("/"): value += "/" if not os.path.isdir(value): settings_check_results.append( Warning( "'%s' is not a directory. Run the 'collectstatic' command to fix this problem." % value, obj="configuration", ) ) return value
def database_engine(settings_dict): """Allow to use aliases for database engines, as well as the default dotted name""" engine = _default_database_engines.get( settings_dict["DATABASE_ENGINE"].lower(), settings_dict["DATABASE_ENGINE"] ) if engine == "django.db.backends.postgresql": try: get_distribution("psycopg2-binary") except DistributionNotFound: try: get_distribution("psycopg2") except DistributionNotFound: settings_check_results.append( missing_package("psycopg2-binary", " to use PostgreSQL database") ) elif engine == "django.db.backends.oracle": try: get_distribution("cx_Oracle") except DistributionNotFound: settings_check_results.append( missing_package("cx_Oracle", " to use Oracle database") ) elif engine == "django.db.backends.mysql": try: get_distribution("mysqlclient") except DistributionNotFound: settings_check_results.append( missing_package("mysqlclient", " to use MySQL or MariaDB database") ) return engine
def get_value(self, merger, provider_name: str, setting_name: str): """ Return the value :param merger: merger object, with all interpreted settings :type merger: :class:`djangofloor.utils.SettingMerger` :param provider_name: name of the provider containing this value :param setting_name: name of the setting containing this value """ filename = merger.analyze_raw_value(self.value, provider_name, setting_name) if os.path.isfile(filename): with open(filename, "r", encoding="utf-8") as fd: result_text = fd.read() result = self.unserialize_value(result_text) else: settings_check_results.append( Warning( "'%s' does not exist. Run the 'migrate' command to fix this problem." % filename, obj="configuration", )) result = self.create_function(False, *self.args, **self.kwargs) return result
def get_value(self, merger, provider_name: str, setting_name: str): """ Return the value :param merger: merger object, with all interpreted settings :type merger: :class:`djangofloor.utils.SettingMerger` :param provider_name: name of the provider containing this value :param setting_name: name of the setting containing this value """ filename = merger.analyze_raw_value(self.value, provider_name, setting_name) if os.path.isfile(filename): with open(filename, "r", encoding="utf-8") as fd: result_text = fd.read() result = self.unserialize_value(result_text) else: settings_check_results.append( Warning( "'%s' does not exist. Run the 'migrate' command to fix this problem." % filename, obj="configuration", ) ) result = self.create_function(False, *self.args, **self.kwargs) return result
def process_pam(self, settings_dict): if not settings_dict["USE_PAM_AUTHENTICATION"]: return [] try: get_distribution("django_pam") except DistributionNotFound: settings_check_results.append( missing_package("django-pam", " to use PAM authentication") ) return [] # check if the current user is in the shadow group username = pwd.getpwuid(os.getuid()).pw_name if not any( x.gr_name == "shadow" and username in x.gr_mem for x in grp.getgrall() ): settings_check_results.append( Error( 'The user "%s" must belong to the "shadow" group to use PAM ' "authentication." % username, obj="configuration", ) ) return [] return ["django_pam.auth.backends.PAMBackend"]
def add_handler( self, logger: str, filename: str, level: str = "WARN", formatter=None, **kwargs ): """Add a handler to a logger. The name of the added handler is unique, so the definition of the handler is also add if required. You can use "ROOT" as logger name to target the root logger. filename: can be a filename or one of the following special values: "stderr", "stdout", "logd", "syslog" """ if filename == "stderr": handler_name = "%s.%s" % (filename, level.lower()) if formatter in ("django.server", "colorized") and not sys.stderr.isatty(): formatter = None elif formatter: handler_name += ".%s" % formatter handler = { "class": "logging.StreamHandler", "level": level, "stream": "ext://sys.stderr", "formatter": formatter, } elif filename == "stdout": handler_name = "%s.%s" % (filename, level.lower()) if formatter in ("django.server", "colorized") and not sys.stdout.isatty(): formatter = None elif formatter: handler_name += ".%s" % formatter handler = { "class": "logging.StreamHandler", "level": level, "stream": "ext://sys.stdout", "formatter": formatter, } elif filename == "syslog": handler_name = "%s.%s" % (filename, level.lower()) handler = {"class": "logging.handlers.SysLogHandler", "level": level} handler.update(kwargs) elif filename == "logd": try: # noinspection PyUnresolvedReferences,PyPackageRequirements import systemd.journal except ImportError: warning = Warning( "Unable to import systemd.journal (required to log with journlad)", hint=None, obj="configuration", ) settings_check_results.append(warning) # replace logd by writing to a plain-text log self.add_handler(logger, level.lower(), level=level) return handler_name = "%s.%s" % (filename, level.lower()) handler = {"class": "systemd.journal.JournalHandler", "level": level} handler.update(kwargs) else: # basename of a plain-text log log_directory = os.path.normpath(self.log_directory) if not os.path.isdir(log_directory): warning = Warning( 'Missing directory, you can create it with \nmkdir -p "%s"' % log_directory, hint=None, obj=log_directory, ) settings_check_results.append(warning) self.add_handler(logger, "stdout", level=level, **kwargs) return basename = "%s-%s.log" % (self.log_suffix, filename) log_filename = os.path.join(log_directory, basename) try: remove = not os.path.exists(log_filename) open(log_filename, "a").close() # ok, we can write if ( remove ): # but if this file did not exist, we remove it to avoid lot of empty log files... os.remove(log_filename) except PermissionError: warning_ = Warning( 'Unable to write logs in "%s". Unsufficient rights?' % log_directory, hint=None, obj=log_directory, ) settings_check_results.append(warning_) self.add_handler(logger, "stdout", level=level, **kwargs) handler_name = "%s.%s" % (self.log_suffix, filename) handler = { "class": "logging.handlers.RotatingFileHandler", "maxBytes": 1000000, "backupCount": 3, "formatter": "nocolor", "filename": log_filename, "level": level, } if handler_name not in self.handlers: self.handlers[handler_name] = handler if logger == "ROOT": self.root["handlers"].append(handler_name) else: self.loggers[logger]["handlers"].append(handler_name)
def add_handler(self, logger: str, filename: str, level: str = "WARN", formatter=None, **kwargs): """Add a handler to a logger. The name of the added handler is unique, so the definition of the handler is also add if required. You can use "ROOT" as logger name to target the root logger. filename: can be a filename or one of the following special values: "stderr", "stdout", "logd", "syslog" """ if filename == "stderr": handler_name = "%s.%s" % (filename, level.lower()) if formatter in ("django.server", "colorized") and not self.stderr.isatty(): formatter = None elif formatter: handler_name += ".%s" % formatter handler = { "class": "logging.StreamHandler", "level": level, "stream": "ext://sys.stderr", "formatter": formatter, } elif filename == "stdout": handler_name = "%s.%s" % (filename, level.lower()) if formatter in ("django.server", "colorized") and not self.stdout.isatty(): formatter = None elif formatter: handler_name += ".%s" % formatter handler = { "class": "logging.StreamHandler", "level": level, "stream": "ext://sys.stdout", "formatter": formatter, } elif filename == "syslog": handler_name = "%s.%s" % (filename, level.lower()) handler = { "class": "logging.handlers.SysLogHandler", "level": level } handler.update(kwargs) elif filename == "logd": try: # noinspection PyUnresolvedReferences,PyPackageRequirements import systemd.journal except ImportError: warning = Warning( "Unable to import systemd.journal (required to log with journlad)", hint=None, obj="configuration", ) settings_check_results.append(warning) # replace logd by writing to a plain-text log self.add_handler(logger, level.lower(), level=level) return handler_name = "%s.%s" % (filename, level.lower()) handler = { "class": "systemd.journal.JournalHandler", "level": level } handler.update(kwargs) else: # basename of a plain-text log log_directory = os.path.normpath(self.log_directory) if not os.path.isdir(log_directory): warning = Warning( 'Missing directory, you can create it with \nmkdir -p "%s"' % log_directory, hint=None, obj=log_directory, ) settings_check_results.append(warning) self.add_handler(logger, "stdout", level=level, **kwargs) return basename = "%s-%s.log" % (self.log_suffix, filename) log_filename = os.path.join(log_directory, basename) try: remove = not os.path.exists(log_filename) open(log_filename, "a").close() # ok, we can write if ( remove ): # but if this file did not exist, we remove it to avoid lot of empty log files... os.remove(log_filename) except PermissionError: warning_ = Warning( 'Unable to write logs in "%s". Unsufficient rights?' % log_directory, hint=None, obj=log_directory, ) settings_check_results.append(warning_) self.add_handler(logger, "stdout", level=level, **kwargs) handler_name = "%s.%s" % (self.log_suffix, filename) handler = { "class": "logging.handlers.RotatingFileHandler", "maxBytes": 1000000, "backupCount": 3, "formatter": "nocolor", "filename": log_filename, "level": level, } if handler_name not in self.handlers: self.handlers[handler_name] = handler if logger == "ROOT": self.root["handlers"].append(handler_name) else: self.loggers[logger]["handlers"].append(handler_name)