Browse Source

Make permission management better

devel
Dmitry Novikov 8 years ago
parent
commit
84f6144950
  1. 4
      abonapp/locale/ru/LC_MESSAGES/django.po
  2. 19
      abonapp/models.py
  3. 16
      abonapp/templates/abonapp/editAbon.html
  4. 3
      abonapp/templates/abonapp/modal_passport_view.html
  5. 57
      abonapp/views.py
  6. 18
      accounts_app/forms.py
  7. 133
      accounts_app/locale/ru/LC_MESSAGES/django.po
  8. 4
      accounts_app/models.py
  9. 16
      accounts_app/templates/accounts/ext.htm
  10. 24
      accounts_app/templates/accounts/perms/change_global_perms.html
  11. 36
      accounts_app/templates/accounts/perms/ext.html
  12. 4
      accounts_app/templates/accounts/perms/object/objects_of_type.html
  13. 7
      accounts_app/templates/accounts/perms/object/objects_types.html
  14. 30
      accounts_app/templates/accounts/perms/object/perms_edit.html
  15. 7
      accounts_app/urls.py
  16. 52
      accounts_app/views.py
  17. 4
      devapp/locale/ru/LC_MESSAGES/django.po
  18. 3
      devapp/migrations/0001_initial.py
  19. 2
      devapp/migrations/0002_auto_20180409_1318.py
  20. 2
      devapp/migrations/0003_auto_20180529_1311.py
  21. 3
      devapp/models.py
  22. 6
      devapp/templates/devapp/manage_ports/modal_add_edit_port.html
  23. 6
      devapp/templates/devapp/modal_device_extra_edit.html
  24. 29
      devapp/views.py
  25. 4
      group_app/locale/ru/LC_MESSAGES/django.po
  26. 3
      group_app/migrations/0001_initial.py
  27. 2
      group_app/migrations/0003_auto_20180808_1236.py
  28. 3
      group_app/models.py
  29. 3
      group_app/views.py
  30. 3
      ip_pool/views.py
  31. 3
      mapapp/templates/maps/dot.html
  32. 8
      msg_app/locale/ru/LC_MESSAGES/django.po
  33. 6
      msg_app/models.py
  34. 7
      msg_app/views.py
  35. 1
      nas_app/views.py
  36. 3
      tariff_app/templates/tariff_app/periodic_pays/add_edit.html
  37. 4
      tariff_app/views.py
  38. 4
      taskapp/locale/ru/LC_MESSAGES/django.po
  39. 3
      taskapp/models.py
  40. 14
      taskapp/templates/taskapp/add_edit_task.html
  41. 18
      taskapp/templates/taskapp/comments/task_comments.html
  42. 19
      taskapp/views.py
  43. 54
      templates/base.html

4
abonapp/locale/ru/LC_MESSAGES/django.po

@ -168,10 +168,6 @@ msgstr "Маркер"
msgid "Buy service perm" msgid "Buy service perm"
msgstr "Покупка тарифа абоненту" msgstr "Покупка тарифа абоненту"
#: models.py:137
msgid "Can view passport"
msgstr "Может просматривать паспортные данные"
#: models.py:138 #: models.py:138
msgid "fill account" msgid "fill account"
msgstr "Пополнение счёта" msgstr "Пополнение счёта"

19
abonapp/models.py

@ -134,7 +134,6 @@ class Abon(BaseAccount):
db_table = 'abonent' db_table = 'abonent'
permissions = ( permissions = (
('can_buy_tariff', _('Buy service perm')), ('can_buy_tariff', _('Buy service perm')),
('can_view_passport', _('Can view passport')),
('can_add_ballance', _('fill account')), ('can_add_ballance', _('fill account')),
('can_ping', _('Can ping')) ('can_ping', _('Can ping'))
) )
@ -191,15 +190,15 @@ class Abon(BaseAccount):
) )
# Destroy the service if the time has come # Destroy the service if the time has come
def bill_service(self, author):
abon_tariff = self.active_tariff()
if abon_tariff is None:
return
nw = timezone.now()
# if service is overdue
if nw > abon_tariff.deadline:
print("Service %s for user %s is overdued, end service" % (abon_tariff.tariff, self))
abon_tariff.delete()
# def bill_service(self, author):
# abon_tariff = self.active_tariff()
# if abon_tariff is None:
# return
# nw = timezone.now()
# # if service is overdue
# if nw > abon_tariff.deadline:
# print("Service %s for user %s is overdued, end service" % (abon_tariff.tariff, self))
# abon_tariff.delete()
# is subscriber have access to service, view in tariff_app.custom_tariffs.<TariffBase>.manage_access() # is subscriber have access to service, view in tariff_app.custom_tariffs.<TariffBase>.manage_access()
def is_access(self) -> bool: def is_access(self) -> bool:

16
abonapp/templates/abonapp/editAbon.html

@ -22,16 +22,13 @@
{# telephone field #} {# telephone field #}
{% trans 'Call to' as tx %}
{% bootstrap_button '' button_type='link' icon='earphone' button_class='btn-default' title=tx href='sip:'|add:form.telephone.value size='sm' as btn_call %}
{% bootstrap_button '' button_type='link' icon='earphone' button_class='btn-default' title=_('Call to') href='sip:'|add:form.telephone.value size='sm' as btn_call %}
{% trans 'Additional telephones' as tx %}
{% url 'abonapp:telephones' group.pk abon.username as url %} {% url 'abonapp:telephones' group.pk abon.username as url %}
{% bootstrap_button '' button_type='link' icon='list' button_class='btn-default btn-modal' title=tx href=url size='sm' as btn_teleph_list %}
{% bootstrap_button '' button_type='link' icon='list' button_class='btn-default btn-modal' title=_('Additional telephones') href=url size='sm' as btn_teleph_list %}
{% trans 'Add telephone' as tx %}
{% url 'abonapp:telephone_new' group.pk abon.username as url %} {% url 'abonapp:telephone_new' group.pk abon.username as url %}
{% bootstrap_button '' button_type='link' icon='plus' button_class='btn-default btn-modal' title=tx href=url size='sm' as btn_teleph_add %}
{% bootstrap_button '' button_type='link' icon='plus' button_class='btn-default btn-modal' title=_('Add telephone') href=url size='sm' as btn_teleph_add %}
{% with ''|add:btn_call|add:btn_teleph_list|add:btn_teleph_add as bt %} {% with ''|add:btn_call|add:btn_teleph_list|add:btn_teleph_add as bt %}
{% bootstrap_field form.telephone form_group_class='form-group-sm' addon_after_class='input-group-btn' addon_after=bt %} {% bootstrap_field form.telephone form_group_class='form-group-sm' addon_after_class='input-group-btn' addon_after=bt %}
@ -69,11 +66,10 @@
<div class="form-group-sm"> <div class="form-group-sm">
<div class="btn-group btn-group-sm"> <div class="btn-group btn-group-sm">
{% trans 'Save' as tx %}
{% if perms.abonapp.change_abon %} {% if perms.abonapp.change_abon %}
{% bootstrap_button tx button_type='submit' icon='floppy-disk' button_class='btn-primary' %}
{% bootstrap_button _('Save') button_type='submit' icon='floppy-disk' button_class='btn-primary' %}
{% else %} {% else %}
{% bootstrap_button tx button_type='button' icon='floppy-disk' button_class='btn-primary disabled' %}
{% bootstrap_button _('Save') button_type='button' icon='floppy-disk' button_class='btn-primary disabled' %}
{% endif %} {% endif %}
{% if perms.taskapp.add_task %} {% if perms.taskapp.add_task %}
@ -98,7 +94,7 @@
</a> </a>
{% endif %} {% endif %}
{% if perms.abonapp.can_view_passport %}
{% if perms.abonapp.view_passportinfo %}
<a href="{% url 'abonapp:passport_view' group.pk abon.username %}" class="btn btn-default btn-modal"> <a href="{% url 'abonapp:passport_view' group.pk abon.username %}" class="btn btn-default btn-modal">
<span class="glyphicon glyphicon-paperclip"></span> {% trans 'Passport information' %} <span class="glyphicon glyphicon-paperclip"></span> {% trans 'Passport information' %}
</a> </a>

3
abonapp/templates/abonapp/modal_passport_view.html

@ -9,7 +9,6 @@
{% bootstrap_form form %} {% bootstrap_form form %}
{% trans 'Save' as tx %}
{% bootstrap_button tx button_type='submit' button_class='btn-primary' icon='floppy-disk' %}
{% bootstrap_button _('Save') button_type='submit' button_class='btn-primary' icon='floppy-disk' %}
</div> </div>
</form> </form>

57
abonapp/views.py

@ -67,7 +67,7 @@ class PeoplesListView(OrderedFilteredList):
if gid < 1: if gid < 1:
return HttpResponseBadRequest('group id is broken') return HttpResponseBadRequest('group id is broken')
group = get_object_or_404(Group, pk=gid) group = get_object_or_404(Group, pk=gid)
if not self.request.user.has_perm('group_app.can_view_group', group):
if not self.request.user.has_perm('group_app.view_group', group):
raise PermissionDenied raise PermissionDenied
context = super(PeoplesListView, self).get_context_data(**kwargs) context = super(PeoplesListView, self).get_context_data(**kwargs)
@ -86,7 +86,7 @@ class GroupListView(OrderedFilteredList):
def get_queryset(self): def get_queryset(self):
queryset = super(GroupListView, self).get_queryset() queryset = super(GroupListView, self).get_queryset()
queryset = get_objects_for_user(self.request.user, 'group_app.can_view_group', klass=queryset,
queryset = get_objects_for_user(self.request.user, 'group_app.view_group', klass=queryset,
accept_global_perms=False) accept_global_perms=False)
return queryset return queryset
@ -103,7 +103,7 @@ class AbonCreateView(CreateView):
def dispatch(self, request, *args, **kwargs): def dispatch(self, request, *args, **kwargs):
group = get_object_or_404(Group, pk=self.kwargs.get('gid')) group = get_object_or_404(Group, pk=self.kwargs.get('gid'))
if not request.user.has_perm('group_app.can_view_group', group):
if not request.user.has_perm('group_app.view_group', group):
raise PermissionDenied raise PermissionDenied
self.group = group self.group = group
return super(AbonCreateView, self).dispatch(request, *args, **kwargs) return super(AbonCreateView, self).dispatch(request, *args, **kwargs)
@ -127,7 +127,7 @@ class AbonCreateView(CreateView):
assign_perm("abonapp.change_abon", me, abon) assign_perm("abonapp.change_abon", me, abon)
assign_perm("abonapp.delete_abon", me, abon) assign_perm("abonapp.delete_abon", me, abon)
assign_perm("abonapp.can_buy_tariff", me, abon) assign_perm("abonapp.can_buy_tariff", me, abon)
assign_perm("abonapp.can_view_passport", me, abon)
assign_perm("abonapp.view_passportinfo", me, abon)
assign_perm('abonapp.can_add_ballance', me, abon) assign_perm('abonapp.can_add_ballance', me, abon)
me.log(self.request.META, 'cusr', '%s, "%s", %s' % ( me.log(self.request.META, 'cusr', '%s, "%s", %s' % (
abon.username, abon.fio, abon.username, abon.fio,
@ -159,7 +159,7 @@ class DelAbonDeleteView(DeleteView):
def get_object(self, queryset=None): def get_object(self, queryset=None):
abon = super(DelAbonDeleteView, self).get_object(queryset) abon = super(DelAbonDeleteView, self).get_object(queryset)
if not self.request.user.has_perm('group_app.can_view_group', abon.group):
if not self.request.user.has_perm('group_app.view_group', abon.group):
raise PermissionDenied raise PermissionDenied
return abon return abon
@ -223,7 +223,7 @@ def abonamount(request, gid: int, uname):
@method_decorator(login_decs, name='dispatch') @method_decorator(login_decs, name='dispatch')
@method_decorator(permission_required('group_app.can_view_group', (Group, 'pk', 'gid')), name='dispatch')
@method_decorator(permission_required('group_app.view_group', (Group, 'pk', 'gid')), name='dispatch')
class DebtsListView(OrderedFilteredList): class DebtsListView(OrderedFilteredList):
context_object_name = 'invoices' context_object_name = 'invoices'
template_name = 'abonapp/invoiceForPayment.html' template_name = 'abonapp/invoiceForPayment.html'
@ -241,7 +241,7 @@ class DebtsListView(OrderedFilteredList):
@method_decorator(login_decs, name='dispatch') @method_decorator(login_decs, name='dispatch')
@method_decorator(permission_required('group_app.can_view_group', (Group, 'pk', 'gid')), name='dispatch')
@method_decorator(permission_required('group_app.view_group', (Group, 'pk', 'gid')), name='dispatch')
class PayHistoryListView(OrderedFilteredList): class PayHistoryListView(OrderedFilteredList):
context_object_name = 'pay_history' context_object_name = 'pay_history'
template_name = 'abonapp/payHistory.html' template_name = 'abonapp/payHistory.html'
@ -263,7 +263,7 @@ class PayHistoryListView(OrderedFilteredList):
@lib.decorators.only_admins @lib.decorators.only_admins
def abon_services(request, gid: int, uname): def abon_services(request, gid: int, uname):
grp = get_object_or_404(Group, pk=gid) grp = get_object_or_404(Group, pk=gid)
if not request.user.has_perm('group_app.can_view_group', grp):
if not request.user.has_perm('group_app.view_group', grp):
raise PermissionDenied raise PermissionDenied
abon = get_object_or_404(models.Abon, username=uname) abon = get_object_or_404(models.Abon, username=uname)
@ -286,7 +286,7 @@ def abon_services(request, gid: int, uname):
@method_decorator(login_decs, name='dispatch') @method_decorator(login_decs, name='dispatch')
@method_decorator(permission_required('abonapp.change_abon'), name='post')
@method_decorator(permission_required('abonapp.view_abon'), name='post')
class AbonHomeUpdateView(UpdateView): class AbonHomeUpdateView(UpdateView):
model = models.Abon model = models.Abon
form_class = forms.AbonForm form_class = forms.AbonForm
@ -311,7 +311,7 @@ class AbonHomeUpdateView(UpdateView):
def get_object(self, queryset=None): def get_object(self, queryset=None):
gid = self.kwargs.get('gid') gid = self.kwargs.get('gid')
self.group = get_object_or_404(Group, pk=gid) self.group = get_object_or_404(Group, pk=gid)
if not self.request.user.has_perm('group_app.can_view_group', self.group):
if not self.request.user.has_perm('group_app.view_group', self.group):
raise PermissionDenied raise PermissionDenied
return super(AbonHomeUpdateView, self).get_object(queryset) return super(AbonHomeUpdateView, self).get_object(queryset)
@ -493,7 +493,7 @@ class DebtorsListView(ListView):
@method_decorator(login_decs, name='dispatch') @method_decorator(login_decs, name='dispatch')
@method_decorator(permission_required('group_app.can_view_group', (Group, 'pk', 'gid')), name='dispatch')
@method_decorator(permission_required('group_app.view_group', (Group, 'pk', 'gid')), name='dispatch')
class TaskLogListView(ListView): class TaskLogListView(ListView):
paginate_by = getattr(settings, 'PAGINATION_ITEMS_PER_PAGE', 10) paginate_by = getattr(settings, 'PAGINATION_ITEMS_PER_PAGE', 10)
http_method_names = ('get',) http_method_names = ('get',)
@ -513,7 +513,7 @@ class TaskLogListView(ListView):
@method_decorator(login_decs, name='dispatch') @method_decorator(login_decs, name='dispatch')
@method_decorator(permission_required('abonapp.can_view_passport'), name='dispatch')
@method_decorator(permission_required('abonapp.view_passportinfo'), name='dispatch')
class PassportUpdateView(UpdateView): class PassportUpdateView(UpdateView):
form_class = forms.PassportForm form_class = forms.PassportForm
model = models.PassportInfo model = models.PassportInfo
@ -602,7 +602,7 @@ def dev(request, gid: int, uname):
@login_required @login_required
@lib.decorators.only_admins @lib.decorators.only_admins
@permission_required('abonapp.change_abon') @permission_required('abonapp.change_abon')
@permission_required('group_app.can_view_group', (Group, 'pk', 'gid'))
@permission_required('group_app.view_group', (Group, 'pk', 'gid'))
def clear_dev(request, gid: int, uname): def clear_dev(request, gid: int, uname):
try: try:
abon = models.Abon.objects.get(username=uname) abon = models.Abon.objects.get(username=uname)
@ -619,7 +619,7 @@ def clear_dev(request, gid: int, uname):
@login_required @login_required
@lib.decorators.only_admins @lib.decorators.only_admins
@permission_required('group_app.can_view_group', (Group, 'pk', 'gid'))
@permission_required('group_app.view_group', (Group, 'pk', 'gid'))
def charts(request, gid: int, uname): def charts(request, gid: int, uname):
high = 100 high = 100
@ -771,7 +771,7 @@ class DialsListView(OrderedFilteredList):
def get_queryset(self): def get_queryset(self):
abon = get_object_or_404(models.Abon, username=self.kwargs.get('uname')) abon = get_object_or_404(models.Abon, username=self.kwargs.get('uname'))
if not self.request.user.has_perm('group_app.can_view_group', abon.group):
if not self.request.user.has_perm('group_app.view_group', abon.group):
raise PermissionDenied raise PermissionDenied
self.abon = abon self.abon = abon
if abon.telephone is not None and abon.telephone != '': if abon.telephone is not None and abon.telephone != '':
@ -856,7 +856,7 @@ def save_user_dev_port(request, gid: int, uname):
@login_required @login_required
@lib.decorators.only_admins @lib.decorators.only_admins
@permission_required('abonapp.add_abonstreet') @permission_required('abonapp.add_abonstreet')
@permission_required('group_app.can_view_group', (Group, 'pk', 'gid'))
@permission_required('group_app.view_group', (Group, 'pk', 'gid'))
def street_add(request, gid): def street_add(request, gid):
if request.method == 'POST': if request.method == 'POST':
frm = forms.AbonStreetForm(request.POST) frm = forms.AbonStreetForm(request.POST)
@ -877,7 +877,7 @@ def street_add(request, gid):
@login_required @login_required
@lib.decorators.only_admins @lib.decorators.only_admins
@permission_required('abonapp.change_abonstreet') @permission_required('abonapp.change_abonstreet')
@permission_required('group_app.can_view_group', (Group, 'pk', 'gid'))
@permission_required('group_app.view_group', (Group, 'pk', 'gid'))
def street_edit(request, gid): def street_edit(request, gid):
try: try:
if request.method == 'POST': if request.method == 'POST':
@ -901,7 +901,7 @@ def street_edit(request, gid):
@login_required @login_required
@lib.decorators.only_admins @lib.decorators.only_admins
@permission_required('abonapp.delete_abonstreet') @permission_required('abonapp.delete_abonstreet')
@permission_required('group_app.can_view_group', (Group, 'pk', 'gid'))
@permission_required('group_app.view_group', (Group, 'pk', 'gid'))
def street_del(request, gid: int, sid: int): def street_del(request, gid: int, sid: int):
try: try:
models.AbonStreet.objects.get(pk=sid, group=gid).delete() models.AbonStreet.objects.get(pk=sid, group=gid).delete()
@ -913,7 +913,7 @@ def street_del(request, gid: int, sid: int):
@login_required @login_required
@lib.decorators.only_admins @lib.decorators.only_admins
@permission_required('group_app.can_view_group', (Group, 'pk', 'gid'))
@permission_required('group_app.view_group', (Group, 'pk', 'gid'))
def active_nets(request, gid): def active_nets(request, gid):
nets = NetworkModel.objects.filter(groups__id=gid) nets = NetworkModel.objects.filter(groups__id=gid)
return render(request, 'abonapp/modal_current_networks.html', { return render(request, 'abonapp/modal_current_networks.html', {
@ -924,7 +924,7 @@ def active_nets(request, gid):
@login_required @login_required
@lib.decorators.only_admins @lib.decorators.only_admins
@permission_required('abonapp.can_view_additionaltelephones') @permission_required('abonapp.can_view_additionaltelephones')
@permission_required('group_app.can_view_group', (Group, 'pk', 'gid'))
@permission_required('group_app.view_group', (Group, 'pk', 'gid'))
def tels(request, gid: int, uname): def tels(request, gid: int, uname):
abon = get_object_or_404(models.Abon, username=uname) abon = get_object_or_404(models.Abon, username=uname)
telephones = abon.additional_telephones.all() telephones = abon.additional_telephones.all()
@ -937,7 +937,7 @@ def tels(request, gid: int, uname):
@login_required @login_required
@lib.decorators.only_admins @lib.decorators.only_admins
@permission_required('abnapp.add_additionaltelephone')
@permission_required('abonapp.add_additionaltelephone')
def tel_add(request, gid: int, uname): def tel_add(request, gid: int, uname):
if request.method == 'POST': if request.method == 'POST':
frm = forms.AdditionalTelephoneForm(request.POST) frm = forms.AdditionalTelephoneForm(request.POST)
@ -961,7 +961,7 @@ def tel_add(request, gid: int, uname):
@login_required @login_required
@lib.decorators.only_admins @lib.decorators.only_admins
@permission_required('abnapp.delete_additionaltelephone')
@permission_required('abonapp.delete_additionaltelephone')
def tel_del(request, gid: int, uname): def tel_del(request, gid: int, uname):
try: try:
tid = lib.safe_int(request.GET.get('tid')) tid = lib.safe_int(request.GET.get('tid'))
@ -975,7 +975,7 @@ def tel_del(request, gid: int, uname):
@login_required @login_required
@lib.decorators.only_admins @lib.decorators.only_admins
@permission_required('group_app.can_view_group', (Group, 'pk', 'gid'))
@permission_required('group_app.view_group', (Group, 'pk', 'gid'))
def phonebook(request, gid): def phonebook(request, gid):
res_format = request.GET.get('f') res_format = request.GET.get('f')
t1 = models.Abon.objects.filter(group__id=int(gid)).only('telephone', 'fio').values_list('telephone', 'fio') t1 = models.Abon.objects.filter(group__id=int(gid)).only('telephone', 'fio').values_list('telephone', 'fio')
@ -998,7 +998,7 @@ def phonebook(request, gid):
@login_required @login_required
@lib.decorators.only_admins @lib.decorators.only_admins
@permission_required('group_app.can_view_group', (Group, 'pk', 'gid'))
@permission_required('group_app.view_group', (Group, 'pk', 'gid'))
def abon_export(request, gid): def abon_export(request, gid):
res_format = request.GET.get('f') res_format = request.GET.get('f')
@ -1052,7 +1052,7 @@ def fin_report(request):
@login_required @login_required
@lib.decorators.only_admins @lib.decorators.only_admins
@permission_required('group_app.can_view_group', (Group, 'pk', 'gid'))
@permission_required('group_app.view_group', (Group, 'pk', 'gid'))
def add_edit_periodic_pay(request, gid: int, uname, periodic_pay_id=0): def add_edit_periodic_pay(request, gid: int, uname, periodic_pay_id=0):
if periodic_pay_id == 0: if periodic_pay_id == 0:
if not request.user.has_perm('abonapp.add_periodicpayforid'): if not request.user.has_perm('abonapp.add_periodicpayforid'):
@ -1084,7 +1084,7 @@ def add_edit_periodic_pay(request, gid: int, uname, periodic_pay_id=0):
@login_required @login_required
@lib.decorators.only_admins @lib.decorators.only_admins
@permission_required('group_app.can_view_group', (Group, 'pk', 'gid'))
@permission_required('group_app.view_group', (Group, 'pk', 'gid'))
@permission_required('abonapp.delete_periodicpayforid') @permission_required('abonapp.delete_periodicpayforid')
def del_periodic_pay(request, gid: int, uname, periodic_pay_id): def del_periodic_pay(request, gid: int, uname, periodic_pay_id):
periodic_pay_instance = get_object_or_404(models.PeriodicPayForId, pk=periodic_pay_id) periodic_pay_instance = get_object_or_404(models.PeriodicPayForId, pk=periodic_pay_id)
@ -1096,6 +1096,7 @@ def del_periodic_pay(request, gid: int, uname, periodic_pay_id):
@method_decorator(login_decs, name='dispatch') @method_decorator(login_decs, name='dispatch')
@method_decorator(permission_required('abonapp.change_abon'), name='dispatch')
class EditSibscriberMarkers(UpdateView): class EditSibscriberMarkers(UpdateView):
http_method_names = ('get', 'post') http_method_names = ('get', 'post')
template_name = 'abonapp/modal_user_markers.html' template_name = 'abonapp/modal_user_markers.html'
@ -1129,6 +1130,7 @@ class EditSibscriberMarkers(UpdateView):
@login_required @login_required
@lib.decorators.only_admins @lib.decorators.only_admins
@permission_required('abonapp.change_abon')
def user_session_toggle(request, gid: int, uname, lease_id: int, action=None): def user_session_toggle(request, gid: int, uname, lease_id: int, action=None):
abon = get_object_or_404(models.Abon, username=uname) abon = get_object_or_404(models.Abon, username=uname)
if abon.nas is None: if abon.nas is None:
@ -1159,7 +1161,7 @@ def user_session_toggle(request, gid: int, uname, lease_id: int, action=None):
@login_required @login_required
@lib.decorators.only_admins @lib.decorators.only_admins
@permission_required('change_abon')
@permission_required('abonapp.change_abon')
def lease_add(request, gid: int, uname): def lease_add(request, gid: int, uname):
group = get_object_or_404(Group, pk=gid) group = get_object_or_404(Group, pk=gid)
if request.method == 'POST': if request.method == 'POST':
@ -1205,6 +1207,7 @@ def lease_add(request, gid: int, uname):
@login_required @login_required
@lib.decorators.only_admins @lib.decorators.only_admins
@permission_required('abonapp.change_abon')
def attach_nas(request, gid): def attach_nas(request, gid):
if request.method == 'POST': if request.method == 'POST':
gateway_id = lib.safe_int(request.POST.get('gateway')) gateway_id = lib.safe_int(request.POST.get('gateway'))

18
accounts_app/forms.py

@ -6,6 +6,12 @@ from .models import UserProfile
class MyUserObjectPermissionsForm(UserObjectPermissionsForm): class MyUserObjectPermissionsForm(UserObjectPermissionsForm):
def __init__(self, *args, **kwargs):
super(MyUserObjectPermissionsForm, self).__init__(*args, **kwargs)
self.fields['permissions'].widget.attrs.update({
'size': 15
})
def save_obj_perms(self): def save_obj_perms(self):
""" """
Saves selected object permissions by creating new ones and removing Saves selected object permissions by creating new ones and removing
@ -29,3 +35,15 @@ class AvatarChangeForm(forms.ModelForm):
class Meta: class Meta:
model = UserProfile model = UserProfile
fields = ('avatar',) fields = ('avatar',)
class UserPermissionsForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(UserPermissionsForm, self).__init__(*args, **kwargs)
self.fields['user_permissions'].widget.attrs.update({
'size': 35
})
class Meta:
model = UserProfile
fields = 'user_permissions',

133
accounts_app/locale/ru/LC_MESSAGES/django.po

@ -7,7 +7,7 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-08-26 19:09+0300\n"
"POT-Creation-Date: 2018-08-31 16:28+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Dmitry Novikov nerosketch@gmail.com\n" "Last-Translator: Dmitry Novikov nerosketch@gmail.com\n"
"Language: ru\n" "Language: ru\n"
@ -18,112 +18,114 @@ msgstr ""
"%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n" "%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n"
"%100>=11 && n%100<=14)? 2 : 3);\n" "%100>=11 && n%100<=14)? 2 : 3);\n"
#: models.py:21
#: models.py:22
msgid "Users must have an telephone number" msgid "Users must have an telephone number"
msgstr "У пользователей должен быть номер телефона" msgstr "У пользователей должен быть номер телефона"
#: models.py:49 templates/accounts/acc_list.html:21
#: models.py:50 templates/accounts/acc_list.html:21
msgid "profile username" msgid "profile username"
msgstr "Логин" msgstr "Логин"
#: models.py:54
#: models.py:55
msgid "fio" msgid "fio"
msgstr "ФИО" msgstr "ФИО"
#: models.py:55
#: models.py:56
msgid "birth day" msgid "birth day"
msgstr "дата рождения" msgstr "дата рождения"
#: models.py:56
#: models.py:57
msgid "Is active" msgid "Is active"
msgstr "Активен" msgstr "Активен"
#: models.py:60 templates/accounts/acc_list.html:23
#: models.py:61 templates/accounts/acc_list.html:23
#: templates/accounts/create_acc.html:62 templates/accounts/index.html:9 #: templates/accounts/create_acc.html:62 templates/accounts/index.html:9
#: templates/accounts/settings/ch_info.html:38 #: templates/accounts/settings/ch_info.html:38
msgid "Telephone" msgid "Telephone"
msgstr "Телефон" msgstr "Телефон"
#: models.py:94
#: models.py:95
msgid "Author" msgid "Author"
msgstr "Автор" msgstr "Автор"
#: models.py:95 templates/accounts/action_log.html:12
#: models.py:96 templates/accounts/action_log.html:12
msgid "Meta information" msgid "Meta information"
msgstr "Мета информация" msgstr "Мета информация"
#: models.py:97
#: models.py:98
msgid "Create user" msgid "Create user"
msgstr "Создание абонента" msgstr "Создание абонента"
#: models.py:98
#: models.py:99
msgid "Delete user" msgid "Delete user"
msgstr "Удаление абонента" msgstr "Удаление абонента"
#: models.py:99
#: models.py:100
msgid "Create device" msgid "Create device"
msgstr "Создание устройства" msgstr "Создание устройства"
#: models.py:100
#: models.py:101
msgid "Delete device" msgid "Delete device"
msgstr "Удаление устройства" msgstr "Удаление устройства"
#: models.py:101
#: models.py:102
msgid "Create NAS" msgid "Create NAS"
msgstr "Создание NAS" msgstr "Создание NAS"
#: models.py:102
#: models.py:103
msgid "Delete NAS" msgid "Delete NAS"
msgstr "Удаление NAS" msgstr "Удаление NAS"
#: models.py:103
#: models.py:104
msgid "Create service" msgid "Create service"
msgstr "Создание тарифа" msgstr "Создание тарифа"
#: models.py:104
#: models.py:105
msgid "Delete service" msgid "Delete service"
msgstr "Удаление тарифа" msgstr "Удаление тарифа"
#: models.py:106
#: models.py:107
msgid "Action type" msgid "Action type"
msgstr "Тип действия" msgstr "Тип действия"
#: models.py:107
#: models.py:108
msgid "Additional info" msgid "Additional info"
msgstr "Дополнительная информация" msgstr "Дополнительная информация"
#: models.py:108
#: models.py:109
msgid "Action date" msgid "Action date"
msgstr "Дата действия" msgstr "Дата действия"
#: models.py:115
#: models.py:116
msgid "User profile log" msgid "User profile log"
msgstr "Лог действий учётной записи" msgstr "Лог действий учётной записи"
#: models.py:116
#: models.py:117
msgid "User profile logs" msgid "User profile logs"
msgstr "Логи действий учётной записи" msgstr "Логи действий учётной записи"
#: models.py:125
#: models.py:126
msgid "Avatar" msgid "Avatar"
msgstr "Аватар" msgstr "Аватар"
#: models.py:127
#: models.py:128
msgid "Responsibility groups" msgid "Responsibility groups"
msgstr "Группы администратора" msgstr "Группы администратора"
#: models.py:141
#: models.py:142
msgid "Staff account profile" msgid "Staff account profile"
msgstr "Учётная запись работника" msgstr "Учётная запись работника"
#: models.py:142
#: models.py:143
msgid "Staff account profiles" msgid "Staff account profiles"
msgstr "Учётные записи работников" msgstr "Учётные записи работников"
#: templates/accounts/acc_list.html:7 templates/accounts/create_acc.html:8 #: templates/accounts/acc_list.html:7 templates/accounts/create_acc.html:8
#: templates/accounts/perms/objects_of_type.html:7
#: templates/accounts/perms/objects_types.html:8
#: templates/accounts/perms/perms_edit.html:8
#: templates/accounts/perms/change_global_perms.html:8
#: templates/accounts/perms/ext.html:7
#: templates/accounts/perms/object/objects_of_type.html:7
#: templates/accounts/perms/object/objects_types.html:8
#: templates/accounts/perms/object/perms_edit.html:8
msgid "Administrators" msgid "Administrators"
msgstr "Сотрудники" msgstr "Сотрудники"
@ -211,7 +213,8 @@ msgstr "Повторите пароль"
#: templates/accounts/create_acc.html:89 #: templates/accounts/create_acc.html:89
#: templates/accounts/manage_responsibility_groups.html:20 #: templates/accounts/manage_responsibility_groups.html:20
#: templates/accounts/perms/perms_edit.html:65
#: templates/accounts/perms/change_global_perms.html:22
#: templates/accounts/perms/object/perms_edit.html:43
#: templates/accounts/set_abon_groups_permission.html:20 #: templates/accounts/set_abon_groups_permission.html:20
#: templates/accounts/settings/ch_info.html:67 #: templates/accounts/settings/ch_info.html:67
msgid "Save" msgid "Save"
@ -219,7 +222,7 @@ msgstr "Сохранить"
#: templates/accounts/create_acc.html:92 #: templates/accounts/create_acc.html:92
#: templates/accounts/manage_responsibility_groups.html:21 #: templates/accounts/manage_responsibility_groups.html:21
#: templates/accounts/perms/perms_edit.html:68
#: templates/accounts/perms/object/perms_edit.html:46
#: templates/accounts/set_abon_groups_permission.html:21 #: templates/accounts/set_abon_groups_permission.html:21
#: templates/accounts/settings/ch_info.html:70 #: templates/accounts/settings/ch_info.html:70
msgid "Reset" msgid "Reset"
@ -262,38 +265,50 @@ msgstr "Войти по местоположению"
msgid "The responsibility of the administrator of the group of subscribers" msgid "The responsibility of the administrator of the group of subscribers"
msgstr "Ответственность администратора за группы абонентов" msgstr "Ответственность администратора за группы абонентов"
#: templates/accounts/perms/objects_of_type.html:9
#: templates/accounts/perms/objects_types.html:10
#: templates/accounts/perms/perms_edit.html:10
#: templates/accounts/perms/change_global_perms.html:10
#: templates/accounts/perms/ext.html:9 templates/accounts/perms/ext.html:14
msgid "Permission options" msgid "Permission options"
msgstr "Права" msgstr "Права"
#: templates/accounts/perms/objects_of_type.html:16
#: templates/accounts/perms/perms_edit.html:19
#: templates/accounts/perms/change_global_perms.html:11
#: templates/accounts/perms/ext.html:22
msgid "Global permission options"
msgstr "Глобальные права"
#: templates/accounts/perms/change_global_perms.html:16
msgid "Select permissions for picked account"
msgstr "Отметьте права для выбранной учётной записи"
#: templates/accounts/perms/ext.html:27
#: templates/accounts/perms/object/objects_of_type.html:9
#: templates/accounts/perms/object/objects_types.html:10
#: templates/accounts/perms/object/objects_types.html:11
#: templates/accounts/perms/object/perms_edit.html:10
msgid "Object permission options"
msgstr "Права для каждого объекта"
#: templates/accounts/perms/object/objects_of_type.html:16
#: templates/accounts/perms/object/perms_edit.html:18
msgid "Pick object for edit permissions" msgid "Pick object for edit permissions"
msgstr "Выберите объект для редактирования прав доступа" msgstr "Выберите объект для редактирования прав доступа"
#: templates/accounts/perms/objects_types.html:15
#: templates/accounts/perms/object/objects_types.html:16
msgid "Pick the type of object" msgid "Pick the type of object"
msgstr "Выберите тип объекта" msgstr "Выберите тип объекта"
#: templates/accounts/perms/objects_types.html:23
#: templates/accounts/perms/object/objects_types.html:24
msgid "Group" msgid "Group"
msgstr "Группа" msgstr "Группа"
#: templates/accounts/perms/perms_edit.html:28
#: templates/accounts/perms/object/perms_edit.html:27
msgid "Profile is superuser, permissions to change it makes no sense" msgid "Profile is superuser, permissions to change it makes no sense"
msgstr "" msgstr ""
"Учётная запись является суперпользователем, разрешения менять нет смысла"
"Учётная запись является суперпользователем. Разрешения менять нет смысла.,"
#: templates/accounts/perms/perms_edit.html:34
#: templates/accounts/perms/object/perms_edit.html:33
msgid "Change permission for that object" msgid "Change permission for that object"
msgstr "Изменение прав доступа для выбранного объекта" msgstr "Изменение прав доступа для выбранного объекта"
#: templates/accounts/perms/perms_edit.html:56
msgid "Not set"
msgstr "Не найдено"
#: templates/accounts/set_abon_groups_permission.html:5 #: templates/accounts/set_abon_groups_permission.html:5
msgid "The list of user groups to which the account has access" msgid "The list of user groups to which the account has access"
msgstr "Список групп абонентов, к которым учётка имеет доступ" msgstr "Список групп абонентов, к которым учётка имеет доступ"
@ -306,53 +321,50 @@ msgstr "Старый пароль"
msgid "New password" msgid "New password"
msgstr "Новый пароль" msgstr "Новый пароль"
#: views.py:32
#: views.py:33
msgid "Wrong login or password, please try again" msgid "Wrong login or password, please try again"
msgstr "Неправильный логин или пароль, попробуйте ещё раз" msgstr "Неправильный логин или пароль, попробуйте ещё раз"
#: views.py:120
#: views.py:121
msgid "New password is empty, fill it" msgid "New password is empty, fill it"
msgstr "Новый пароль пустой, придумайте себе пароль" msgstr "Новый пароль пустой, придумайте себе пароль"
#: views.py:122
#: views.py:123
msgid "Wrong password" msgid "Wrong password"
msgstr "Неправильный пароль" msgstr "Неправильный пароль"
#: views.py:124
#: views.py:125
msgid "Empty password, fill it" msgid "Empty password, fill it"
msgstr "Пустой пароль, впишите что-то в пароль" msgstr "Пустой пароль, впишите что-то в пароль"
#: views.py:148
#: views.py:149
msgid "You forget specify a password for the new account" msgid "You forget specify a password for the new account"
msgstr "Забыли указать пароль для нового аккаунта" msgstr "Забыли указать пароль для нового аккаунта"
#: views.py:151
#: views.py:152
msgid "You forget to repeat a password for the new account" msgid "You forget to repeat a password for the new account"
msgstr "Забыли повторить пароль для нового аккаунта" msgstr "Забыли повторить пароль для нового аккаунта"
#: views.py:160
#: views.py:161
msgid "Subscriber with this name already exist" msgid "Subscriber with this name already exist"
msgstr "Пользователь с таким именем уже есть" msgstr "Пользователь с таким именем уже есть"
#: views.py:162
#: views.py:163
msgid "Passwords does not match, try again" msgid "Passwords does not match, try again"
msgstr "Пароли не совпадают, попробуйте ещё раз" msgstr "Пароли не совпадают, попробуйте ещё раз"
#: views.py:177
#: views.py:178
msgid "Profile has been deleted" msgid "Profile has been deleted"
msgstr "Учётная запись удалена" msgstr "Учётная запись удалена"
#: views.py:255
#: views.py:240
msgid "Permissions has successfully updated" msgid "Permissions has successfully updated"
msgstr "Права успешно обновлены" msgstr "Права успешно обновлены"
#: views.py:322
#: views.py:352
msgid "Responsibilities has been updated" msgid "Responsibilities has been updated"
msgstr "Ответственность за группы обновлена" msgstr "Ответственность за группы обновлена"
msgid "Password"
msgstr "Пароль"
msgid "Change self onfo" msgid "Change self onfo"
msgstr "Изменить инфу о себе" msgstr "Изменить инфу о себе"
@ -362,9 +374,6 @@ msgstr "Редактировать"
msgid "Access to groups" msgid "Access to groups"
msgstr "Доступ к группам" msgstr "Доступ к группам"
msgid "Administrator"
msgstr "Сотрудник"
msgid "Manage responsibility groups" msgid "Manage responsibility groups"
msgstr "Ответственность за группы" msgstr "Ответственность за группы"

4
accounts_app/models.py

@ -8,6 +8,7 @@ from django.contrib.auth.models import BaseUserManager, AbstractBaseUser, Permis
from django.core.validators import RegexValidator from django.core.validators import RegexValidator
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.conf import settings from django.conf import settings
from django.shortcuts import resolve_url
from group_app.models import Group from group_app.models import Group
@ -173,3 +174,6 @@ class UserProfile(BaseAccount):
do_type=do_type, do_type=do_type,
additional_text=additional_text additional_text=additional_text
) )
def get_absolute_url(self):
return resolve_url('acc_app:other_profile', self.pk)

16
accounts_app/templates/accounts/ext.htm

@ -28,17 +28,11 @@
</a> </a>
{% endif %} {% endif %}
{% if request.user.is_superuser %} {% if request.user.is_superuser %}
{% if userprofile.is_superuser %}
<a href="{% url 'acc_app:setup_perms' userprofile.pk %}" class="btn btn-default" title="{% trans 'Profile is superuser, permissions to change it makes no sense' %}" data-toggle="tooltip">
<span class="glyphicon glyphicon-lock"></span>
<span class="hidden-sm hidden-md">{% trans 'Permission options' %}</span>
</a>
{% else %}
<a href="{% url 'acc_app:setup_perms' userprofile.pk %}" class="btn btn-default">
<span class="glyphicon glyphicon-lock"></span>
<span class="hidden-sm hidden-md">{% trans 'Permission options' %}</span>
</a>
{% endif %}
<a href="{% url 'acc_app:setup_perms' userprofile.pk %}" class="btn btn-default"
title="{{ userprofile.is_superuser|yesno:_("Profile is superuser. Permissions to change it makes no sense.,") }}" data-toggle="tooltip">
<span class="glyphicon glyphicon-lock"></span>
<span class="hidden-sm hidden-md">{% trans 'Permission options' %}</span>
</a>
{% endif %} {% endif %}
</div> </div>
</div> </div>

24
accounts_app/templates/accounts/perms/change_global_perms.html

@ -0,0 +1,24 @@
{% extends request.is_ajax|yesno:'nullcont.htm,accounts/perms/ext.html' %}
{% load i18n %}
{% load bootstrap3 %}
{% block breadcrumb %}
<ol class="breadcrumb">
<li><span class="glyphicon glyphicon-home"></span></li>
<li><a href="{% url 'acc_app:accounts_list' %}">{% trans 'Administrators' %}</a></li>
<li><a href="{% url 'acc_app:other_profile' userprofile.pk %}">{{ userprofile.username }}</a></li>
<li><a href="{% url 'acc_app:setup_perms' userprofile.pk %}">{% trans 'Permission options' %}</a></li>
<li class="active">{% trans 'Global permission options' %}</li>
</ol>
{% endblock %}
{% block page-header %}
{% trans 'Select permissions for picked account' %}
{% endblock %}
{% block content %}
<form action="{% url 'acc_app:setup_perms' userprofile.pk %}" method="post">{% csrf_token %}
{% bootstrap_form form %}
{% bootstrap_button _('Save') button_type='submit' button_class='btn-primary' %}
</form>
{% endblock %}

36
accounts_app/templates/accounts/perms/ext.html

@ -0,0 +1,36 @@
{% extends request.is_ajax|yesno:'bajax.html,base.html' %}
{% load i18n %}
{% block breadcrumb %}
<ol class="breadcrumb">
<li><span class="glyphicon glyphicon-home"></span></li>
<li><a href="{% url 'acc_app:accounts_list' %}">{% trans 'Administrators' %}</a></li>
<li><a href="{% url 'acc_app:other_profile' userprofile.pk %}">{{ userprofile.username }}</a></li>
<li class="active">{% trans 'Permission options' %}</li>
</ol>
{% endblock %}
{% block page-header %}
{% trans 'Permission options' %}
{% endblock %}
{% block main %}
<ul class="nav nav-tabs nav-justified">
{% url 'acc_app:setup_perms' userprofile.pk as sperms %}
<li{% if sperms == request.path %} class="active"{% endif %}>
<a href="{{ sperms }}">{% trans 'Global permission options' %}</a>
</li>
{% url 'acc_app:setup_perms_object' userprofile.pk as sperms_obj %}
<li{% if sperms_obj == request.path %} class="active"{% endif %}>
<a href="{{ sperms_obj }}">{% trans 'Object permission options' %}</a>
</li>
</ul>
<div class="tab-content">
<div class="tab-pane active">
{% block content %}{% endblock %}
</div>
</div>
{% endblock %}

4
accounts_app/templates/accounts/perms/objects_of_type.html → accounts_app/templates/accounts/perms/object/objects_of_type.html

@ -1,4 +1,4 @@
{% extends 'base.html' %}
{% extends request.is_ajax|yesno:'nullcont.htm,accounts/perms/ext.html' %}
{% load i18n %} {% load i18n %}
{% block breadcrumb %} {% block breadcrumb %}
@ -6,7 +6,7 @@
<li><span class="glyphicon glyphicon-home"></span></li> <li><span class="glyphicon glyphicon-home"></span></li>
<li><a href="{% url 'acc_app:accounts_list' %}">{% trans 'Administrators' %}</a></li> <li><a href="{% url 'acc_app:accounts_list' %}">{% trans 'Administrators' %}</a></li>
<li><a href="{% url 'acc_app:other_profile' userprofile.pk %}">{{ userprofile.username }}</a></li> <li><a href="{% url 'acc_app:other_profile' userprofile.pk %}">{{ userprofile.username }}</a></li>
<li><a href="{% url 'acc_app:perms_klasses' userprofile.pk klass %}">{% trans 'Permission options' %}</a></li>
<li><a href="{% url 'acc_app:setup_perms_object' userprofile.pk %}">{% trans 'Object permission options' %}</a></li>
<li class="active">&lt;{{ klass }}&gt; {{ klass_name }}</li> <li class="active">&lt;{{ klass }}&gt; {{ klass_name }}</li>
</ol> </ol>
{% endblock %} {% endblock %}

7
accounts_app/templates/accounts/perms/objects_types.html → accounts_app/templates/accounts/perms/object/objects_types.html

@ -1,4 +1,4 @@
{% extends 'base.html' %}
{% extends request.is_ajax|yesno:'nullcont.htm,accounts/perms/ext.html' %}
{% load i18n %} {% load i18n %}
{% load acc_tags %} {% load acc_tags %}
@ -7,7 +7,8 @@
<li><span class="glyphicon glyphicon-home"></span></li> <li><span class="glyphicon glyphicon-home"></span></li>
<li><a href="{% url 'acc_app:accounts_list' %}">{% trans 'Administrators' %}</a></li> <li><a href="{% url 'acc_app:accounts_list' %}">{% trans 'Administrators' %}</a></li>
<li><a href="{% url 'acc_app:other_profile' userprofile.pk %}">{{ userprofile.username }}</a></li> <li><a href="{% url 'acc_app:other_profile' userprofile.pk %}">{{ userprofile.username }}</a></li>
<li class="active">{% trans 'Permission options' %}</li>
<li><a href="{% url 'acc_app:setup_perms_object' userprofile.pk %}">{% trans 'Object permission options' %}</a></li>
<li class="active">{% trans 'Object permission options' %}</li>
</ol> </ol>
{% endblock %} {% endblock %}
@ -15,7 +16,7 @@
{% trans 'Pick the type of object' %} {% trans 'Pick the type of object' %}
{% endblock %} {% endblock %}
{% block main %}
{% block content %}
<div class="table-responsive"> <div class="table-responsive">
<table class="table table-striped table-bordered"> <table class="table table-striped table-bordered">
<thead> <thead>

30
accounts_app/templates/accounts/perms/perms_edit.html → accounts_app/templates/accounts/perms/object/perms_edit.html

@ -1,15 +1,14 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% load i18n %} {% load i18n %}
{% load guardian_tags %}
{% load bootstrap3 %}
{% block breadcrumb %} {% block breadcrumb %}
<ol class="breadcrumb"> <ol class="breadcrumb">
<li><span class="glyphicon glyphicon-home"></span></li> <li><span class="glyphicon glyphicon-home"></span></li>
<li><a href="{% url 'acc_app:accounts_list' %}">{% trans 'Administrators' %}</a></li> <li><a href="{% url 'acc_app:accounts_list' %}">{% trans 'Administrators' %}</a></li>
<li><a href="{% url 'acc_app:other_profile' userprofile.pk %}">{{ userprofile.username }}</a></li> <li><a href="{% url 'acc_app:other_profile' userprofile.pk %}">{{ userprofile.username }}</a></li>
<li><a href="{% url 'acc_app:setup_perms' userprofile.pk %}">{% trans 'Permission options' %}</a></li>
<li><a href="{% url 'acc_app:perms_klasses' userprofile.pk klass %}">&lt;{{ klass }}&gt; {{ klass_name }}</a>
</li>
<li><a href="{% url 'acc_app:setup_perms_object' userprofile.pk %}">{% trans 'Object permission options' %}</a></li>
<li><a href="{% url 'acc_app:perms_klasses' userprofile.pk klass %}">&lt;{{ klass }}&gt; {{ klass_name }}</a></li>
<li class="active">{{ obj }}</li> <li class="active">{{ obj }}</li>
</ol> </ol>
{% endblock %} {% endblock %}
@ -37,28 +36,7 @@
<form role="form" action="{% url 'acc_app:perms_edit' userprofile.pk klass obj.pk %}" method="post">{% csrf_token %} <form role="form" action="{% url 'acc_app:perms_edit' userprofile.pk klass obj.pk %}" method="post">{% csrf_token %}
{% get_obj_perms userprofile for obj as 'obj_perms' %}
{% for field in form %}
<div class="form-group">
<label for="{{ field.id_for_label }}" class="col-sm-3 control-label">{{ field.label }}</label>
<div class="col-sm-9">
<select multiple="multiple" id="{{ field.id_for_label }}" name="{{ field.html_name }}"
class="form-control">
{% for perm_value, perm_name in field.field.choices %}
{% if perm_value in obj_perms %}
<option value="{{ perm_value }}" selected>{{ perm_name }}</option>
{% else %}
<option value="{{ perm_value }}">{{ perm_name }}</option>
{% endif %}
{% empty %}
<option value="0">{% trans 'Not set' %}</option>
{% endfor %}
</select>
</div>
</div>
{% endfor %}
{% bootstrap_form form %}
<div class="btn-group"> <div class="btn-group">
<button type="submit" class="btn btn-sm btn-primary"> <button type="submit" class="btn btn-sm btn-primary">

7
accounts_app/urls.py

@ -19,13 +19,14 @@ urlpatterns = [
path('settings/change_ava/', views.AvatarUpdateView.as_view(), name='setup_avatar'), path('settings/change_ava/', views.AvatarUpdateView.as_view(), name='setup_avatar'),
path('<int:uid>/', views.profile_show, name='other_profile'), path('<int:uid>/', views.profile_show, name='other_profile'),
path('<int:uid>/perms/', views.perms, name='setup_perms'),
path('<int:uid>/perms/', views.PermsUpdateView.as_view(), name='setup_perms'),
path('<int:uid>/perms/object/', views.perms_object, name='setup_perms_object'),
re_path('^(?P<uid>\d+)/perms/(?P<klass_name>[a-z_]+\.[a-zA-Z_]+)/',
re_path('^(?P<uid>\d+)/perms/object/(?P<klass_name>[a-z_]+\.[a-zA-Z_]+)/$',
views.PermissionClassListView.as_view(), views.PermissionClassListView.as_view(),
name='perms_klasses'), name='perms_klasses'),
re_path('^(?P<uid>\d+)/perms/(?P<klass_name>[a-z_]+\.[a-zA-Z_]+)/(?P<obj_id>\d+)/',
re_path('^(?P<uid>\d+)/perms/object/(?P<klass_name>[a-z_]+\.[a-zA-Z_]+)/(?P<obj_id>\d+)/$',
views.perms_edit, views.perms_edit,
name='perms_edit'), name='perms_edit'),

52
accounts_app/views.py

@ -1,3 +1,4 @@
from django.apps import apps
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.contrib.auth import logout, login, authenticate from django.contrib.auth import logout, login, authenticate
from django.contrib.auth.forms import AuthenticationForm from django.contrib.auth.forms import AuthenticationForm
@ -15,7 +16,7 @@ from django.conf import settings
from group_app.models import Group from group_app.models import Group
from .models import UserProfile, UserProfileLog from .models import UserProfile, UserProfileLog
from .forms import AvatarChangeForm
from .forms import AvatarChangeForm, UserPermissionsForm, MyUserObjectPermissionsForm
from djing import lib from djing import lib
from djing.lib.decorators import only_admins from djing.lib.decorators import only_admins
from guardian.decorators import permission_required_or_403 as permission_required from guardian.decorators import permission_required_or_403 as permission_required
@ -192,7 +193,7 @@ class AccountsListView(ListView):
@login_required @login_required
def perms(request, uid: int):
def perms_object(request, uid: int):
if not request.user.is_superuser: if not request.user.is_superuser:
raise PermissionDenied raise PermissionDenied
userprofile = get_object_or_404(UserProfile, id=uid) userprofile = get_object_or_404(UserProfile, id=uid)
@ -202,17 +203,49 @@ def perms(request, uid: int):
'abonapp.PassportInfo', 'abonapp.AdditionalTelephone', 'tariff_app.PeriodicPay', 'abonapp.PassportInfo', 'abonapp.AdditionalTelephone', 'tariff_app.PeriodicPay',
'group_app.Group' 'group_app.Group'
) )
return render(request, 'accounts/perms/objects_types.html', {
return render(request, 'accounts/perms/object/objects_types.html', {
'userprofile': userprofile, 'userprofile': userprofile,
'klasses': klasses 'klasses': klasses
}) })
@method_decorator(login_required, name='dispatch')
class PermsUpdateView(UpdateView):
http_method_names = 'get', 'post'
template_name = 'accounts/perms/change_global_perms.html'
model = UserProfile
form_class = UserPermissionsForm
pk_url_kwarg = 'uid'
def get_success_url(self):
return resolve_url('acc_app:setup_perms', self.userprofile.pk)
def get_object(self, queryset=None):
self.userprofile = get_object_or_404(UserProfile, id=self.kwargs.get('uid'))
return super(PermsUpdateView, self).get_object(queryset=queryset)
def dispatch(self, request, *args, **kwargs):
if not request.user.is_superuser:
raise PermissionDenied
return super(PermsUpdateView, self).dispatch(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = {
'userprofile': self.userprofile
}
context.update(kwargs)
return super(PermsUpdateView, self).get_context_data(**context)
def form_valid(self, form):
messages.success(self.request, _('Permissions has successfully updated'))
return super(PermsUpdateView, self).form_valid(form)
@method_decorator(login_decs, name='dispatch') @method_decorator(login_decs, name='dispatch')
class PermissionClassListView(ListView): class PermissionClassListView(ListView):
http_method_names = 'get', http_method_names = 'get',
paginate_by = getattr(settings, 'PAGINATION_ITEMS_PER_PAGE', 10) paginate_by = getattr(settings, 'PAGINATION_ITEMS_PER_PAGE', 10)
template_name = 'accounts/perms/objects_of_type.html'
template_name = 'accounts/perms/object/objects_of_type.html'
context_object_name = 'objects' context_object_name = 'objects'
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
@ -228,7 +261,6 @@ class PermissionClassListView(ListView):
return context return context
def get_queryset(self): def get_queryset(self):
from django.apps import apps
klass_name = self.kwargs.get('klass_name') klass_name = self.kwargs.get('klass_name')
app_label, model_name = klass_name.split('.', 1) app_label, model_name = klass_name.split('.', 1)
klass = apps.get_model(app_label, model_name) klass = apps.get_model(app_label, model_name)
@ -242,8 +274,6 @@ class PermissionClassListView(ListView):
def perms_edit(request, uid: int, klass_name, obj_id): def perms_edit(request, uid: int, klass_name, obj_id):
if not request.user.is_superuser: if not request.user.is_superuser:
raise PermissionDenied raise PermissionDenied
from django.apps import apps
from .forms import MyUserObjectPermissionsForm
userprofile = get_object_or_404(UserProfile, pk=uid) userprofile = get_object_or_404(UserProfile, pk=uid)
app_label, model_name = klass_name.split('.', 1) app_label, model_name = klass_name.split('.', 1)
klass = apps.get_model(app_label, model_name) klass = apps.get_model(app_label, model_name)
@ -254,7 +284,7 @@ def perms_edit(request, uid: int, klass_name, obj_id):
frm.save_obj_perms() frm.save_obj_perms()
messages.success(request, _('Permissions has successfully updated')) messages.success(request, _('Permissions has successfully updated'))
return render(request, 'accounts/perms/perms_edit.html', {
return render(request, 'accounts/perms/object/perms_edit.html', {
'userprofile': userprofile, 'userprofile': userprofile,
'obj': obj, 'obj': obj,
'form': frm, 'form': frm,
@ -271,16 +301,16 @@ def set_abon_groups_permission(request, uid: int):
raise PermissionDenied raise PermissionDenied
userprofile = get_object_or_404(UserProfile, pk=uid) userprofile = get_object_or_404(UserProfile, pk=uid)
picked_groups = get_objects_for_user(userprofile, 'group_app.can_view_group', accept_global_perms=False)
picked_groups = get_objects_for_user(userprofile, 'group_app.view_group', accept_global_perms=False)
picked_groups = picked_groups.values_list('pk', flat=True) picked_groups = picked_groups.values_list('pk', flat=True)
if request.method == 'POST': if request.method == 'POST':
checked_groups = tuple(int(ag) for ag in request.POST.getlist('grp', default=0)) checked_groups = tuple(int(ag) for ag in request.POST.getlist('grp', default=0))
for grp in Group.objects.all(): for grp in Group.objects.all():
if grp.pk in checked_groups and grp.pk not in picked_groups: if grp.pk in checked_groups and grp.pk not in picked_groups:
assign_perm('groupapp.can_view_group', userprofile, obj=grp)
assign_perm('groupapp.view_group', userprofile, obj=grp)
elif grp.pk not in checked_groups and grp.pk in picked_groups: elif grp.pk not in checked_groups and grp.pk in picked_groups:
remove_perm('groupapp.can_view_group', userprofile, obj=grp)
remove_perm('groupapp.view_group', userprofile, obj=grp)
return redirect('acc_app:set_abon_groups_permission', uid) return redirect('acc_app:set_abon_groups_permission', uid)
groups = Group.objects.only('pk', 'title') groups = Group.objects.only('pk', 'title')

4
devapp/locale/ru/LC_MESSAGES/django.po

@ -160,10 +160,6 @@ msgstr "Состояние"
msgid "Send notify when monitoring state changed" msgid "Send notify when monitoring state changed"
msgstr "Отправлять уведомления при событиях мониторинга" msgstr "Отправлять уведомления при событиях мониторинга"
#: models.py:62
msgid "Can view device"
msgstr "Может видеть устройство"
#: models.py:64 models.py:112 #: models.py:64 models.py:112
msgid "Device" msgid "Device"
msgstr "Устройство" msgstr "Устройство"

3
devapp/migrations/0001_initial.py

@ -43,8 +43,7 @@ class Migration(migrations.Migration):
'verbose_name': 'Device', 'verbose_name': 'Device',
'verbose_name_plural': 'Devices', 'verbose_name_plural': 'Devices',
'db_table': 'dev', 'db_table': 'dev',
'ordering': ['comment'],
'permissions': (('can_view_device', 'Can view device'),),
'ordering': ['comment']
}, },
), ),
migrations.CreateModel( migrations.CreateModel(

2
devapp/migrations/0002_auto_20180409_1318.py

@ -14,7 +14,7 @@ class Migration(migrations.Migration):
operations = [ operations = [
migrations.AlterModelOptions( migrations.AlterModelOptions(
name='device', name='device',
options={'ordering': ['id'], 'permissions': (('can_view_device', 'Can view device'),),
options={'ordering': ['id'],
'verbose_name': 'Device', 'verbose_name_plural': 'Devices'}, 'verbose_name': 'Device', 'verbose_name_plural': 'Devices'},
), ),
migrations.AlterField( migrations.AlterField(

2
devapp/migrations/0003_auto_20180529_1311.py

@ -36,7 +36,7 @@ class Migration(migrations.Migration):
migrations.RunPython(snmp_backup_info), migrations.RunPython(snmp_backup_info),
migrations.AlterModelOptions( migrations.AlterModelOptions(
name='device', name='device',
options={'ordering': ('id',), 'permissions': (('can_view_device', 'Can view device'),), 'verbose_name': 'Device', 'verbose_name_plural': 'Devices'},
options={'ordering': ('id',), 'verbose_name': 'Device', 'verbose_name_plural': 'Devices'},
), ),
migrations.AlterModelOptions( migrations.AlterModelOptions(
name='port', name='port',

3
devapp/models.py

@ -58,9 +58,6 @@ class Device(models.Model):
class Meta: class Meta:
db_table = 'dev' db_table = 'dev'
permissions = (
('can_view_device', _('Can view device')),
)
verbose_name = _('Device') verbose_name = _('Device')
verbose_name_plural = _('Devices') verbose_name_plural = _('Devices')
ordering = ('id',) ordering = ('id',)

6
devapp/templates/devapp/manage_ports/modal_add_edit_port.html

@ -15,12 +15,8 @@
</div> </div>
<div class="modal-body"> <div class="modal-body">
{% bootstrap_form form %} {% bootstrap_form form %}
{% trans 'Save' as btntxt %}
{% bootstrap_button btntxt button_type="submit" button_class="btn-primary" icon="save" size='sm' %}
{% bootstrap_button _('Save') button_type="submit" button_class="btn-primary" icon="save" size='sm' %}
</div> </div>
</form> </form>

6
devapp/templates/devapp/modal_device_extra_edit.html

@ -11,13 +11,11 @@
{% bootstrap_form form %} {% bootstrap_form form %}
<div class="btn-group btn-group-sm"> <div class="btn-group btn-group-sm">
{% trans 'Save' as btntxt %}
{% bootstrap_button btntxt button_type="submit" button_class="btn-primary" icon="save" %}
{% bootstrap_button _('Save') button_type="submit" button_class="btn-primary" icon="save" %}
{% if not request.is_ajax %} {% if not request.is_ajax %}
{% trans 'Back' as btntxt %}
{% url 'devapp:edit' group_id object.pk as backurl %} {% url 'devapp:edit' group_id object.pk as backurl %}
{% bootstrap_button btntxt button_type="link" href=backurl icon="fast-backward" %}
{% bootstrap_button _('Back') button_type="link" href=backurl icon="fast-backward" %}
{% endif %} {% endif %}
</div> </div>
</div> </div>

29
devapp/views.py

@ -33,7 +33,6 @@ from .forms import DeviceForm, PortForm, DeviceExtraDataForm
login_decs = login_required, only_admins login_decs = login_required, only_admins
@method_decorator(login_decs, name='dispatch')
class DevicesListView(global_base_views.OrderedFilteredList): class DevicesListView(global_base_views.OrderedFilteredList):
context_object_name = 'devices' context_object_name = 'devices'
template_name = 'devapp/devices.html' template_name = 'devapp/devices.html'
@ -51,6 +50,8 @@ class DevicesListView(global_base_views.OrderedFilteredList):
context['group'] = get_object_or_404(Group, pk=group_id) context['group'] = get_object_or_404(Group, pk=group_id)
return context return context
@method_decorator(login_decs)
@method_decorator(permission_required('devapp.view_device'))
def dispatch(self, request, *args, **kwargs): def dispatch(self, request, *args, **kwargs):
try: try:
response = super(DevicesListView, self).dispatch(request, *args, **kwargs) response = super(DevicesListView, self).dispatch(request, *args, **kwargs)
@ -61,6 +62,7 @@ class DevicesListView(global_base_views.OrderedFilteredList):
@method_decorator(login_decs, name='dispatch') @method_decorator(login_decs, name='dispatch')
@method_decorator(permission_required('devapp.view_device'), name='dispatch')
class DevicesWithoutGroupsListView(global_base_views.OrderedFilteredList): class DevicesWithoutGroupsListView(global_base_views.OrderedFilteredList):
context_object_name = 'devices' context_object_name = 'devices'
template_name = 'devapp/devices_null_group.html' template_name = 'devapp/devices_null_group.html'
@ -92,7 +94,7 @@ class DeviceDeleteView(DeleteView):
@method_decorator(login_decs, name='dispatch') @method_decorator(login_decs, name='dispatch')
@method_decorator(permission_required('devapp.can_view_device'), name='dispatch')
@method_decorator(permission_required('devapp.view_device'), name='dispatch')
class DeviceUpdate(UpdateView): class DeviceUpdate(UpdateView):
template_name = 'devapp/dev.html' template_name = 'devapp/dev.html'
context_object_name = 'dev' context_object_name = 'dev'
@ -140,7 +142,7 @@ class DeviceUpdate(UpdateView):
def dispatch(self, request, *args, **kwargs): def dispatch(self, request, *args, **kwargs):
group_id = self.kwargs.get('group_id') group_id = self.kwargs.get('group_id')
device_group = get_object_or_404(Group, pk=group_id) device_group = get_object_or_404(Group, pk=group_id)
if not request.user.has_perm('group_app.can_view_group', device_group):
if not request.user.has_perm('group_app.view_group', device_group):
raise PermissionDenied raise PermissionDenied
self.device_group = device_group self.device_group = device_group
return super().dispatch(request, *args, **kwargs) return super().dispatch(request, *args, **kwargs)
@ -158,7 +160,7 @@ class DeviceUpdate(UpdateView):
@method_decorator(login_decs, name='dispatch') @method_decorator(login_decs, name='dispatch')
@method_decorator(permission_required('devapp.can_view_device'), name='dispatch')
@method_decorator(permission_required('devapp.add_device'), name='dispatch')
class DeviceCreateView(CreateView): class DeviceCreateView(CreateView):
template_name = 'devapp/add_dev.html' template_name = 'devapp/add_dev.html'
context_object_name = 'dev' context_object_name = 'dev'
@ -167,11 +169,6 @@ class DeviceCreateView(CreateView):
device_group = None device_group = None
already_dev = None already_dev = None
def get(self, request, *args, **kwargs):
if not request.user.has_perm('devapp.add_device'):
raise PermissionDenied
return super().get(request, *args, **kwargs)
def form_valid(self, form): def form_valid(self, form):
# check if that device is exist # check if that device is exist
try: try:
@ -202,7 +199,7 @@ class DeviceCreateView(CreateView):
def dispatch(self, request, *args, **kwargs): def dispatch(self, request, *args, **kwargs):
group_id = self.kwargs.get('group_id') group_id = self.kwargs.get('group_id')
device_group = get_object_or_404(Group, pk=group_id) device_group = get_object_or_404(Group, pk=group_id)
if not request.user.has_perm('group_app.can_view_group', device_group):
if not request.user.has_perm('group_app.view_group', device_group):
raise PermissionDenied raise PermissionDenied
self.device_group = device_group self.device_group = device_group
return super().dispatch(request, *args, **kwargs) return super().dispatch(request, *args, **kwargs)
@ -364,7 +361,7 @@ def delete_single_port(request, group_id, device_id, port_id):
@login_required @login_required
@only_admins @only_admins
@permission_required('devapp.add_port')
@permission_required('devapp.change_port')
def edit_single_port(request, group_id: int, device_id: int, port_id: int): def edit_single_port(request, group_id: int, device_id: int, port_id: int):
try: try:
port = Port.objects.get(pk=port_id) port = Port.objects.get(pk=port_id)
@ -424,7 +421,7 @@ def add_single_port(request, group_id, device_id):
@login_required @login_required
@only_admins @only_admins
@permission_required('devapp.can_view_device')
@permission_required('devapp.view_device')
def devview(request, group_id: int, device_id: int): def devview(request, group_id: int, device_id: int):
ports, manager = None, None ports, manager = None, None
device = get_object_or_404(Device, id=device_id) device = get_object_or_404(Device, id=device_id)
@ -512,7 +509,7 @@ class GroupsListView(global_base_views.OrderedFilteredList):
def get_queryset(self): def get_queryset(self):
groups = super(GroupsListView, self).get_queryset() groups = super(GroupsListView, self).get_queryset()
groups = get_objects_for_user(self.request.user, 'group_app.can_view_group', klass=groups,
groups = get_objects_for_user(self.request.user, 'group_app.view_group', klass=groups,
accept_global_perms=False) accept_global_perms=False)
return groups return groups
@ -523,7 +520,7 @@ class GroupsListView(global_base_views.OrderedFilteredList):
def search_dev(request): def search_dev(request):
word = request.GET.get('s') word = request.GET.get('s')
if word is None or word == '': if word is None or word == '':
results = [{'id': 0, 'text': ''}]
results = tuple({'id': 0, 'text': ''})
else: else:
qs = Q(comment__icontains=word) qs = Q(comment__icontains=word)
try: try:
@ -532,10 +529,10 @@ def search_dev(request):
except ValueError: except ValueError:
pass pass
results = Device.objects.filter(qs).only('pk', 'ip_address', 'comment')[:16] results = Device.objects.filter(qs).only('pk', 'ip_address', 'comment')[:16]
results = [{
results = tuple({
'id': device.pk, 'id': device.pk,
'text': "%s: %s" % (device.ip_address or '', device.comment) 'text': "%s: %s" % (device.ip_address or '', device.comment)
} for device in results]
} for device in results)
return results return results

4
group_app/locale/ru/LC_MESSAGES/django.po

@ -27,10 +27,6 @@ msgstr "Название"
msgid "Tech code" msgid "Tech code"
msgstr "Технический код" msgstr "Технический код"
#: models.py:17
msgid "Can view group"
msgstr "Может видеть группы"
#: models.py:19 #: models.py:19
msgid "Group" msgid "Group"
msgstr "Группа" msgstr "Группа"

3
group_app/migrations/0001_initial.py

@ -22,8 +22,7 @@ class Migration(migrations.Migration):
'verbose_name': 'Group', 'verbose_name': 'Group',
'verbose_name_plural': 'Groups', 'verbose_name_plural': 'Groups',
'db_table': 'groups', 'db_table': 'groups',
'ordering': ['title'],
'permissions': (('can_view_group', 'Can view group'),),
'ordering': ('title',),
}, },
), ),
] ]

2
group_app/migrations/0003_auto_20180808_1236.py

@ -14,6 +14,6 @@ class Migration(migrations.Migration):
operations = [ operations = [
migrations.AlterModelOptions( migrations.AlterModelOptions(
name='group', name='group',
options={'ordering': ('title',), 'permissions': (('can_view_group', 'Can view group'),), 'verbose_name': 'Group', 'verbose_name_plural': 'Groups'},
options={'ordering': ('title',), 'verbose_name': 'Group', 'verbose_name_plural': 'Groups'},
), ),
] ]

3
group_app/models.py

@ -12,9 +12,6 @@ class Group(models.Model):
class Meta: class Meta:
db_table = 'groups' db_table = 'groups'
permissions = (
('can_view_group', _('Can view group')),
)
verbose_name = _('Group') verbose_name = _('Group')
verbose_name_plural = _('Groups') verbose_name_plural = _('Groups')
ordering = ('title',) ordering = ('title',)

3
group_app/views.py

@ -19,6 +19,7 @@ login_decs = login_required, only_admins
@method_decorator(login_decs, name='dispatch') @method_decorator(login_decs, name='dispatch')
@method_decorator(permission_required('group_app.view_group'), name='dispatch')
class GroupListView(OrderedFilteredList): class GroupListView(OrderedFilteredList):
http_method_names = ('get',) http_method_names = ('get',)
paginate_by = getattr(settings, 'PAGINATION_ITEMS_PER_PAGE', 10) paginate_by = getattr(settings, 'PAGINATION_ITEMS_PER_PAGE', 10)
@ -28,6 +29,7 @@ class GroupListView(OrderedFilteredList):
@method_decorator(login_decs, name='dispatch') @method_decorator(login_decs, name='dispatch')
@method_decorator(permission_required('group_app.change_group'), name='dispatch')
class EditGroupView(UpdateView): class EditGroupView(UpdateView):
http_method_names = ('get', 'post') http_method_names = ('get', 'post')
template_name = 'group_app/edit_group.html' template_name = 'group_app/edit_group.html'
@ -46,6 +48,7 @@ class EditGroupView(UpdateView):
@method_decorator(login_decs, name='dispatch') @method_decorator(login_decs, name='dispatch')
@method_decorator(permission_required('group_app.add_group'), name='dispatch')
class AddGroupView(CreateView): class AddGroupView(CreateView):
http_method_names = ('get', 'post') http_method_names = ('get', 'post')
template_name = 'group_app/add_group.html' template_name = 'group_app/add_group.html'

3
ip_pool/views.py

@ -17,6 +17,7 @@ login_decs = login_required, only_admins
@method_decorator(login_decs, name='dispatch') @method_decorator(login_decs, name='dispatch')
@method_decorator(permission_required('ip_pool.view_networkmodel'), name='dispatch')
class NetworksListView(OrderedFilteredList): class NetworksListView(OrderedFilteredList):
device_kind_code = None device_kind_code = None
template_name = 'ip_pool/network_list.html' template_name = 'ip_pool/network_list.html'
@ -57,6 +58,7 @@ class NetworkDeleteView(DeleteView):
@method_decorator(login_decs, name='dispatch') @method_decorator(login_decs, name='dispatch')
@method_decorator(permission_required('ip_pool.view_ipleasemodel'), name='dispatch')
class IpLeasesListView(OrderedFilteredList): class IpLeasesListView(OrderedFilteredList):
template_name = 'ip_pool/ip_leases_list.html' template_name = 'ip_pool/ip_leases_list.html'
model = models.IpLeaseModel model = models.IpLeaseModel
@ -86,6 +88,7 @@ class NetworkCreateView(CreateView):
@login_required @login_required
@method_decorator(permission_required('ip_pool.view_networkmodel'), name='dispatch')
def network_in_groups(request, net_id): def network_in_groups(request, net_id):
network = get_object_or_404(models.NetworkModel, pk=net_id) network = get_object_or_404(models.NetworkModel, pk=net_id)
if request.method == 'POST': if request.method == 'POST':

3
mapapp/templates/maps/dot.html

@ -99,9 +99,8 @@
{% endfor %} {% endfor %}
</table> </table>
<div class="panel-footer"> <div class="panel-footer">
{% trans 'Add' as trns %}
{% url 'mapapp:add_dev' dot.pk as url %} {% url 'mapapp:add_dev' dot.pk as url %}
{% bootstrap_button trns button_type="link" icon='plus' size='sm' button_class='btn-success' href=url %}
{% bootstrap_button _('Add') button_type="link" icon='plus' size='sm' button_class='btn-success' href=url %}
</div> </div>
</div> </div>
</div> </div>

8
msg_app/locale/ru/LC_MESSAGES/django.po

@ -63,10 +63,6 @@ msgstr "Сообщение"
msgid "Messages" msgid "Messages"
msgstr "Сообщения" msgstr "Сообщения"
#: msg_app/models.py:71
msgid "Can view messages"
msgstr "может просматривать сообщения"
#: msg_app/models.py:79 #: msg_app/models.py:79
msgid "Admin" msgid "Admin"
msgstr "Админ" msgstr "Админ"
@ -103,10 +99,6 @@ msgstr "Без имени"
msgid "Conversations" msgid "Conversations"
msgstr "Беседы" msgstr "Беседы"
#: msg_app/models.py:244
msgid "Can view conversation"
msgstr "Может просматривать беседы"
#: msg_app/templates/msg_app/chat.html:7 #: msg_app/templates/msg_app/chat.html:7
#: msg_app/templates/msg_app/conversations.html:7 #: msg_app/templates/msg_app/conversations.html:7
msgid "Private messages" msgid "Private messages"

6
msg_app/models.py

@ -67,9 +67,6 @@ class Message(models.Model):
ordering = ('-sent_at',) ordering = ('-sent_at',)
verbose_name = _("Message") verbose_name = _("Message")
verbose_name_plural = _("Messages") verbose_name_plural = _("Messages")
permissions = (
('can_view_messages', _('Can view messages')),
)
class ConversationMembership(models.Model): class ConversationMembership(models.Model):
@ -242,7 +239,4 @@ class Conversation(models.Model):
db_table = 'conversations' db_table = 'conversations'
verbose_name = _("Conversation") verbose_name = _("Conversation")
verbose_name_plural = _("Conversations") verbose_name_plural = _("Conversations")
permissions = (
('can_view_conversation', _('Can view conversation')),
)
ordering = ('title',) ordering = ('title',)

7
msg_app/views.py

@ -11,6 +11,7 @@ from django.views.generic import ListView
from chatbot.models import MessageQueue from chatbot.models import MessageQueue
from djing.lib.decorators import only_admins from djing.lib.decorators import only_admins
from guardian.decorators import permission_required_or_403 as permission_required
from .models import Conversation, MessageError, Message from .models import Conversation, MessageError, Message
from .forms import ConversationForm, MessageForm from .forms import ConversationForm, MessageForm
@ -20,6 +21,7 @@ login_decs = login_required, only_admins
@method_decorator(login_decs, name='dispatch') @method_decorator(login_decs, name='dispatch')
@method_decorator(permission_required('msg_app.view_conversation'), name='dispatch')
class ConversationsListView(ListView): class ConversationsListView(ListView):
context_object_name = 'conversations' context_object_name = 'conversations'
template_name = 'msg_app/conversations.html' template_name = 'msg_app/conversations.html'
@ -31,6 +33,7 @@ class ConversationsListView(ListView):
@login_required @login_required
@only_admins @only_admins
@permission_required('msg_app.add_conversation')
def new_conversation(request): def new_conversation(request):
try: try:
frm = ConversationForm(request.POST or None) frm = ConversationForm(request.POST or None)
@ -52,6 +55,7 @@ def new_conversation(request):
@login_required @login_required
@only_admins @only_admins
@permission_required('msg_app.view_conversation')
def to_conversation(request, conv_id): def to_conversation(request, conv_id):
conv = get_object_or_404(Conversation, pk=conv_id) conv = get_object_or_404(Conversation, pk=conv_id)
try: try:
@ -75,6 +79,7 @@ def to_conversation(request, conv_id):
@login_required @login_required
@only_admins @only_admins
@permission_required('msg_app.delete_message')
def remove_msg(request, conv_id, msg_id): def remove_msg(request, conv_id, msg_id):
msg = get_object_or_404(Message, pk=msg_id) msg = get_object_or_404(Message, pk=msg_id)
if msg.author != request.user: if msg.author != request.user:
@ -84,6 +89,8 @@ def remove_msg(request, conv_id, msg_id):
return redirect('msg_app:to_conversation', conversation_id) return redirect('msg_app:to_conversation', conversation_id)
@login_required
@only_admins
def check_news(request): def check_news(request):
if request.user.is_authenticated: if request.user.is_authenticated:
msg = MessageQueue.objects.pop(user=request.user, tag='msgapp') msg = MessageQueue.objects.pop(user=request.user, tag='msgapp')

1
nas_app/views.py

@ -18,6 +18,7 @@ login_decs = login_required, only_admins
@method_decorator(login_decs, name='dispatch') @method_decorator(login_decs, name='dispatch')
@method_decorator(permission_required('nas_app.view_nasmodel'), name='dispatch')
class NasListView(ListView): class NasListView(ListView):
model = NASModel model = NASModel

3
tariff_app/templates/tariff_app/periodic_pays/add_edit.html

@ -44,8 +44,7 @@
{% bootstrap_icon 'rub' as ic %} {% bootstrap_icon 'rub' as ic %}
{% bootstrap_field form.amount addon_before=ic %} {% bootstrap_field form.amount addon_before=ic %}
{% trans 'Save' as ic %}
{% bootstrap_button ic button_class="btn-primary" icon="save" %}
{% bootstrap_button _('Save') button_class="btn-primary" icon="save" %}
</form> </form>
</div> </div>

4
tariff_app/views.py

@ -20,6 +20,7 @@ login_decs = login_required, only_admins
@method_decorator(login_decs, name='dispatch') @method_decorator(login_decs, name='dispatch')
@method_decorator(permission_required('tariff_app.view_tariff'), name='dispatch')
class TariffsListView(OrderedFilteredList): class TariffsListView(OrderedFilteredList):
""" """
Show Services(Tariffs) list Show Services(Tariffs) list
@ -32,6 +33,7 @@ class TariffsListView(OrderedFilteredList):
@login_required @login_required
@only_admins @only_admins
@permission_required('tariff_app.change_tariff')
def edit_tarif(request, tarif_id=0): def edit_tarif(request, tarif_id=0):
tarif_id = lib.safe_int(tarif_id) tarif_id = lib.safe_int(tarif_id)
@ -90,7 +92,7 @@ class TariffDeleteView(DeleteView):
@method_decorator(login_decs, name='dispatch') @method_decorator(login_decs, name='dispatch')
@method_decorator(permission_required('tariff_app.delete_tariff'), name='dispatch')
@method_decorator(permission_required('tariff_app.view_periodicpay'), name='dispatch')
class PeriodicPaysListView(OrderedFilteredList): class PeriodicPaysListView(OrderedFilteredList):
context_object_name = 'pays' context_object_name = 'pays'
model = PeriodicPay model = PeriodicPay

4
taskapp/locale/ru/LC_MESSAGES/django.po

@ -241,10 +241,6 @@ msgstr "Автор"
msgid "Time of create" msgid "Time of create"
msgstr "Дата создания" msgstr "Дата создания"
#: taskapp/models.py:131
msgid "Can view comments"
msgstr "Может видеть комментарии"
#: taskapp/models.py:133 #: taskapp/models.py:133
msgid "Extra comment" msgid "Extra comment"
msgstr "Комментарий" msgstr "Комментарий"

3
taskapp/models.py

@ -131,9 +131,6 @@ class ExtraComment(models.Model):
class Meta: class Meta:
db_table = 'extra_comments' db_table = 'extra_comments'
permissions = (
('can_view_comments', _('Can view comments')),
)
verbose_name = _('Extra comment') verbose_name = _('Extra comment')
verbose_name_plural = _('Extra comments') verbose_name_plural = _('Extra comments')
ordering = ('-date_create',) ordering = ('-date_create',)

14
taskapp/templates/taskapp/add_edit_task.html

@ -101,12 +101,14 @@
</div> </div>
</div> </div>
{% if task %} {% if task %}
<div class="col-sm-6">
{% include 'taskapp/details.html' with task=task time_diff=time_diff %}
</div>
<div class="col-sm-6">
{% include "taskapp/comments/task_comments.html" with comments=comments task_uid=task.pk comment_form=comment_form %}
</div>
<div class="col-sm-6">
{% include 'taskapp/details.html' with task=task time_diff=time_diff %}
</div>
{% if perms.taskapp.view_extracomment %}
<div class="col-sm-6">
{% include "taskapp/comments/task_comments.html" with comments=comments task_uid=task.pk comment_form=comment_form %}
</div>
{% endif %}
{% endif %} {% endif %}
</div> </div>

18
taskapp/templates/taskapp/comments/task_comments.html

@ -26,13 +26,15 @@
</div> </div>
{% endfor %} {% endfor %}
</div> </div>
<form action="{% url 'taskapp:comment_add' task_uid %}" method="post">{% csrf_token %}
{% bootstrap_form comment_form %}
{% buttons %}
<button type="submit" class="btn btn-primary">
{% bootstrap_icon "send" %} {% trans 'Send' %}
</button>
{% endbuttons %}
</form>
{% if perms.taskapp.add_extracomment %}
<form action="{% url 'taskapp:comment_add' task_uid %}" method="post">{% csrf_token %}
{% bootstrap_form comment_form %}
{% buttons %}
<button type="submit" class="btn btn-primary">
{% bootstrap_icon "send" %} {% trans 'Send' %}
</button>
{% endbuttons %}
</form>
{% endif %}
</div> </div>
</div> </div>

19
taskapp/views.py

@ -27,16 +27,14 @@ from .forms import TaskFrm, ExtraCommentForm
login_decs = login_required, only_admins login_decs = login_required, only_admins
class BaseTaskListView(ListView):
http_method_names = ('get',)
paginate_by = getattr(settings, 'PAGINATION_ITEMS_PER_PAGE', 10)
@method_decorator(login_decs, name='dispatch') @method_decorator(login_decs, name='dispatch')
class NewTasksView(BaseTaskListView):
@method_decorator(permission_required('taskapp.view_task'), name='dispatch')
class NewTasksView(ListView):
""" """
Show new tasks Show new tasks
""" """
http_method_names = ('get',)
paginate_by = getattr(settings, 'PAGINATION_ITEMS_PER_PAGE', 10)
template_name = 'taskapp/tasklist.html' template_name = 'taskapp/tasklist.html'
context_object_name = 'tasks' context_object_name = 'tasks'
@ -47,6 +45,7 @@ class NewTasksView(BaseTaskListView):
@method_decorator(login_decs, name='dispatch') @method_decorator(login_decs, name='dispatch')
@method_decorator(permission_required('taskapp.view_task'), name='dispatch')
class FailedTasksView(NewTasksView): class FailedTasksView(NewTasksView):
""" """
Show crashed tasks Show crashed tasks
@ -60,6 +59,7 @@ class FailedTasksView(NewTasksView):
@method_decorator(login_decs, name='dispatch') @method_decorator(login_decs, name='dispatch')
@method_decorator(permission_required('taskapp.view_task'), name='dispatch')
class FinishedTaskListView(NewTasksView): class FinishedTaskListView(NewTasksView):
template_name = 'taskapp/tasklist_finish.html' template_name = 'taskapp/tasklist_finish.html'
@ -69,6 +69,7 @@ class FinishedTaskListView(NewTasksView):
@method_decorator(login_decs, name='dispatch') @method_decorator(login_decs, name='dispatch')
@method_decorator(permission_required('taskapp.view_task'), name='dispatch')
class OwnTaskListView(NewTasksView): class OwnTaskListView(NewTasksView):
template_name = 'taskapp/tasklist_own.html' template_name = 'taskapp/tasklist_own.html'
@ -80,6 +81,7 @@ class OwnTaskListView(NewTasksView):
@method_decorator(login_decs, name='dispatch') @method_decorator(login_decs, name='dispatch')
@method_decorator(permission_required('taskapp.view_task'), name='dispatch')
class MyTaskListView(NewTasksView): class MyTaskListView(NewTasksView):
template_name = 'taskapp/tasklist.html' template_name = 'taskapp/tasklist.html'
@ -91,7 +93,9 @@ class MyTaskListView(NewTasksView):
@method_decorator(login_decs, name='dispatch') @method_decorator(login_decs, name='dispatch')
@method_decorator(permission_required('taskapp.can_viewall'), name='dispatch') @method_decorator(permission_required('taskapp.can_viewall'), name='dispatch')
class AllTasksListView(BaseTaskListView):
class AllTasksListView(ListView):
http_method_names = ('get',)
paginate_by = getattr(settings, 'PAGINATION_ITEMS_PER_PAGE', 10)
template_name = 'taskapp/tasklist_all.html' template_name = 'taskapp/tasklist_all.html'
context_object_name = 'tasks' context_object_name = 'tasks'
@ -101,6 +105,7 @@ class AllTasksListView(BaseTaskListView):
@method_decorator(login_decs, name='dispatch') @method_decorator(login_decs, name='dispatch')
@method_decorator(permission_required('taskapp.view_task'), name='dispatch')
class EmptyTasksListView(NewTasksView): class EmptyTasksListView(NewTasksView):
template_name = 'taskapp/tasklist_empty.html' template_name = 'taskapp/tasklist_empty.html'

54
templates/base.html

@ -36,20 +36,24 @@
</a> </a>
</li> </li>
{% url 'taskapp:home' as task_home %}
<li{% if task_home in request.path %} class="active"{% endif %}>
<a href="{{ task_home }}">
<span class="glyphicon glyphicon-tasks"></span> {% trans 'Tasks' %}
{% if tasks_count > 0 %}<span class="badge">{{ tasks_count }}</span>{% endif %}
</a>
</li>
{% if perms.taskapp.view_task %}
{% url 'taskapp:home' as task_home %}
<li{% if task_home in request.path %} class="active"{% endif %}>
<a href="{{ task_home }}">
<span class="glyphicon glyphicon-tasks"></span> {% trans 'Tasks' %}
{% if tasks_count > 0 %}<span class="badge">{{ tasks_count }}</span>{% endif %}
</a>
</li>
{% endif %}
{% url 'group_app:group_list' as group_list_link %}
<li{% if group_list_link in request.path %} class="active"{% endif %}>
<a href="{{ group_list_link }}">
<span class="glyphicon glyphicon-list-alt"></span> {% trans 'Groups' %}
</a>
</li>
{% if perms.group_app.view_group %}
{% url 'group_app:group_list' as group_list_link %}
<li{% if group_list_link in request.path %} class="active"{% endif %}>
<a href="{{ group_list_link }}">
<span class="glyphicon glyphicon-list-alt"></span> {% trans 'Groups' %}
</a>
</li>
{% endif %}
{% url 'tarifs:home' as tarifs_home %} {% url 'tarifs:home' as tarifs_home %}
<li{% if tarifs_home in request.path %} class="active"{% endif %}> <li{% if tarifs_home in request.path %} class="active"{% endif %}>
@ -85,12 +89,12 @@
</li> </li>
{% if perms.dialing_app.change_asteriskcdr %} {% if perms.dialing_app.change_asteriskcdr %}
{% url 'dialapp:home' as dialhome %}
<li{% if dialhome in request.path %} class="active"{% endif %}>
<a href="{{ dialhome }}">
<span class="glyphicon glyphicon-phone-alt"></span> {% trans 'Dialing' %}
</a>
</li>
{% url 'dialapp:home' as dialhome %}
<li{% if dialhome in request.path %} class="active"{% endif %}>
<a href="{{ dialhome }}">
<span class="glyphicon glyphicon-phone-alt"></span> {% trans 'Dialing' %}
</a>
</li>
{% endif %} {% endif %}
{% url 'devapp:group_list' as devapp_groups %} {% url 'devapp:group_list' as devapp_groups %}
@ -101,12 +105,12 @@
</li> </li>
{% if perms.nas_app.view_nasmodel %} {% if perms.nas_app.view_nasmodel %}
{% url 'nas_app:home' as nashome %}
<li{% if nashome in request.path %} class="active"{% endif %}>
<a href="{{ nashome }}">
<span class="glyphicon glyphicon-globe"></span> {% trans 'NAS' %}
</a>
</li>
{% url 'nas_app:home' as nashome %}
<li{% if nashome in request.path %} class="active"{% endif %}>
<a href="{{ nashome }}">
<span class="glyphicon glyphicon-globe"></span> {% trans 'NAS' %}
</a>
</li>
{% endif %} {% endif %}
</ul> </ul>

Loading…
Cancel
Save