diff --git a/modoboa/core/app_settings.py b/modoboa/core/app_settings.py index d4c04f7e0..63c009777 100644 --- a/modoboa/core/app_settings.py +++ b/modoboa/core/app_settings.py @@ -2,9 +2,10 @@ from django import forms from django.conf import settings from django.utils.translation import ugettext as _, ugettext_lazy -from modoboa.lib.form_utils import YesNoField, SeparatorField, InlineRadioSelect -from modoboa.lib.cryptutils import random_key + from modoboa.lib import parameters +from modoboa.lib.cryptutils import random_key +from modoboa.lib.form_utils import YesNoField, SeparatorField, InlineRadioSelect def enabled_applications(): @@ -304,8 +305,9 @@ class GeneralParametersForm(parameters.AdminParametersForm): required_fields = ["ldap_user_dn_template"] for f in required_fields: - if not f in cleaned_data or cleaned_data[f] == u'': - self._errors[f] = self.error_class([_("This field is required")]) + if f not in cleaned_data or cleaned_data[f] == u'': + self._errors[f] = self.error_class( + [_("This field is required")]) return cleaned_data @@ -341,14 +343,20 @@ class GeneralParametersForm(parameters.AdminParametersForm): )) if values["ldap_auth_method"] == "searchbind": setattr(settings, "AUTH_LDAP_BIND_DN", values["ldap_bind_dn"]) - setattr(settings, "AUTH_LDAP_BIND_PASSWORD", values["ldap_bind_password"]) + setattr( + settings, "AUTH_LDAP_BIND_PASSWORD", + values["ldap_bind_password"] + ) search = LDAPSearch( values["ldap_search_base"], ldap.SCOPE_SUBTREE, values["ldap_search_filter"] ) setattr(settings, "AUTH_LDAP_USER_SEARCH", search) else: - setattr(settings, "AUTH_LDAP_USER_DN_TEMPLATE", values["ldap_user_dn_template"]) + setattr( + settings, "AUTH_LDAP_USER_DN_TEMPLATE", + values["ldap_user_dn_template"] + ) if values["ldap_is_active_directory"] == "yes": if not hasattr(settings, "AUTH_LDAP_GLOBAL_OPTIONS"): setattr(settings, "AUTH_LDAP_GLOBAL_OPTIONS", { diff --git a/modoboa/core/commands/__init__.py b/modoboa/core/commands/__init__.py index 9b2b1c9f2..e95f987b2 100644 --- a/modoboa/core/commands/__init__.py +++ b/modoboa/core/commands/__init__.py @@ -1,7 +1,9 @@ # coding: utf-8 + +import argparse import os import sys -import argparse + from django.conf import settings from django.template import Context, Template @@ -71,6 +73,7 @@ def scan_for_commands(dirname=""): def handle_command_line(): + """Parse the command line.""" commands = scan_for_commands() parser = argparse.ArgumentParser( description="A set of utilities to ease the installation of Modoboa.", @@ -83,7 +86,7 @@ def handle_command_line(): help='A valid command name') (args, remaining) = parser.parse_known_args() - if not args.command in commands: + if args.command not in commands: print >> sys.stderr, "Unknown command '%s'" % args.command sys.exit(1) diff --git a/modoboa/core/commands/help.py b/modoboa/core/commands/help.py index dfe46307c..ab6960d00 100644 --- a/modoboa/core/commands/help.py +++ b/modoboa/core/commands/help.py @@ -1,9 +1,12 @@ # coding: utf-8 + import sys + from . import Command class HelpCommand(Command): + help = "Display the help message associated to a specific command" def __init__(self, *args, **kwargs): @@ -12,7 +15,7 @@ class HelpCommand(Command): help='A command name') def handle(self, parsed_args): - if not parsed_args.name in self._commands: + if parsed_args.name not in self._commands: print >>sys.stderr, "Unknown command: %s" % parsed_args.name sys.exit(1) cmd = self._commands[parsed_args.name](self._commands) diff --git a/modoboa/core/extensions.py b/modoboa/core/extensions.py index 03997c150..99a89f7a3 100644 --- a/modoboa/core/extensions.py +++ b/modoboa/core/extensions.py @@ -1,3 +1,5 @@ +"""Extension management.""" + from django.conf import settings from django.conf.urls import include @@ -44,9 +46,9 @@ class ExtensionsPool(object): self.extensions[ext.name] = dict(cls=ext, show=show) def get_extension(self, name): - if not name in self.extensions: + if name not in self.extensions: return None - if not "instance" in self.extensions[name]: + if "instance" not in self.extensions[name]: self.extensions[name]["instance"] = self.extensions[name]["cls"]() return self.extensions[name]["instance"] @@ -54,7 +56,7 @@ class ExtensionsPool(object): """Check if an extension is enabled or not.""" from modoboa.core.models import Extension - if not name in self.extensions: + if name not in self.extensions: return False try: state = Extension.objects.get(name=name).enabled diff --git a/modoboa/core/forms.py b/modoboa/core/forms.py index 12c361797..a72f13d44 100644 --- a/modoboa/core/forms.py +++ b/modoboa/core/forms.py @@ -1,6 +1,10 @@ # coding: utf-8 + +"""Core forms.""" + from django import forms from django.utils.translation import ugettext as _, ugettext_lazy + from modoboa.core.models import User from modoboa.lib import parameters @@ -38,9 +42,9 @@ class ProfileForm(forms.ModelForm): model = User fields = ("first_name", "last_name") widgets = { - 'first_name': forms.TextInput(attrs={'class': 'form-control'}), - 'last_name': forms.TextInput(attrs={'class': 'form-control'}) - } + 'first_name': forms.TextInput(attrs={'class': 'form-control'}), + 'last_name': forms.TextInput(attrs={'class': 'form-control'}) + } def __init__(self, update_password, *args, **kwargs): super(ProfileForm, self).__init__(*args, **kwargs) @@ -61,15 +65,19 @@ class ProfileForm(forms.ModelForm): return self.cleaned_data["oldpassword"] def clean_confirmation(self): - if self.cleaned_data["newpassword"] != self.cleaned_data["confirmation"]: + newpassword = self.cleaned_data["newpassword"] + confirmation = self.cleaned_data["confirmation"] + if newpassword != confirmation: raise forms.ValidationError(_("Passwords mismatch")) return self.cleaned_data["confirmation"] def save(self, commit=True): user = super(ProfileForm, self).save(commit=False) if commit: - if self.cleaned_data.has_key("confirmation") and \ - self.cleaned_data["confirmation"] != "": - user.set_password(self.cleaned_data["confirmation"], self.cleaned_data["oldpassword"]) + if self.cleaned_data.get("confirmation", "") != "": + user.set_password( + self.cleaned_data["confirmation"], + self.cleaned_data["oldpassword"] + ) user.save() return user diff --git a/modoboa/core/management/commands/clean_unknown_extensions.py b/modoboa/core/management/commands/clean_unknown_extensions.py index f22c13852..d0a297fea 100644 --- a/modoboa/core/management/commands/clean_unknown_extensions.py +++ b/modoboa/core/management/commands/clean_unknown_extensions.py @@ -21,6 +21,6 @@ class Command(BaseCommand): """Entry point.""" for extension in Extension.objects.all(): fullname = "modoboa.extensions.{0}".format(extension.name) - if not fullname in settings.MODOBOA_APPS: + if fullname not in settings.MODOBOA_APPS: extension.delete() connection.close() diff --git a/modoboa/core/management/commands/manage_extensions.py b/modoboa/core/management/commands/manage_extensions.py index 24133a1e0..af90b1302 100644 --- a/modoboa/core/management/commands/manage_extensions.py +++ b/modoboa/core/management/commands/manage_extensions.py @@ -53,6 +53,6 @@ class Command(BaseCommand, CloseConnectionMixin): for extname in args: fullname = "modoboa.extensions.{0}".format(extname) - if not fullname in settings.MODOBOA_APPS: + if fullname not in settings.MODOBOA_APPS: continue self._change_extension_state(extname, options) diff --git a/modoboa/core/models.py b/modoboa/core/models.py index 29f3be872..93f32451f 100644 --- a/modoboa/core/models.py +++ b/modoboa/core/models.py @@ -1,27 +1,33 @@ -import sys +"""Core models.""" + +import logging import os import re -import logging -import reversion -from django.db import models -from django.db.models.signals import post_delete +import sys + from django.conf import settings -from django.dispatch import receiver -from django.utils import timezone -from django.utils.translation import ugettext as _, ugettext_lazy -from django.contrib.contenttypes.models import ContentType -from django.contrib.contenttypes import generic +from django.contrib.auth.hashers import make_password, is_password_usable from django.contrib.auth.models import ( UserManager, Group, PermissionsMixin ) -from django.contrib.auth.hashers import make_password, is_password_usable +from django.contrib.contenttypes import generic +from django.contrib.contenttypes.models import ContentType +from django.db import models +from django.db.models.signals import post_delete +from django.dispatch import receiver +from django.utils import timezone +from django.utils.translation import ugettext as _, ugettext_lazy + +import reversion + +from modoboa.core.extensions import exts_pool +from modoboa.core.password_hashers import get_password_hasher from modoboa.lib import events, parameters from modoboa.lib.exceptions import ( PermDeniedException, InternalError, BadRequest, Conflict ) from modoboa.lib.sysutils import exec_cmd -from modoboa.core.extensions import exts_pool -from modoboa.core.password_hashers import get_password_hasher + try: from modoboa.lib.ldap_utils import LDAPAuthBackend @@ -242,7 +248,8 @@ class User(PermissionsMixin): """ ct = ContentType.objects.get_for_model(obj) try: - ooentry = self.objectaccess_set.get(content_type=ct, object_id=obj.id) + ooentry = self.objectaccess_set.get( + content_type=ct, object_id=obj.id) except ObjectAccess.DoesNotExist: return False return ooentry.is_owner @@ -263,7 +270,8 @@ class User(PermissionsMixin): ct = ContentType.objects.get_for_model(obj) try: - ooentry = self.objectaccess_set.get(content_type=ct, object_id=obj.id) + ooentry = self.objectaccess_set.get( + content_type=ct, object_id=obj.id) except ObjectAccess.DoesNotExist: pass else: @@ -333,7 +341,8 @@ class User(PermissionsMixin): if len(row) < 7: raise BadRequest(_("Invalid line")) role = row[6].strip() - if not user.is_superuser and not role in ["SimpleUsers", "DomainAdmins"]: + allowed_roles = ["SimpleUsers", "DomainAdmins"] + if not user.is_superuser and role not in allowed_roles: raise PermDeniedException( _("You can't import an account with a role greater than yours") ) @@ -345,13 +354,15 @@ class User(PermissionsMixin): else: raise Conflict if role == "SimpleUsers": - if (len(row) < 8 or not row[7].strip()): + if len(row) < 8 or not row[7].strip(): raise BadRequest( - _("The simple user '%s' must have a valid email address" % self.username) + _("The simple user '%s' must have a valid email address" + % self.username) ) if self.username != row[7].strip(): raise BadRequest( - _("username and email fields must not differ for '%s'" % self.username) + _("username and email fields must not differ for '%s'" + % self.username) ) if crypt_password: @@ -374,9 +385,16 @@ class User(PermissionsMixin): :param csvwriter: csv object """ - row = ["account", self.username.encode("utf-8"), self.password.encode("utf-8"), - self.first_name.encode("utf-8"), self.last_name.encode("utf-8"), - self.is_active, self.group, self.email.encode("utf-8")] + row = [ + "account", + self.username.encode("utf-8"), + self.password.encode("utf-8"), + self.first_name.encode("utf-8"), + self.last_name.encode("utf-8"), + self.is_active, + self.group, + self.email.encode("utf-8") + ] row += events.raiseQueryEvent("AccountExported", self) csvwriter.writerow(row) @@ -414,7 +432,9 @@ class ObjectAccess(models.Model): unique_together = (("user", "content_type", "object_id"),) def __unicode__(self): - return "%s => %s (%s)" % (self.user, self.content_object, self.content_type) + return "%s => %s (%s)" % ( + self.user, self.content_object, self.content_type + ) class Extension(models.Model): @@ -501,7 +521,7 @@ def post_revision_commit(sender, **kwargs): """ from modoboa.lib.signals import get_request - current_user = get_request().user.username + current_user = get_request().user.username logger = logging.getLogger("modoboa.admin") for version in kwargs["versions"]: if version.object is None: diff --git a/modoboa/core/templatetags/core_tags.py b/modoboa/core/templatetags/core_tags.py index 9cbed9c08..9c9830c33 100644 --- a/modoboa/core/templatetags/core_tags.py +++ b/modoboa/core/templatetags/core_tags.py @@ -1,10 +1,14 @@ +"""Custom tags for Core application.""" + import re + from django import template +from django.contrib.sessions.models import Session +from django.core.urlresolvers import reverse from django.template.loader import render_to_string from django.utils import timezone from django.utils.translation import ugettext as _ -from django.core.urlresolvers import reverse -from django.contrib.sessions.models import Session + from modoboa.lib import events @@ -125,7 +129,7 @@ def colorize_level(level): "WARNING": "text-warning", "CRITICAL": "text-danger" } - if not level in classes: + if level not in classes: return level return "

%s

" % (classes[level], level) @@ -140,7 +144,7 @@ def tohtml(message): def visirule(field): if not hasattr(field, 'form') or \ not hasattr(field.form, "visirules") or \ - not field.html_name in field.form.visirules: + field.html_name not in field.form.visirules: return "" rule = field.form.visirules[field.html_name] return " data-visibility-field='%s' data-visibility-value='%s' " \ diff --git a/modoboa/core/tests.py b/modoboa/core/tests.py index 56ed41f2e..8c3608dae 100644 --- a/modoboa/core/tests.py +++ b/modoboa/core/tests.py @@ -74,7 +74,8 @@ class ModoboaAdminCommandTestCase(TestCase): categories = ["std", "autoreply", "relaydomains"] dburl = "{0}://user:password@localhost/testdb".format(engine) code, output = exec_cmd( - "modoboa-admin.py postfix_maps --categories {0} --dburl {1} {2}".format( + "modoboa-admin.py postfix_maps --categories {0}" + " --dburl {1} {2}".format( " ".join(categories), dburl, self.workdir ) ) diff --git a/modoboa/core/views/admin.py b/modoboa/core/views/admin.py index a81af1880..b4b36e056 100644 --- a/modoboa/core/views/admin.py +++ b/modoboa/core/views/admin.py @@ -1,15 +1,12 @@ """ Views available to super administrators only. """ - -from django.shortcuts import render -from django.template.loader import render_to_string -from django.utils.translation import ugettext as _ - from django.contrib.auth.decorators import ( login_required, user_passes_test ) - +from django.shortcuts import render +from django.template.loader import render_to_string +from django.utils.translation import ugettext as _ from modoboa.core.models import Extension, Log from modoboa.core.utils import new_version_available @@ -88,12 +85,12 @@ def saveextensions(request): if k.startswith("select_"): parts = k.split("_", 1) dbext = Extension.objects.get(name=parts[1]) - if not dbext in actived_exts: + if dbext not in actived_exts: dbext.on() else: found += [dbext] for ext in actived_exts: - if not ext in found: + if ext not in found: ext.off() return render_to_json_response(_("Modifications applied.")) diff --git a/modoboa/core/views/auth.py b/modoboa/core/views/auth.py index d46ef3ea2..44325a366 100644 --- a/modoboa/core/views/auth.py +++ b/modoboa/core/views/auth.py @@ -1,16 +1,19 @@ # coding: utf-8 import logging -from django.views.decorators.cache import never_cache + from django.contrib.auth import authenticate, login, logout -from django.http import HttpResponse, HttpResponseRedirect from django.core.urlresolvers import reverse +from django.http import HttpResponse, HttpResponseRedirect from django.utils.translation import ugettext as _ +from django.views.decorators.cache import never_cache + +from modoboa.core.forms import LoginForm from modoboa.lib import events, parameters from modoboa.lib.web_utils import _render_to_string -from modoboa.core.forms import LoginForm def dologin(request): + """Try to authenticate.""" error = None if request.method == "POST": form = LoginForm(request.POST) @@ -43,7 +46,7 @@ def dologin(request): error = _( "Your username and password didn't match. Please try again.") logger.warning( - "Failed connection attempt from '%(addr)s' as user '%(user)s'" \ + "Failed connection attempt from '%(addr)s' as user '%(user)s'" % {"addr": request.META["REMOTE_ADDR"], "user": form.cleaned_data["username"]} ) diff --git a/modoboa/core/views/user.py b/modoboa/core/views/user.py index 3cc2ec53d..7c444bbd6 100644 --- a/modoboa/core/views/user.py +++ b/modoboa/core/views/user.py @@ -1,12 +1,15 @@ +"""Simple user views.""" + +from django.contrib.auth.decorators import login_required from django.shortcuts import render from django.utils.translation import ugettext as _ -from django.contrib.auth.decorators import login_required + +from modoboa.core.forms import ProfileForm from modoboa.lib import events, parameters +from modoboa.lib.cryptutils import encrypt from modoboa.lib.web_utils import ( _render_to_string, render_to_json_response ) -from modoboa.lib.cryptutils import encrypt -from modoboa.core.forms import ProfileForm @login_required @@ -31,7 +34,8 @@ def profile(request, tplname='core/user_profile.html'): if form.is_valid(): form.save() if update_password and form.cleaned_data["confirmation"] != "": - request.session["password"] = encrypt(form.cleaned_data["confirmation"]) + request.session["password"] = encrypt( + form.cleaned_data["confirmation"]) return render_to_json_response(_("Profile updated")) return render_to_json_response({'form_errors': form.errors}, status=400) diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 000000000..a7854adaf --- /dev/null +++ b/setup.cfg @@ -0,0 +1,3 @@ +[pep8] +max-line-length = 80 +exclude = migrations