diff --git a/orchestra/apps/users/__init__.py b/orchestra/apps/users/__init__.py
deleted file mode 100644
index e69de29b..00000000
diff --git a/orchestra/apps/users/admin.py b/orchestra/apps/users/admin.py
deleted file mode 100644
index 6451d0af..00000000
--- a/orchestra/apps/users/admin.py
+++ /dev/null
@@ -1,110 +0,0 @@
-from django.conf.urls import patterns, url
-from django.core.urlresolvers import reverse
-from django.contrib import admin
-from django.contrib.admin.util import unquote
-from django.contrib.auth import admin as auth
-from django.utils.translation import ugettext, ugettext_lazy as _
-
-from orchestra.admin import ExtendedModelAdmin
-from orchestra.admin.utils import wrap_admin_view
-from orchestra.apps.accounts.admin import AccountAdminMixin
-
-from .forms import UserCreationForm, UserChangeForm
-from .models import User
-from .roles.filters import role_list_filter_factory
-
-
-class UserAdmin(AccountAdminMixin, auth.UserAdmin, ExtendedModelAdmin):
- list_display = ('username', 'display_is_main')
- list_filter = ('is_staff', 'is_superuser', 'is_active')
- fieldsets = (
- (None, {
- 'fields': ('account', 'username', 'password')
- }),
- (_("Personal info"), {
- 'fields': ('first_name', 'last_name', 'email')
- }),
- (_("Permissions"), {
- 'fields': ('is_active', 'is_staff', 'is_superuser', 'display_is_main')
- }),
- (_("Important dates"), {
- 'fields': ('last_login', 'date_joined')
- }),
- )
- add_fieldsets = (
- (None, {
- 'classes': ('wide',),
- 'fields': ('username', 'password1', 'password2', 'account'),
- }),
- )
- search_fields = ['username', 'account__user__username']
- readonly_fields = ('display_is_main', 'account_link')
- change_readonly_fields = ('username',)
- filter_horizontal = ()
- add_form = UserCreationForm
- form = UserChangeForm
- roles = []
- ordering = ('-id',)
- change_form_template = 'admin/users/user/change_form.html'
-
- def display_is_main(self, instance):
- return instance.is_main
- display_is_main.short_description = _("is main")
- display_is_main.boolean = True
-
- def get_urls(self):
- """ Returns the additional urls for the change view links """
- urls = super(UserAdmin, self).get_urls()
- opts = self.model._meta
- new_urls = patterns("")
- for role in self.roles:
- new_urls += patterns("",
- url('^(\d+)/%s/$' % role.url_name,
- wrap_admin_view(self, role().change_view),
- name='%s_%s_%s_change' % (opts.app_label, opts.model_name, role.name)),
- url('^(\d+)/%s/delete/$' % role.url_name,
- wrap_admin_view(self, role().delete_view),
- name='%s_%s_%s_delete' % (opts.app_label, opts.model_name, role.name))
- )
- return new_urls + urls
-
- def get_fieldsets(self, request, obj=None):
- fieldsets = super(UserAdmin, self).get_fieldsets(request, obj=obj)
- if obj and obj.account:
- fieldsets[0][1]['fields'] = ('account_link',) + fieldsets[0][1]['fields'][1:]
- return fieldsets
-
- def get_list_display(self, request):
- roles = []
- for role in self.roles:
- def has_role(user, role_class=role):
- role = role_class(user=user)
- if role.exists:
- return ''
- url = reverse('admin:users_user_%s_change' % role.name, args=(user.pk,))
- false = ''
- return '%s' % (url, false)
- has_role.short_description = _("Has %s") % role.name
- has_role.admin_order_field = role.name
- has_role.allow_tags = True
- roles.append(has_role)
- return list(self.list_display) + roles + ['account_link']
-
- def get_list_filter(self, request):
- roles = [ role_list_filter_factory(role) for role in self.roles ]
- return list(self.list_filter) + roles
-
- def change_view(self, request, object_id, **kwargs):
- user = self.get_object(User, unquote(object_id))
- extra_context = kwargs.get('extra_context', {})
- extra_context['roles'] = [ role(user=user) for role in self.roles ]
- kwargs['extra_context'] = extra_context
- return super(UserAdmin, self).change_view(request, object_id, **kwargs)
-
- def get_queryset(self, request):
- """ Select related for performance """
- related = ['account__user'] + [ role.name for role in self.roles ]
- return super(UserAdmin, self).get_queryset(request).select_related(*related)
-
-
-admin.site.register(User, UserAdmin)
diff --git a/orchestra/apps/users/api.py b/orchestra/apps/users/api.py
deleted file mode 100644
index dda373e5..00000000
--- a/orchestra/apps/users/api.py
+++ /dev/null
@@ -1,20 +0,0 @@
-from django.contrib.auth import get_user_model
-from rest_framework import viewsets
-
-from orchestra.api import router, SetPasswordApiMixin
-from orchestra.apps.accounts.api import AccountApiMixin
-
-from .serializers import UserSerializer
-
-
-class UserViewSet(AccountApiMixin, SetPasswordApiMixin, viewsets.ModelViewSet):
- model = get_user_model()
- serializer_class = UserSerializer
-
- def get_queryset(self):
- """ select related roles """
- qs = super(UserViewSet, self).get_queryset()
- return qs.select_related(*self.inserted)
-
-
-router.register(r'users', UserViewSet)
diff --git a/orchestra/apps/users/backends.py b/orchestra/apps/users/backends.py
deleted file mode 100644
index 1af71f40..00000000
--- a/orchestra/apps/users/backends.py
+++ /dev/null
@@ -1,123 +0,0 @@
-import textwrap
-
-from django.utils import timezone
-from django.utils.translation import ugettext_lazy as _
-
-from orchestra.apps.orchestration import ServiceController
-from orchestra.apps.resources import ServiceMonitor
-
-from . import settings
-
-
-class SystemUserBackend(ServiceController):
- verbose_name = _("System User")
- model = 'users.User'
- ignore_fields = ['last_login']
-
- def save(self, user):
- context = self.get_context(user)
- if user.is_main:
- self.append(textwrap.dedent("""
- if [[ $( id %(username)s ) ]]; then
- usermod --password '%(password)s' %(username)s
- else
- useradd %(username)s --password '%(password)s' \\
- --shell /bin/false
- fi
- mkdir -p %(home)s
- chown %(username)s.%(username)s %(home)s""" % context
- ))
- else:
- self.delete(user)
-
- def delete(self, user):
- context = self.get_context(user)
- self.append("{ sleep 2 && killall -u %(username)s -s KILL; } &" % context)
- self.append("killall -u %(username)s" % context)
- self.append("userdel %(username)s" % context)
-
- def get_context(self, user):
- context = {
- 'username': user.username,
- 'password': user.password if user.is_active else '*%s' % user.password,
- }
- context['home'] = settings.USERS_SYSTEMUSER_HOME % context
- return context
-
-
-class SystemUserDisk(ServiceMonitor):
- model = 'users.User'
- resource = ServiceMonitor.DISK
- verbose_name = _('System user disk')
-
- def monitor(self, user):
- context = self.get_context(user)
- self.append("du -s %(home)s | xargs echo %(object_id)s" % context)
-
- def get_context(self, user):
- context = SystemUserBackend().get_context(user)
- context['object_id'] = user.pk
- return context
-
-
-class FTPTraffic(ServiceMonitor):
- model = 'users.User'
- resource = ServiceMonitor.TRAFFIC
- verbose_name = _('FTP traffic')
-
- def prepare(self):
- current_date = timezone.localtime(self.current_date)
- current_date = current_date.strftime("%Y%m%d%H%M%S")
- self.append(textwrap.dedent("""
- function monitor () {
- OBJECT_ID=$1
- INI_DATE=$2
- USERNAME="$3"
- LOG_FILE="$4"
- grep "UPLOAD\|DOWNLOAD" "${LOG_FILE}" \\
- | grep " \\[${USERNAME}\\] " \\
- | awk -v ini="${INI_DATE}" '
- BEGIN {
- end = "%s"
- sum = 0
- months["Jan"] = "01"
- months["Feb"] = "02"
- months["Mar"] = "03"
- months["Apr"] = "04"
- months["May"] = "05"
- months["Jun"] = "06"
- months["Jul"] = "07"
- months["Aug"] = "08"
- months["Sep"] = "09"
- months["Oct"] = "10"
- months["Nov"] = "11"
- months["Dec"] = "12"
- } {
- # log: Fri Jul 11 13:23:17 2014
- split($4, t, ":")
- # line_date = year month day hour minute second
- line_date = $5 months[$2] $3 t[1] t[2] t[3]
- if ( line_date > ini && line_date < end)
- split($0, l, "\\", ")
- split(l[3], b, " ")
- sum += b[1]
- } END {
- print sum
- }
- ' | xargs echo ${OBJECT_ID}
- }""" % current_date))
-
- def monitor(self, user):
- context = self.get_context(user)
- self.append(
- 'monitor %(object_id)i %(last_date)s "%(username)s" "%(log_file)s"' % context)
-
- def get_context(self, user):
- last_date = timezone.localtime(self.get_last_date(user.pk))
- return {
- 'log_file': settings.USERS_FTP_LOG_PATH,
- 'last_date': last_date.strftime("%Y%m%d%H%M%S"),
- 'object_id': user.pk,
- 'username': user.username,
- }
-
diff --git a/orchestra/apps/users/forms.py b/orchestra/apps/users/forms.py
deleted file mode 100644
index 42c52ac5..00000000
--- a/orchestra/apps/users/forms.py
+++ /dev/null
@@ -1,49 +0,0 @@
-from django import forms
-from django.contrib import auth
-from django.utils.translation import ugettext, ugettext_lazy as _
-
-from orchestra.core.validators import validate_password
-
-from .models import User
-
-
-class UserCreationForm(auth.forms.UserCreationForm):
- class Meta(auth.forms.UserCreationForm.Meta):
- model = User
-
- def __init__(self, *args, **kwargs):
- super(UserCreationForm, self).__init__(*args, **kwargs)
- self.fields['password1'].validators.append(validate_password)
-
- def clean_username(self):
- # Since User.username is unique, this check is redundant,
- # but it sets a nicer error message than the ORM. See #13147.
- username = self.cleaned_data["username"]
- try:
- User._default_manager.get(username=username)
- except User.DoesNotExist:
- return username
- raise forms.ValidationError(self.error_messages['duplicate_username'])
-
-
-class UserChangeForm(forms.ModelForm):
- password = auth.forms.ReadOnlyPasswordHashField(label=_("Password"),
- help_text=_("Raw passwords are not stored, so there is no way to see "
- "this user's password, but you can change the password "
- "using this form."))
-
- class Meta:
- model = User
- fields = '__all__'
-
- def __init__(self, *args, **kwargs):
- super(UserChangeForm, self).__init__(*args, **kwargs)
- f = self.fields.get('user_permissions', None)
- if f is not None:
- f.queryset = f.queryset.select_related('content_type')
-
- def clean_password(self):
- # Regardless of what the user provides, return the initial value.
- # This is done here, rather than on the field, because the
- # field does not have access to the initial value
- return self.initial["password"]
diff --git a/orchestra/apps/users/models.py b/orchestra/apps/users/models.py
deleted file mode 100644
index b91b72aa..00000000
--- a/orchestra/apps/users/models.py
+++ /dev/null
@@ -1,92 +0,0 @@
-from django.contrib.auth import models as auth
-from django.core import validators
-from django.core.mail import send_mail
-from django.db import models
-from django.utils import timezone
-from django.utils.translation import ugettext_lazy as _
-
-from orchestra.core import services
-
-
-class User(auth.AbstractBaseUser):
- username = models.CharField(_("username"), max_length=64, unique=True,
- help_text=_("Required. 30 characters or fewer. Letters, digits and "
- "./-/_ only."),
- validators=[validators.RegexValidator(r'^[\w.-]+$',
- _("Enter a valid username."), 'invalid')])
- account = models.ForeignKey('accounts.Account', verbose_name=_("Account"),
- related_name='users')
- first_name = models.CharField(_("first name"), max_length=30, blank=True)
- last_name = models.CharField(_("last name"), max_length=30, blank=True)
- email = models.EmailField(_('email address'), blank=True)
- is_superuser = models.BooleanField(_("superuser status"), default=False,
- help_text=_("Designates that this user has all permissions without "
- "explicitly assigning them."))
- is_staff = models.BooleanField(_("staff status"), default=False,
- help_text=_("Designates whether the user can log into this admin "
- "site."))
- is_admin = models.BooleanField(_("admin status"), default=False,
- help_text=_("Designates whether the user can administrate its account."))
- is_active = models.BooleanField(_("active"), default=True,
- help_text=_("Designates whether this user should be treated as "
- "active. Unselect this instead of deleting accounts."))
- date_joined = models.DateTimeField(_("date joined"), default=timezone.now)
-
- objects = auth.UserManager()
-
- USERNAME_FIELD = 'username'
- REQUIRED_FIELDS = ['email']
-
- @property
- def is_main(self):
- return self.account.user == self
-
- def get_full_name(self):
- full_name = '%s %s' % (self.first_name, self.last_name)
- return full_name.strip() or self.username
-
- def get_short_name(self):
- """ Returns the short name for the user """
- return self.first_name
-
- def email_user(self, subject, message, from_email=None, **kwargs):
- """ Sends an email to this User """
- send_mail(subject, message, from_email, [self.email], **kwargs)
-
- def has_perm(self, perm, obj=None):
- """
- Returns True if the user has the specified permission. This method
- queries all available auth backends, but returns immediately if any
- backend returns True. Thus, a user who has permission from a single
- auth backend is assumed to have permission in general. If an object is
- provided, permissions for this specific object are checked.
- """
- # Active superusers have all permissions.
- if self.is_active and self.is_superuser:
- return True
- # Otherwise we need to check the backends.
- return auth._user_has_perm(self, perm, obj)
-
- def has_perms(self, perm_list, obj=None):
- """
- Returns True if the user has each of the specified permissions. If
- object is passed, it checks if the user has all required perms for this
- object.
- """
- for perm in perm_list:
- if not self.has_perm(perm, obj):
- return False
- return True
-
- def has_module_perms(self, app_label):
- """
- Returns True if the user has any permissions in the given app label.
- Uses pretty much the same logic as has_perm, above.
- """
- # Active superusers have all permissions.
- if self.is_active and self.is_superuser:
- return True
- return auth._user_has_module_perms(self, app_label)
-
-
-services.register(User, menu=False)
diff --git a/orchestra/apps/users/roles/__init__.py b/orchestra/apps/users/roles/__init__.py
deleted file mode 100644
index 62b9ee6f..00000000
--- a/orchestra/apps/users/roles/__init__.py
+++ /dev/null
@@ -1,27 +0,0 @@
-from ..models import User
-
-
-class Register(object):
- def __init__(self):
- self._registry = {}
-
- def __contains__(self, key):
- return key in self._registry
-
- def register(self, name, model):
- if name in self._registry:
- raise KeyError("%s already registered" % name)
- def has_role(user, model=model):
- try:
- getattr(user, name)
- except model.DoesNotExist:
- return False
- return True
- setattr(User, 'has_%s' % name, has_role)
- self._registry[name] = model
-
- def get(self):
- return self._registry
-
-
-roles = Register()
diff --git a/orchestra/apps/users/roles/admin.py b/orchestra/apps/users/roles/admin.py
deleted file mode 100644
index 0432a682..00000000
--- a/orchestra/apps/users/roles/admin.py
+++ /dev/null
@@ -1,145 +0,0 @@
-from django.contrib import messages
-from django.contrib.admin.util import unquote, get_deleted_objects
-from django.contrib.admin.templatetags.admin_urls import add_preserved_filters
-from django.db import router
-from django.http import Http404, HttpResponseRedirect
-from django.template.response import TemplateResponse
-from django.shortcuts import redirect
-from django.utils.encoding import force_text
-from django.utils.html import escape
-from django.utils.translation import ugettext, ugettext_lazy as _
-
-from orchestra.admin.utils import get_modeladmin, change_url
-
-from .forms import role_form_factory
-from ..models import User
-
-
-class RoleAdmin(object):
- model = None
- name = ''
- url_name = ''
- form = None
-
- def __init__(self, user=None):
- self.user = user
-
- @property
- def exists(self):
- try:
- return getattr(self.user, self.name)
- except self.model.DoesNotExist:
- return False
-
- def get_user(self, request, object_id):
- try:
- user = User.objects.get(pk=unquote(object_id))
- except User.DoesNotExist:
- opts = self.model._meta
- raise Http404(
- _('%(name)s object with primary key %(key)r does not exist.') %
- {'name': force_text(opts.verbose_name), 'key': escape(object_id)}
- )
- return user
-
- def change_view(self, request, object_id):
- modeladmin = get_modeladmin(User)
- user = self.get_user(request, object_id)
- self.user = user
- obj = None
- exists = self.exists
- if exists:
- obj = getattr(user, self.name)
- form_class = self.form if self.form else role_form_factory(self)
- form = form_class(instance=obj)
- opts = User._meta
- app_label = opts.app_label
- title = _("Add %s for user %s" % (self.name, user))
- action = _("Create")
- # User has submitted the form
- if request.method == 'POST':
- form = form_class(request.POST, instance=obj)
- form.user = user
- if form.is_valid():
- obj = form.save()
- context = {
- 'name': obj._meta.verbose_name,
- 'obj': obj,
- 'action': _("saved" if exists else "created")
- }
- modeladmin.log_change(request, request.user, "%s saved" % self.name.capitalize())
- msg = _('The role %(name)s for user "%(obj)s" was %(action)s successfully.') % context
- modeladmin.message_user(request, msg, messages.SUCCESS)
- if not "_continue" in request.POST:
- return redirect(change_url(user))
- exists = True
-
- if exists:
- title = _("Change %s %s settings" % (user, self.name))
- action = _("Save")
- form = form_class(instance=obj)
-
- context = {
- 'title': title,
- 'opts': opts,
- 'app_label': app_label,
- 'form': form,
- 'action': action,
- 'role': self,
- 'roles': [ role(user=user) for role in modeladmin.roles ],
- 'media': modeladmin.media
- }
-
- template = 'admin/users/user/role.html'
- app = modeladmin.admin_site.name
- return TemplateResponse(request, template, context, current_app=app)
-
- def delete_view(self, request, object_id):
- "The 'delete' admin view for this model."
- opts = self.model._meta
- app_label = opts.app_label
- modeladmin = get_modeladmin(User)
- user = self.get_user(request, object_id)
- obj = getattr(user, self.name)
-
- using = router.db_for_write(self.model)
-
- # Populate deleted_objects, a data structure of all related objects that
- # will also be deleted.
- (deleted_objects, perms_needed, protected) = get_deleted_objects(
- [obj], opts, request.user, modeladmin.admin_site, using)
-
- if request.POST: # The user has already confirmed the deletion.
- if perms_needed:
- raise PermissionDenied
- obj_display = force_text(obj)
- modeladmin.log_deletion(request, obj, obj_display)
- modeladmin.delete_model(request, obj)
- post_url = change_url(user)
- preserved_filters = modeladmin.get_preserved_filters(request)
- post_url = add_preserved_filters(
- {'preserved_filters': preserved_filters, 'opts': opts}, post_url
- )
- return HttpResponseRedirect(post_url)
-
- object_name = force_text(opts.verbose_name)
-
- if perms_needed or protected:
- title = _("Cannot delete %(name)s") % {"name": object_name}
- else:
- title = _("Are you sure?")
-
- context = {
- "title": title,
- "object_name": object_name,
- "object": obj,
- "deleted_objects": deleted_objects,
- "perms_lacking": perms_needed,
- "protected": protected,
- "opts": opts,
- "app_label": app_label,
- 'preserved_filters': modeladmin.get_preserved_filters(request),
- 'role': self,
- }
- return TemplateResponse(request, 'admin/users/user/delete_role.html',
- context, current_app=modeladmin.admin_site.name)
diff --git a/orchestra/apps/users/roles/filters.py b/orchestra/apps/users/roles/filters.py
deleted file mode 100644
index 7bac9a3b..00000000
--- a/orchestra/apps/users/roles/filters.py
+++ /dev/null
@@ -1,23 +0,0 @@
-from django.contrib.admin import SimpleListFilter
-from django.utils.translation import ugettext_lazy as _
-
-
-def role_list_filter_factory(role):
- class RoleListFilter(SimpleListFilter):
- """ Filter Nodes by group according to request.user """
- title = _("has %s" % role.name)
- parameter_name = role.url_name
-
- def lookups(self, request, model_admin):
- return (
- ('True', _("Yes")),
- ('False', _("No")),
- )
-
- def queryset(self, request, queryset):
- if self.value() == 'True':
- return queryset.filter(**{ '%s__isnull' % role.name: False })
- if self.value() == 'False':
- return queryset.filter(**{ '%s__isnull' % role.name: True })
-
- return RoleListFilter
diff --git a/orchestra/apps/users/roles/forms.py b/orchestra/apps/users/roles/forms.py
deleted file mode 100644
index decc6610..00000000
--- a/orchestra/apps/users/roles/forms.py
+++ /dev/null
@@ -1,17 +0,0 @@
-from django import forms
-
-
-class RoleAdminBaseForm(forms.ModelForm):
- class Meta:
- exclude = ('user', )
-
- def save(self, *args, **kwargs):
- self.instance.user = self.user
- return super(RoleAdminBaseForm, self).save(*args, **kwargs)
-
-
-def role_form_factory(role):
- class RoleAdminForm(RoleAdminBaseForm):
- class Meta(RoleAdminBaseForm.Meta):
- model = role.model
- return RoleAdminForm
diff --git a/orchestra/apps/users/roles/jabber/__init__.py b/orchestra/apps/users/roles/jabber/__init__.py
deleted file mode 100644
index e69de29b..00000000
diff --git a/orchestra/apps/users/roles/jabber/admin.py b/orchestra/apps/users/roles/jabber/admin.py
deleted file mode 100644
index ba126c0f..00000000
--- a/orchestra/apps/users/roles/jabber/admin.py
+++ /dev/null
@@ -1,15 +0,0 @@
-from django.contrib.auth import get_user_model
-
-from orchestra.admin.utils import insertattr
-from orchestra.apps.users.roles.admin import RoleAdmin
-
-from .models import Jabber
-
-
-class JabberRoleAdmin(RoleAdmin):
- model = Jabber
- name = 'jabber'
- url_name = 'jabber'
-
-
-insertattr(get_user_model(), 'roles', JabberRoleAdmin)
diff --git a/orchestra/apps/users/roles/jabber/models.py b/orchestra/apps/users/roles/jabber/models.py
deleted file mode 100644
index 32850579..00000000
--- a/orchestra/apps/users/roles/jabber/models.py
+++ /dev/null
@@ -1,15 +0,0 @@
-from django.db import models
-from django.utils.translation import ugettext_lazy as _
-
-from .. import roles
-
-
-class Jabber(models.Model):
- user = models.OneToOneField('users.User', verbose_name=_("user"),
- related_name='jabber')
-
- def __unicode__(self):
- return str(self.user)
-
-
-roles.register('jabber', Jabber)
diff --git a/orchestra/apps/users/roles/mail/__init__.py b/orchestra/apps/users/roles/mail/__init__.py
deleted file mode 100644
index e69de29b..00000000
diff --git a/orchestra/apps/users/roles/mail/admin.py b/orchestra/apps/users/roles/mail/admin.py
deleted file mode 100644
index 58d3fa56..00000000
--- a/orchestra/apps/users/roles/mail/admin.py
+++ /dev/null
@@ -1,124 +0,0 @@
-from django import forms
-from django.contrib import admin
-from django.contrib.auth import get_user_model
-from django.core.urlresolvers import reverse
-from django.utils.translation import ugettext_lazy as _
-
-from orchestra.admin import ExtendedModelAdmin
-from orchestra.admin.utils import insertattr, admin_link
-from orchestra.apps.accounts.admin import SelectAccountAdminMixin
-from orchestra.apps.users.roles.admin import RoleAdmin
-
-from .forms import MailRoleAdminForm
-from .models import Mailbox, Address, Autoresponse
-
-
-class AutoresponseInline(admin.StackedInline):
- model = Autoresponse
- verbose_name_plural = _("autoresponse")
-
- def formfield_for_dbfield(self, db_field, **kwargs):
- if db_field.name == 'subject':
- kwargs['widget'] = forms.TextInput(attrs={'size':'118'})
- return super(AutoresponseInline, self).formfield_for_dbfield(db_field, **kwargs)
-
-
-#class AddressAdmin(SelectAccountAdminMixin, ExtendedModelAdmin):
-# list_display = ('email', 'domain_link', 'mailboxes', 'forwards', 'account_link')
-# fields = ('account_link', ('name', 'domain'), 'destination')
-# inlines = [AutoresponseInline]
-# search_fields = ('name', 'domain__name',)
-# readonly_fields = ('account_link', 'domain_link', 'email_link')
-# filter_by_account_fields = ['domain']
-#
-# domain_link = link('domain', order='domain__name')
-#
-# def email_link(self, address):
-# link = self.domain_link(address)
-# return "%s@%s" % (address.name, link)
-# email_link.short_description = _("Email")
-# email_link.allow_tags = True
-#
-# def mailboxes(self, address):
-# boxes = []
-# for mailbox in address.get_mailboxes():
-# user = mailbox.user
-# url = reverse('admin:users_user_mailbox_change', args=(user.pk,))
-# boxes.append('%s' % (url, user.username))
-# return '
'.join(boxes)
-# mailboxes.allow_tags = True
-#
-# def forwards(self, address):
-# values = [ dest for dest in address.destination.split() if '@' in dest ]
-# return '
'.join(values)
-# forwards.allow_tags = True
-#
-# def formfield_for_dbfield(self, db_field, **kwargs):
-# if db_field.name == 'destination':
-# kwargs['widget'] = forms.TextInput(attrs={'size':'118'})
-# return super(AddressAdmin, self).formfield_for_dbfield(db_field, **kwargs)
-#
-# def queryset(self, request):
-# """ Select related for performance """
-# qs = super(AddressAdmin, self).queryset(request)
-# return qs.select_related('domain')
-
-
-class AddressAdmin(SelectAccountAdminMixin, ExtendedModelAdmin):
- list_display = (
- 'email', 'domain_link', 'display_mailboxes', 'display_forward', 'account_link'
- )
- fields = ('account_link', ('name', 'domain'), 'mailboxes', 'forward')
- inlines = [AutoresponseInline]
- search_fields = ('name', 'domain__name',)
- readonly_fields = ('account_link', 'domain_link', 'email_link')
- filter_by_account_fields = ['domain']
- filter_horizontal = ['mailboxes']
-
- domain_link = admin_link('domain', order='domain__name')
-
- def email_link(self, address):
- link = self.domain_link(address)
- return "%s@%s" % (address.name, link)
- email_link.short_description = _("Email")
- email_link.allow_tags = True
-
- def display_mailboxes(self, address):
- boxes = []
- for mailbox in address.mailboxes.all():
- user = mailbox.user
- url = reverse('admin:users_user_mailbox_change', args=(user.pk,))
- boxes.append('%s' % (url, user.username))
- return '
'.join(boxes)
- display_mailboxes.short_description = _("Mailboxes")
- display_mailboxes.allow_tags = True
-
- def display_forward(self, address):
- values = [ dest for dest in address.forward.split() ]
- return '
'.join(values)
- display_forward.short_description = _("Forward")
- display_forward.allow_tags = True
-
- def formfield_for_dbfield(self, db_field, **kwargs):
- if db_field.name == 'forward':
- kwargs['widget'] = forms.TextInput(attrs={'size':'118'})
- if db_field.name == 'mailboxes':
- mailboxes = db_field.rel.to.objects.select_related('user')
- kwargs['queryset'] = mailboxes.filter(user__account=self.account)
- return super(AddressAdmin, self).formfield_for_dbfield(db_field, **kwargs)
-
- def get_queryset(self, request):
- """ Select related for performance """
- qs = super(AddressAdmin, self).get_queryset(request)
- return qs.select_related('domain')
-
-
-class MailRoleAdmin(RoleAdmin):
- model = Mailbox
- name = 'mailbox'
- url_name = 'mailbox'
- form = MailRoleAdminForm
-
-
-admin.site.register(Address, AddressAdmin)
-insertattr(get_user_model(), 'roles', MailRoleAdmin)
diff --git a/orchestra/apps/users/roles/mail/api.py b/orchestra/apps/users/roles/mail/api.py
deleted file mode 100644
index 410d8a1c..00000000
--- a/orchestra/apps/users/roles/mail/api.py
+++ /dev/null
@@ -1,27 +0,0 @@
-from rest_framework import viewsets
-
-from orchestra.api import router
-from orchestra.apps.accounts.api import AccountApiMixin
-
-from .models import Address, Mailbox
-from .serializers import AddressSerializer, MailboxSerializer
-
-
-class AddressViewSet(AccountApiMixin, viewsets.ModelViewSet):
- model = Address
- serializer_class = AddressSerializer
-
-
-
-class MailboxViewSet(viewsets.ModelViewSet):
- model = Mailbox
- serializer_class = MailboxSerializer
-
- def get_queryset(self):
- qs = super(MailboxViewSet, self).get_queryset()
- qs = qs.select_related('user')
- return qs.filter(user__account=self.request.user.account_id)
-
-
-router.register(r'mailboxes', MailboxViewSet)
-router.register(r'addresses', AddressViewSet)
diff --git a/orchestra/apps/users/roles/mail/backends.py b/orchestra/apps/users/roles/mail/backends.py
deleted file mode 100644
index b29d03ae..00000000
--- a/orchestra/apps/users/roles/mail/backends.py
+++ /dev/null
@@ -1,160 +0,0 @@
-import os
-
-from django.utils import timezone
-from django.utils.translation import ugettext_lazy as _
-
-from orchestra.apps.orchestration import ServiceController
-from orchestra.apps.resources import ServiceMonitor
-
-from . import settings
-from .models import Address
-
-
-class MailSystemUserBackend(ServiceController):
- verbose_name = _("Mail system user")
- model = 'mail.Mailbox'
- # TODO related_models = ('resources__content_type') ??
-
- DEFAULT_GROUP = 'postfix'
-
- def create_user(self, context):
- self.append(
- "if [[ $( id %(username)s ) ]]; then \n"
- " usermod -p '%(password)s' %(username)s \n"
- "else \n"
- " useradd %(username)s --password '%(password)s' \\\n"
- " --shell /dev/null \n"
- "fi" % context
- )
- self.append("mkdir -p %(home)s" % context)
- self.append("chown %(username)s.%(group)s %(home)s" % context)
-
- def generate_filter(self, mailbox, context):
- now = timezone.now().strftime("%B %d, %Y, %H:%M")
- context['filtering'] = (
- "# Sieve Filter\n"
- "# Generated by Orchestra %s\n\n" % now
- )
- if mailbox.use_custom_filtering:
- context['filtering'] += mailbox.custom_filtering
- else:
- context['filtering'] += settings.EMAILS_DEFAUL_FILTERING
- context['filter_path'] = os.path.join(context['home'], '.orchestra.sieve')
- self.append("echo '%(filtering)s' > %(filter_path)s" % context)
-
- def save(self, mailbox):
- context = self.get_context(mailbox)
- self.create_user(context)
- self.generate_filter(mailbox, context)
-
- def delete(self, mailbox):
- context = self.get_context(mailbox)
- self.append("{ sleep 2 && killall -u %(username)s -s KILL; } &" % context)
- self.append("killall -u %(username)s" % context)
- self.append("userdel %(username)s" % context)
- self.append("rm -fr %(home)s" % context)
-
- def get_context(self, mailbox):
- user = mailbox.user
- context = {
- 'username': user.username,
- 'password': user.password if user.is_active else '*%s' % user.password,
- 'group': self.DEFAULT_GROUP
- }
- context['home'] = settings.EMAILS_HOME % context
- return context
-
-
-class PostfixAddressBackend(ServiceController):
- verbose_name = _("Postfix address")
- model = 'mail.Address'
-
- def include_virtdomain(self, context):
- self.append(
- '[[ $(grep "^\s*%(domain)s\s*$" %(virtdomains)s) ]]'
- ' || { echo "%(domain)s" >> %(virtdomains)s; UPDATED=1; }' % context
- )
-
- def exclude_virtdomain(self, context):
- domain = context['domain']
- if not Address.objects.filter(domain=domain).exists():
- self.append('sed -i "s/^%(domain)s//" %(virtdomains)s' % context)
-
- def update_virtusertable(self, context):
- self.append(
- 'LINE="%(email)s\t%(destination)s"\n'
- 'if [[ ! $(grep "^%(email)s\s" %(virtusertable)s) ]]; then\n'
- ' echo "$LINE" >> %(virtusertable)s\n'
- ' UPDATED=1\n'
- 'else\n'
- ' if [[ ! $(grep "^${LINE}$" %(virtusertable)s) ]]; then\n'
- ' sed -i "s/^%(email)s\s.*$/${LINE}/" %(virtusertable)s\n'
- ' UPDATED=1\n'
- ' fi\n'
- 'fi' % context
- )
-
- def exclude_virtusertable(self, context):
- self.append(
- 'if [[ $(grep "^%(email)s\s") ]]; then\n'
- ' sed -i "s/^%(email)s\s.*$//" %(virtusertable)s\n'
- ' UPDATED=1\n'
- 'fi'
- )
-
- def save(self, address):
- context = self.get_context(address)
- self.include_virtdomain(context)
- self.update_virtusertable(context)
-
- def delete(self, address):
- context = self.get_context(address)
- self.exclude_virtdomain(context)
- self.exclude_virtusertable(context)
-
- def commit(self):
- context = self.get_context_files()
- self.append('[[ $UPDATED == 1 ]] && { '
- 'postmap %(virtdomains)s;'
- 'postmap %(virtusertable)s;'
- '}' % context)
-
- def get_context_files(self):
- return {
- 'virtdomains': settings.EMAILS_VIRTDOMAINS_PATH,
- 'virtusertable': settings.EMAILS_VIRTUSERTABLE_PATH,
- }
-
- def get_context(self, address):
- context = self.get_context_files()
- context.update({
- 'domain': address.domain,
- 'email': address.email,
- 'destination': address.destination,
- })
- return context
-
-
-class AutoresponseBackend(ServiceController):
- verbose_name = _("Mail autoresponse")
- model = 'mail.Autoresponse'
-
-
-class MaildirDisk(ServiceMonitor):
- model = 'email.Mailbox'
- resource = ServiceMonitor.DISK
- verbose_name = _("Maildir disk usage")
-
- def monitor(self, mailbox):
- context = self.get_context(mailbox)
- self.append(
- "SIZE=$(sed -n '2p' %(maildir_path)s | cut -d' ' -f1)\n"
- "echo %(object_id)s ${SIZE:-0}" % context
- )
-
- def get_context(self, mailbox):
- context = MailSystemUserBackend().get_context(mailbox)
- context['home'] = settings.EMAILS_HOME % context
- context['maildir_path'] = os.path.join(context['home'], 'Maildir/maildirsize')
- context['object_id'] = mailbox.pk
- return context
diff --git a/orchestra/apps/users/roles/mail/forms.py b/orchestra/apps/users/roles/mail/forms.py
deleted file mode 100644
index 7066e5d0..00000000
--- a/orchestra/apps/users/roles/mail/forms.py
+++ /dev/null
@@ -1,53 +0,0 @@
-from django import forms
-from django.core.urlresolvers import reverse
-from django.utils.safestring import mark_safe
-from django.utils.translation import ugettext_lazy as _
-
-from orchestra.forms.widgets import ReadOnlyWidget
-
-from .models import Mailbox
-from ..forms import RoleAdminBaseForm
-
-
-class MailRoleAdminForm(RoleAdminBaseForm):
- class Meta(RoleAdminBaseForm.Meta):
- model = Mailbox
-
- def __init__(self, *args, **kwargs):
- super(MailRoleAdminForm, self).__init__(*args, **kwargs)
- instance = kwargs.get('instance')
- if instance:
- widget = ReadOnlyWidget(self.addresses(instance))
- self.fields['addresses'] = forms.CharField(widget=widget,
- label=_("Addresses"))
-
-# def addresses(self, mailbox):
-# account = mailbox.user.account
-# addresses = account.addresses.filter(destination__contains=mailbox.user.username)
-# add_url = reverse('admin:mail_address_add')
-# add_url += '?account=%d&destination=%s' % (account.pk, mailbox.user.username)
-# img = ''
-# onclick = 'onclick="return showAddAnotherPopup(this);"'
-# add_link = '%s Add address' % (add_url, onclick, img)
-# value = '%s
' % add_link
-# for pk, name, domain in addresses.values_list('pk', 'name', 'domain__name'):
-# url = reverse('admin:mail_address_change', args=(pk,))
-# name = '%s@%s' % (name, domain)
-# value += '
%s' % (url, name)
-# value = '' % value
-# return mark_safe('%s
' % value)
-
- def addresses(self, mailbox):
- account = mailbox.user.account
- add_url = reverse('admin:mail_address_add')
- add_url += '?account=%d&mailboxes=%s' % (account.pk, mailbox.pk)
- img = ''
- onclick = 'onclick="return showAddAnotherPopup(this);"'
- add_link = '%s Add address' % (add_url, onclick, img)
- value = '%s
' % add_link
- for pk, name, domain in mailbox.addresses.values_list('pk', 'name', 'domain__name'):
- url = reverse('admin:mail_address_change', args=(pk,))
- name = '%s@%s' % (name, domain)
- value += '%s' % (url, name)
- value = '' % value
- return mark_safe('%s
' % value)
diff --git a/orchestra/apps/users/roles/mail/models.py b/orchestra/apps/users/roles/mail/models.py
deleted file mode 100644
index 35d28355..00000000
--- a/orchestra/apps/users/roles/mail/models.py
+++ /dev/null
@@ -1,110 +0,0 @@
-from django.db import models
-from django.utils.translation import ugettext_lazy as _
-
-from orchestra.core import services
-
-from .. import roles
-
-from . import validators, settings
-
-
-class Mailbox(models.Model):
- user = models.OneToOneField('users.User', verbose_name=_("User"),
- related_name='mailbox')
- use_custom_filtering = models.BooleanField(_("Use custom filtering"),
- default=False)
- custom_filtering = models.TextField(_("filtering"), blank=True,
- validators=[validators.validate_sieve],
- help_text=_("Arbitrary email filtering in sieve language."))
-
- class Meta:
- verbose_name_plural = _("mailboxes")
-
- def __unicode__(self):
- return self.user.username
-
-# def get_addresses(self):
-# regex = r'(^|\s)+%s(\s|$)+' % self.user.username
-# return Address.objects.filter(destination__regex=regex)
-#
-# def delete(self, *args, **kwargs):
-# """ Update related addresses """
-# regex = re.compile(r'(^|\s)+(\s*%s)(\s|$)+' % self.user.username)
-# super(Mailbox, self).delete(*args, **kwargs)
-# for address in self.get_addresses():
-# address.destination = regex.sub(r'\3', address.destination).strip()
-# if not address.destination:
-# address.delete()
-# else:
-# address.save()
-
-
-#class Address(models.Model):
-# name = models.CharField(_("name"), max_length=64,
-# validators=[validators.validate_emailname])
-# domain = models.ForeignKey(settings.EMAILS_DOMAIN_MODEL,
-# verbose_name=_("domain"),
-# related_name='addresses')
-# destination = models.CharField(_("destination"), max_length=256,
-# validators=[validators.validate_destination],
-# help_text=_("Space separated mailbox names or email addresses"))
-# account = models.ForeignKey('accounts.Account', verbose_name=_("Account"),
-# related_name='addresses')
-#
-# class Meta:
-# verbose_name_plural = _("addresses")
-# unique_together = ('name', 'domain')
-#
-# def __unicode__(self):
-# return self.email
-#
-# @property
-# def email(self):
-# return "%s@%s" % (self.name, self.domain)
-#
-# def get_mailboxes(self):
-# for dest in self.destination.split():
-# if '@' not in dest:
-# yield Mailbox.objects.select_related('user').get(user__username=dest)
-
-
-class Address(models.Model):
- name = models.CharField(_("name"), max_length=64,
- validators=[validators.validate_emailname])
- domain = models.ForeignKey(settings.EMAILS_DOMAIN_MODEL,
- verbose_name=_("domain"),
- related_name='addresses')
- mailboxes = models.ManyToManyField('mail.Mailbox',
- verbose_name=_("mailboxes"),
- related_name='addresses', blank=True)
- forward = models.CharField(_("forward"), max_length=256, blank=True,
- validators=[validators.validate_forward])
- account = models.ForeignKey('accounts.Account', verbose_name=_("Account"),
- related_name='addresses')
-
- class Meta:
- verbose_name_plural = _("addresses")
- unique_together = ('name', 'domain')
-
- def __unicode__(self):
- return self.email
-
- @property
- def email(self):
- return "%s@%s" % (self.name, self.domain)
-
-
-class Autoresponse(models.Model):
- address = models.OneToOneField(Address, verbose_name=_("address"),
- related_name='autoresponse')
- # TODO initial_date
- subject = models.CharField(_("subject"), max_length=256)
- message = models.TextField(_("message"))
- enabled = models.BooleanField(_("enabled"), default=False)
-
- def __unicode__(self):
- return self.address
-
-
-services.register(Address)
-roles.register('mailbox', Mailbox)
diff --git a/orchestra/apps/users/roles/mail/serializers.py b/orchestra/apps/users/roles/mail/serializers.py
deleted file mode 100644
index 24bf1a70..00000000
--- a/orchestra/apps/users/roles/mail/serializers.py
+++ /dev/null
@@ -1,43 +0,0 @@
-from rest_framework import serializers
-
-from orchestra.api import router
-from orchestra.apps.accounts.serializers import AccountSerializerMixin
-
-from .models import Address, Mailbox
-
-
-#class AddressSerializer(serializers.HyperlinkedModelSerializer):
-# class Meta:
-# model = Address
-# fields = ('url', 'name', 'domain', 'destination')
-
-
-class NestedMailboxSerializer(serializers.HyperlinkedModelSerializer):
- class Meta:
- model = Mailbox
- fields = ('url', 'use_custom_filtering', 'custom_filtering')
-
-
-class MailboxSerializer(serializers.HyperlinkedModelSerializer):
- class Meta:
- model = Mailbox
- fields = ('url', 'user', 'use_custom_filtering', 'custom_filtering')
-
-
-class AddressSerializer(AccountSerializerMixin, serializers.HyperlinkedModelSerializer):
- class Meta:
- model = Address
- fields = ('url', 'name', 'domain', 'mailboxes', 'forward')
-
- def get_fields(self, *args, **kwargs):
- fields = super(AddressSerializer, self).get_fields(*args, **kwargs)
- account = self.context['view'].request.user.account_id
- mailboxes = fields['mailboxes'].queryset.select_related('user')
- fields['mailboxes'].queryset = mailboxes.filter(user__account=account)
- # TODO do it on permissions or in self.filter_by_account_field ?
- domain = fields['domain'].queryset
- fields['domain'].queryset = domain .filter(account=account)
- return fields
-
-
-router.insert('users', 'mailbox', NestedMailboxSerializer, required=False)
diff --git a/orchestra/apps/users/roles/mail/settings.py b/orchestra/apps/users/roles/mail/settings.py
deleted file mode 100644
index fcca1e32..00000000
--- a/orchestra/apps/users/roles/mail/settings.py
+++ /dev/null
@@ -1,29 +0,0 @@
-from django.conf import settings
-
-
-EMAILS_DOMAIN_MODEL = getattr(settings, 'EMAILS_DOMAIN_MODEL', 'domains.Domain')
-
-EMAILS_HOME = getattr(settings, 'EMAILS_HOME', '/home/%(username)s/')
-
-EMAILS_SIEVETEST_PATH = getattr(settings, 'EMAILS_SIEVETEST_PATH', '/dev/shm')
-
-EMAILS_SIEVETEST_BIN_PATH = getattr(settings, 'EMAILS_SIEVETEST_BIN_PATH',
- '%(orchestra_root)s/bin/sieve-test')
-
-
-EMAILS_VIRTUSERTABLE_PATH = getattr(settings, 'EMAILS_VIRTUSERTABLE_PATH',
- '/etc/postfix/virtusertable')
-
-
-EMAILS_VIRTDOMAINS_PATH = getattr(settings, 'EMAILS_VIRTDOMAINS_PATH',
- '/etc/postfix/virtdomains')
-
-
-EMAILS_DEFAUL_FILTERING = getattr(settings, 'EMAILS_DEFAULT_FILTERING',
- 'require ["fileinto","regex","envelope","vacation","reject","relational","comparator-i;ascii-numeric"];\n'
- '\n'
- 'if header :value "ge" :comparator "i;ascii-numeric" "X-Spam-Score" "5" {\n'
- ' fileinto "Junk";\n'
- ' discard;\n'
- '}'
-)
diff --git a/orchestra/apps/users/roles/mail/validators.py b/orchestra/apps/users/roles/mail/validators.py
deleted file mode 100644
index eab400fa..00000000
--- a/orchestra/apps/users/roles/mail/validators.py
+++ /dev/null
@@ -1,62 +0,0 @@
-import hashlib
-import os
-import re
-
-from django.core.validators import ValidationError, EmailValidator
-from django.utils.translation import ugettext_lazy as _
-
-from orchestra.utils import paths
-from orchestra.utils.system import run
-
-from . import settings
-
-
-def validate_emailname(value):
- msg = _("'%s' is not a correct email name" % value)
- if '@' in value:
- raise ValidationError(msg)
- value += '@localhost'
- try:
- EmailValidator(value)
- except ValidationError:
- raise ValidationError(msg)
-
-
-#def validate_destination(value):
-# """ space separated mailboxes or emails """
-# for destination in value.split():
-# msg = _("'%s' is not an existent mailbox" % destination)
-# if '@' in destination:
-# if not destination[-1].isalpha():
-# raise ValidationError(msg)
-# EmailValidator(destination)
-# else:
-# from .models import Mailbox
-# if not Mailbox.objects.filter(user__username=destination).exists():
-# raise ValidationError(msg)
-# validate_emailname(destination)
-
-
-def validate_forward(value):
- """ space separated mailboxes or emails """
- for destination in value.split():
- EmailValidator(destination)
-
-
-def validate_sieve(value):
- sieve_name = '%s.sieve' % hashlib.md5(value).hexdigest()
- path = os.path.join(settings.EMAILS_SIEVETEST_PATH, sieve_name)
- with open(path, 'wb') as f:
- f.write(value)
- context = {
- 'orchestra_root': paths.get_orchestra_root()
- }
- sievetest = settings.EMAILS_SIEVETEST_BIN_PATH % context
- test = run(' '.join([sievetest, path, '/dev/null']), display=False)
- if test.return_code:
- errors = []
- for line in test.stderr.splitlines():
- error = re.match(r'^.*(line\s+[0-9]+:.*)', line)
- if error:
- errors += error.groups()
- raise ValidationError(' '.join(errors))
diff --git a/orchestra/apps/users/roles/owncloud/__init__.py b/orchestra/apps/users/roles/owncloud/__init__.py
deleted file mode 100644
index e69de29b..00000000
diff --git a/orchestra/apps/users/roles/posix/__init__.py b/orchestra/apps/users/roles/posix/__init__.py
deleted file mode 100644
index e69de29b..00000000
diff --git a/orchestra/apps/users/roles/posix/admin.py b/orchestra/apps/users/roles/posix/admin.py
deleted file mode 100644
index 0ef5af77..00000000
--- a/orchestra/apps/users/roles/posix/admin.py
+++ /dev/null
@@ -1,15 +0,0 @@
-from django.contrib.auth import get_user_model
-
-from orchestra.admin.utils import insertattr
-from orchestra.apps.users.roles.admin import RoleAdmin
-
-from .models import POSIX
-
-
-class POSIXRoleAdmin(RoleAdmin):
- model = POSIX
- name = 'posix'
- url_name = 'posix'
-
-
-insertattr(get_user_model(), 'roles', POSIXRoleAdmin)
diff --git a/orchestra/apps/users/roles/posix/models.py b/orchestra/apps/users/roles/posix/models.py
deleted file mode 100644
index 3639afc9..00000000
--- a/orchestra/apps/users/roles/posix/models.py
+++ /dev/null
@@ -1,22 +0,0 @@
-from django.db import models
-from django.utils.translation import ugettext_lazy as _
-
-from .. import roles
-
-from . import settings
-
-
-class POSIX(models.Model):
- user = models.OneToOneField('users.User', verbose_name=_("user"),
- related_name='posix')
- home = models.CharField(_("home"), max_length=256, blank=True,
- help_text=_("Home directory relative to account's ~primary_user"))
- shell = models.CharField(_("shell"), max_length=32,
- choices=settings.POSIX_SHELLS, default=settings.POSIX_DEFAULT_SHELL)
-
- def __unicode__(self):
- return str(self.user)
-
-# TODO groups
-
-roles.register('posix', POSIX)
diff --git a/orchestra/apps/users/roles/posix/serializers.py b/orchestra/apps/users/roles/posix/serializers.py
deleted file mode 100644
index 3dc341c5..00000000
--- a/orchestra/apps/users/roles/posix/serializers.py
+++ /dev/null
@@ -1,14 +0,0 @@
-from rest_framework import serializers
-
-from orchestra.api import router
-
-from .models import POSIX
-
-
-class POSIXSerializer(serializers.ModelSerializer):
- class Meta:
- model = POSIX
- fields = ('home', 'shell')
-
-
-router.insert('users', 'posix', POSIXSerializer, required=False)
diff --git a/orchestra/apps/users/roles/posix/settings.py b/orchestra/apps/users/roles/posix/settings.py
deleted file mode 100644
index 36860863..00000000
--- a/orchestra/apps/users/roles/posix/settings.py
+++ /dev/null
@@ -1,11 +0,0 @@
-from django.conf import settings
-from django.utils.translation import ugettext, ugettext_lazy as _
-
-
-POSIX_SHELLS = getattr(settings, 'POSIX_SHELLS', (
- ('/bin/false', _("FTP/sFTP only")),
- ('/bin/rsync', _("rsync shell")),
- ('/bin/bash', "Bash"),
-))
-
-POSIX_DEFAULT_SHELL = getattr(settings, 'POSIX_DEFAULT_SHELL', '/bin/false')
diff --git a/orchestra/apps/users/serializers.py b/orchestra/apps/users/serializers.py
deleted file mode 100644
index 321e8b02..00000000
--- a/orchestra/apps/users/serializers.py
+++ /dev/null
@@ -1,35 +0,0 @@
-from django.contrib.auth import get_user_model
-from django.forms import widgets
-from django.utils.translation import ugettext, ugettext_lazy as _
-from rest_framework import serializers
-
-from orchestra.apps.accounts.serializers import AccountSerializerMixin
-from orchestra.core.validators import validate_password
-
-
-class UserSerializer(AccountSerializerMixin, serializers.HyperlinkedModelSerializer):
- password = serializers.CharField(max_length=128, label=_('Password'),
- validators=[validate_password], write_only=True, required=False,
- widget=widgets.PasswordInput)
-
- class Meta:
- model = get_user_model()
- fields = (
- 'url', 'username', 'password', 'first_name', 'last_name', 'email',
- 'is_admin', 'is_active',
- )
-
- def validate_password(self, attrs, source):
- """ POST only password """
- if self.object.pk:
- if 'password' in attrs:
- raise serializers.ValidationError(_("Can not set password"))
- elif 'password' not in attrs:
- raise serializers.ValidationError(_("Password required"))
- return attrs
-
- def save_object(self, obj, **kwargs):
- # FIXME this method will be called when saving nested serializers :(
- if not obj.pk:
- obj.set_password(obj.password)
- super(UserSerializer, self).save_object(obj, **kwargs)
diff --git a/orchestra/apps/users/settings.py b/orchestra/apps/users/settings.py
deleted file mode 100644
index 012099a4..00000000
--- a/orchestra/apps/users/settings.py
+++ /dev/null
@@ -1,6 +0,0 @@
-from django.conf import settings
-
-
-USERS_SYSTEMUSER_HOME = getattr(settings, 'USERES_SYSTEMUSER_HOME', '/home/%(username)s')
-
-USERS_FTP_LOG_PATH = getattr(settings, 'USERS_FTP_LOG_PATH', '/var/log/vsftpd.log')
diff --git a/orchestra/apps/users/templates/admin/users/user/change_form.html b/orchestra/apps/users/templates/admin/users/user/change_form.html
deleted file mode 100644
index 82814f98..00000000
--- a/orchestra/apps/users/templates/admin/users/user/change_form.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{% extends "admin/change_form.html" %}
-{% load i18n admin_urls %}
-
-{% block object-tools-items %}
- {% trans "User" %}
-{% for item in roles %}
- {% if item.exists %}{{ item.name.capitalize }}{% else %}Add {{ item.name }}{% endif %}
-{% endfor %}
-
- {% url opts|admin_urlname:'history' original.pk|admin_urlquote as history_url %}
- {% trans "History" %}
-
-{% if has_absolute_url %}{% trans "View on site" %}{% endif%}
-{% endblock %}
-
diff --git a/orchestra/apps/users/templates/admin/users/user/delete_role.html b/orchestra/apps/users/templates/admin/users/user/delete_role.html
deleted file mode 100644
index ae94df22..00000000
--- a/orchestra/apps/users/templates/admin/users/user/delete_role.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{% extends "admin/delete_confirmation.html" %}
-{% load i18n admin_urls %}
-
-
-{% block breadcrumbs %}
-
-{% endblock %}
-
diff --git a/orchestra/apps/users/templates/admin/users/user/role.html b/orchestra/apps/users/templates/admin/users/user/role.html
deleted file mode 100644
index 75927310..00000000
--- a/orchestra/apps/users/templates/admin/users/user/role.html
+++ /dev/null
@@ -1,70 +0,0 @@
-{% extends "admin/base_site.html" %}
-{% load i18n admin_urls admin_static admin_modify utils %}
-
-
-{% block extrastyle %}
-{{ block.super }}
-
-{{ media }}
-{% endblock %}
-
-{% block coltype %}colM{% endblock %}
-{% block bodyclass %}{{ block.super }} app-{{ opts.app_label }} model-{{ opts.model_name }} change-form{% endblock %}
-
-
-{% block breadcrumbs %}
-
-{% endblock %}
-
-
-
-{% block content %}
-{% block object-tools %}
-
-{% endblock %}
-
-
-
-{% endblock %}