diff --git a/issue/forms.py b/issue/forms.py index 9b2d929..9e72c3f 100644 --- a/issue/forms.py +++ b/issue/forms.py @@ -26,15 +26,21 @@ class IssueForm(forms.Form): class CommentForm(forms.Form): comment = forms.CharField(widget=MarkdownWidget) -class GlobalPermissionForm(forms.ModelForm): +class PermissionForm(forms.ModelForm): class Meta: - model = GlobalPermission - exclude = ['content_type'] + model = PermissionModel + exclude = [] + abstract = True def clean(self): - data = super(GlobalPermissionForm, self).clean() + data = super(PermissionForm, self).clean() + + if not 'grantee_name' in data or not 'grantee_type' in data: + # a field required error will be printed so we dont care + return data + name = data['grantee_name'] if int(data['grantee_type']) == PermissionModel.GRANTEE_USER: @@ -48,3 +54,15 @@ class GlobalPermissionForm(forms.ModelForm): raise ValidationError("Team '%s' does not exists." %name) return data + +class GlobalPermissionForm(PermissionForm): + + class Meta: + model = GlobalPermission + exclude = [] + +class ProjectPermissionForm(PermissionForm): + + class Meta: + model = ProjectPermission + exclude = [] diff --git a/issue/migrations/0009_auto_20140808_1635.py b/issue/migrations/0009_auto_20140808_1635.py new file mode 100644 index 0000000..d2fb17d --- /dev/null +++ b/issue/migrations/0009_auto_20140808_1635.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('issue', '0008_auto_20140808_0222'), + ] + + operations = [ + migrations.AlterField( + model_name='projectpermission', + name='project', + field=models.ForeignKey(editable=False, to='issue.Project'), + ), + ] diff --git a/issue/models.py b/issue/models.py index ecb1a6d..8d6ce17 100644 --- a/issue/models.py +++ b/issue/models.py @@ -388,7 +388,7 @@ class GlobalPermission(PermissionModel): class ProjectPermission(PermissionModel): - project = models.ForeignKey(Project, related_name='permissions') + project = models.ForeignKey(Project, related_name='permissions', editable=False) create_issue = models.BooleanField(default=True) modify_issue = models.BooleanField(default=False) diff --git a/issue/templates/issue/global_permission_list.html b/issue/templates/issue/global_permission_list.html index 2bfce69..a71bb72 100644 --- a/issue/templates/issue/global_permission_list.html +++ b/issue/templates/issue/global_permission_list.html @@ -10,7 +10,7 @@

- Permissions + Global permissions @@ -18,23 +18,23 @@

{% if permissions.count %} - +
- - - + + + {% for perm in permissions %} - - - - + + + diff --git a/issue/templates/issue/project.html b/issue/templates/issue/project.html index 252fb76..8ea81b0 100644 --- a/issue/templates/issue/project.html +++ b/issue/templates/issue/project.html @@ -4,8 +4,10 @@ {% block page_title %}{{ project }}{% endblock %} {% block projectmenu %} +
  • Manage permissions
  • Modify this project
  • Delete this project
  • + {% endblock %} {% block navbar %} diff --git a/issue/templates/issue/project_add.html b/issue/templates/issue/project_add.html new file mode 100644 index 0000000..ab6f00e --- /dev/null +++ b/issue/templates/issue/project_add.html @@ -0,0 +1,13 @@ +{% extends 'base.html' %} + +{% load crispy_forms_tags %} + +{% block content %} + + + {{ form|crispy }} + {% csrf_token %} + + + +{% endblock %} diff --git a/issue/templates/issue/project_edit.html b/issue/templates/issue/project_edit.html index ab6f00e..fa65db6 100644 --- a/issue/templates/issue/project_edit.html +++ b/issue/templates/issue/project_edit.html @@ -1,4 +1,4 @@ -{% extends 'base.html' %} +{% extends 'issue/project.html' %} {% load crispy_forms_tags %} diff --git a/issue/templates/issue/project_permission_edit.html b/issue/templates/issue/project_permission_edit.html new file mode 100644 index 0000000..6910b27 --- /dev/null +++ b/issue/templates/issue/project_permission_edit.html @@ -0,0 +1,27 @@ +{% extends 'issue/project.html' %} + +{% load crispy_forms_tags %} + +{% block content %} + +
    + +
    +

    + Permissions of {{ project }} project + +

    + +
    +
    + {{ form|crispy }} + {% csrf_token %} + + +
    + +
    + +{% endblock %} diff --git a/issue/templates/issue/project_permission_list.html b/issue/templates/issue/project_permission_list.html new file mode 100644 index 0000000..dd39ff5 --- /dev/null +++ b/issue/templates/issue/project_permission_list.html @@ -0,0 +1,76 @@ +{% extends 'issue/project.html' %} + +{% load django_markdown %} +{% load issue_filters %} +{% load issue_tags %} + +{% block content %} + + +
    + +
    +

    + Permissions of {{ project }} project + +

    +
    + + {% if permissions.count %} +
    Type NameCreate project?Modify project?Delete project?Create project?Modify project?Delete project?
    {{ perm.type }} {{ perm.name }}{{ perm.create_project|boolean }}{{ perm.modify_project|boolean }}{{ perm.delete_project|boolean }} + {{ perm.create_project|boolean }}{{ perm.modify_project|boolean }}{{ perm.delete_project|boolean }}
    + + + + + + + + + + + + + + + + + + + + + + + + + {% for perm in permissions %} + + + + + + + + + + + + + + + + + + {% endfor %} +
    TypeNameIssueCommentLabelMilestone
    {% vertical 'Create?' %}{% vertical 'Modify?' %}{% vertical 'Delete?' %}{% vertical 'Create?' %}{% vertical 'Modify?' %}{% vertical 'Delete?' %}{% vertical 'Create?' %}{% vertical 'Modify?' %}{% vertical 'Delete?' %}{% vertical 'Create?' %}{% vertical 'Modify?' %}{% vertical 'Delete?' %}
    {{ perm.type }}{{ perm.name }}{{ perm.create_issue|boolean }}{{ perm.modify_issue|boolean }}{{ perm.delete_issue|boolean }}{{ perm.create_comment|boolean }}{{ perm.modify_comment|boolean }}{{ perm.delete_comment|boolean }}{{ perm.create_label|boolean }}{{ perm.modify_label|boolean }}{{ perm.delete_label|boolean }}{{ perm.create_milestone|boolean }}{{ perm.modify_milestone|boolean }}{{ perm.delete_milestone|boolean }} + + +
    + {% else %} +
    + There aren't any permissions defined yet. +
    + {% endif %} + +{% endblock %} diff --git a/issue/templatetags/issue_tags.py b/issue/templatetags/issue_tags.py index c7d23b0..ec60696 100644 --- a/issue/templatetags/issue_tags.py +++ b/issue/templatetags/issue_tags.py @@ -48,3 +48,7 @@ def same_author(context, author): url += '?q=is:open%20author:' + author.username return mark_safe(url) + +@register.simple_tag +def vertical(string): + return string.replace("", "\0").strip("\0").replace("\0", "
    ") diff --git a/issue/urls.py b/issue/urls.py index e10f7ab..b3bd4ec 100644 --- a/issue/urls.py +++ b/issue/urls.py @@ -28,6 +28,11 @@ urlpatterns = [ url(r'^(?P[a-z0-9_-]+)/milestones/(?P[a-z0-9_.-]+)/close$', 'issue.views.milestone_close', name='close-milestone'), url(r'^(?P[a-z0-9_-]+)/milestones/(?P[a-z0-9_.-]+)/reopen$', 'issue.views.milestone_reopen', name='reopen-milestone'), url(r'^(?P[a-z0-9_-]+)/milestones/(?P[a-z0-9_.-]+)/delete$', 'issue.views.milestone_delete', name='delete-milestone'), + url(r'^(?P[a-z0-9_-]+)/permissions$', 'issue.views.project_permission_list', name='list-project-permission'), + url(r'^(?P[a-z0-9_-]+)/permissions/add$', 'issue.views.project_permission_edit', name='add-project-permission'), + url(r'^(?P[a-z0-9_-]+)/permissions/(?P[0-9]+)/edit$', 'issue.views.project_permission_edit', name='edit-project-permission'), + url(r'^(?P[a-z0-9_-]+)/permissions/(?P[0-9]+)/toggle/(?P[a-z-]+)$', 'issue.views.project_permission_toggle', name='toggle-project-permission'), + url(r'^(?P[a-z0-9_-]+)/permissions/(?P[0-9]+)/delete$', 'issue.views.project_permission_delete', name='delete-project-permission'), url(r'^permissions$', 'issue.views.global_permission_list', name='list-global-permission'), url(r'^permissions/add$', 'issue.views.global_permission_edit', name='add-global-permission'), url(r'^permissions/(?P[0-9]+)/edit$', 'issue.views.global_permission_edit', name='edit-global-permission'), diff --git a/issue/views.py b/issue/views.py index 2ed0a2d..f887cc3 100644 --- a/issue/views.py +++ b/issue/views.py @@ -34,8 +34,10 @@ def global_permission_edit(request, id=None): if id: permission = get_object_or_404(GlobalPermission, id=id) + new = False else: permission = None + new = True form = GlobalPermissionForm(request.POST or None, instance=permission) @@ -43,7 +45,10 @@ def global_permission_edit(request, id=None): permission = form.save() - messages.success(request, 'Permission added successfully.') + if new: + messages.success(request, 'Permission added successfully.') + else: + messages.success(request, 'Permission updated successfully.') return redirect('list-global-permission') @@ -77,8 +82,77 @@ def global_permission_delete(request, id): permission.delete() + messages.success(request, 'Permission deleted successfully.') + return redirect('list-global-permission') +def project_permission_list(request, project): + + permissions = ProjectPermission.objects.filter(project=project) + + c = { + 'project': project, + 'permissions': permissions, + } + + return render(request, 'issue/project_permission_list.html', c) + +def project_permission_edit(request, project, id=None): + + if id: + permission = get_object_or_404(ProjectPermission, project=project, id=id) + else: + permission = None + + form = ProjectPermissionForm(request.POST or None, instance=permission) + + if request.method == 'POST' and form.is_valid(): + + permission = form.save(commit=False) + if not hasattr(permission, 'project'): + permission.project = project + messages.success(request, 'Permission added successfully.') + else: + messages.success(request, 'Permission updated successfully.') + permission.save() + + return redirect('list-project-permission', project.name) + + c = { + 'project': project, + 'form': form, + } + + return render(request, 'issue/project_permission_edit.html', c) + +def project_permission_toggle(request, project, id, perm): + + permission = get_object_or_404(ProjectPermission, project=project, id=id) + + # to be sure to dont modify other attribut with the following trick + if not '-' in perm: + raise Http404 + perm = perm.replace('-', '_') + + if hasattr(permission, perm): + print(type(getattr(permission, perm))) + setattr(permission, perm, not getattr(permission, perm)) + permission.save() + else: + raise Http404 + + return redirect('list-project-permission', project.name) + +def project_permission_delete(request, project, id): + + permission = get_object_or_404(ProjectPermission, project=project, id=id) + + permission.delete() + + messages.success(request, 'Permission deleted successfully.') + + return redirect('list-project-permission', project.name) + def project_list(request): if not request.projects.exists(): @@ -113,7 +187,7 @@ def project_add(request): 'form': form, } - return render(request, 'issue/project_edit.html', c) + return render(request, 'issue/project_add.html', c) def project_edit(request, project): @@ -136,6 +210,7 @@ def project_edit(request, project): return redirect('list-issue', project.name) c = { + 'project': project, 'form': form, }