mirror of
https://github.com/jwinterm/modoboa.git
synced 2026-10-18 05:51:26 +02:00
wip: Radicale extension.
Check permissions and generate owner access rules.
This commit is contained in:
@@ -128,7 +128,9 @@ class UserCalendarWizard(WizardForm):
|
||||
def __init__(self, request):
|
||||
super(UserCalendarWizard, self).__init__(request)
|
||||
self.add_step(UserCalendarForm, _("General"))
|
||||
self.add_step(RightsForm, _("Rights"))
|
||||
self.add_step(
|
||||
RightsForm, _("Rights"), formtpl="radicale/rightsform.html"
|
||||
)
|
||||
|
||||
def extra_context(self, context):
|
||||
context.update({
|
||||
@@ -141,6 +143,8 @@ class UserCalendarWizard(WizardForm):
|
||||
calendar = self.first_step.form.save(commit=False)
|
||||
calendar.mailbox = self.request.user.mailbox_set.all()[0]
|
||||
calendar.save()
|
||||
self.steps[1].form.calendar = calendar
|
||||
self.steps[1].form.save()
|
||||
return render_to_json_response(_("Calendar created"))
|
||||
|
||||
|
||||
|
||||
@@ -86,6 +86,10 @@ permission = %s
|
||||
"domain-shared-calendars", r"^(.+)@(.+)$", r"{1}/shared/.+$",
|
||||
comment="Access rule to domain shared calendars"
|
||||
)
|
||||
self._generate_acr(
|
||||
"owners-access", r"^(.+)@(.+)$", r"{1}/user/{0}/.+$",
|
||||
comment="Read/Write permission for calendar owners"
|
||||
)
|
||||
|
||||
self._user_access_rules()
|
||||
self._cfgfile.close()
|
||||
|
||||
@@ -31,6 +31,11 @@ class Calendar(models.Model):
|
||||
"""Return calendar type"""
|
||||
raise NotImplementedError
|
||||
|
||||
@property
|
||||
def owner(self):
|
||||
"""Return calendar owner"""
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class UserCalendarManager(models.Manager):
|
||||
"""Custom UserCalendar manager.
|
||||
@@ -70,6 +75,10 @@ class UserCalendar(Calendar):
|
||||
def type(self):
|
||||
return _("user")
|
||||
|
||||
@property
|
||||
def owner(self):
|
||||
return self.mailbox.user
|
||||
|
||||
|
||||
class SharedCalendarManager(models.Manager):
|
||||
"""Custom SharedCalendar manager.
|
||||
@@ -109,6 +118,10 @@ class SharedCalendar(Calendar):
|
||||
def type(self):
|
||||
return _("shared")
|
||||
|
||||
@property
|
||||
def owner(self):
|
||||
return self.domain
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class AccessRule(models.Model):
|
||||
|
||||
@@ -19,7 +19,7 @@ Radicale.prototype = {
|
||||
this.options.defcallback = $.proxy(this.list_cb, this);
|
||||
this.navobj = new History(this.options);
|
||||
$(document).on(
|
||||
"click", "a[name=delcalendar]", this.del_calendar
|
||||
"click", "a[name=delcalendar]", $.proxy(this.del_calendar, this)
|
||||
);
|
||||
},
|
||||
|
||||
@@ -34,13 +34,25 @@ Radicale.prototype = {
|
||||
*
|
||||
*/
|
||||
reload_listing: function(data) {
|
||||
console.log("reload");
|
||||
this.navobj.update(true);
|
||||
if (data) {
|
||||
$("body").notify("success", data, 2000);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Rights form initialization.
|
||||
*/
|
||||
rightsform_init: function() {
|
||||
$("#original_row").dynamicrule();
|
||||
$("#id_username").autocompleter({
|
||||
choices: $.proxy(this.get_username_list, this)
|
||||
});
|
||||
},
|
||||
|
||||
add_calendar_cb: function() {
|
||||
this.rightsform_init();
|
||||
$("#wizard").cwizard({
|
||||
formid: "newcal_form",
|
||||
success_callback: $.proxy(this.reload_listing, this)
|
||||
@@ -64,10 +76,7 @@ Radicale.prototype = {
|
||||
},
|
||||
|
||||
edit_calendar_cb: function() {
|
||||
$("#original_row").dynamicrule();
|
||||
$("#id_username").autocompleter({
|
||||
choices: $.proxy(this.get_username_list, this)
|
||||
});
|
||||
this.rightsform_init();
|
||||
$('.submit').on('click', $.proxy(function(e) {
|
||||
simple_ajax_form_post(e, {
|
||||
formid: "ucal_form",
|
||||
@@ -92,7 +101,7 @@ Radicale.prototype = {
|
||||
*/
|
||||
del_calendar: function(event) {
|
||||
event.preventDefault();
|
||||
var $link = $(this);
|
||||
var $link = get_target(event, "a");
|
||||
|
||||
if (!confirm($link.attr("title"))) {
|
||||
return;
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
<table id="{{ tableid }}" class="table {{ styles }}">
|
||||
<thead>
|
||||
<tr>
|
||||
<th id="name" class="sortable" data-sort_order="identity" width="">{% trans "Name" %}</th>
|
||||
<th id="name" class="sortable" data-sort_order="name" width="">{% trans "Name" %}</th>
|
||||
{% if with_owner %}<th id="owner" class="sortable" data-sort_order="mailbox">{% trans "Owner" %}</th>{% endif %}
|
||||
<th id="type">{% trans "Type" %}</th>
|
||||
<th id="url">{% trans "Address" %}</th>
|
||||
<th id="actions" width="">{% trans "Actions" %}</th>
|
||||
@@ -12,6 +13,7 @@
|
||||
{% for cal in calendars %}
|
||||
<tr id="{{ cal.id }}" class="" name="{{ forloop.counter }}">
|
||||
<td name="name">{% calendar_modify_link cal %}</td>
|
||||
{% if with_owner %}<td name="owner">{{ cal.owner }}</td>{% endif %}
|
||||
<td name="type">
|
||||
<span class="label label-info"><a href="#" class="filter">{{ cal.type }}</a></span>
|
||||
</td>
|
||||
|
||||
@@ -36,14 +36,16 @@ def calendars(request, tplname="radicale/calendar_list.html"):
|
||||
if request.user.group == "SimpleUsers":
|
||||
mbox = request.user.mailbox_set.all()[0]
|
||||
cals = UserCalendar.objects.filter(mailbox=mbox).select_related().all()
|
||||
with_owner = False
|
||||
else:
|
||||
cals = chain(
|
||||
UserCalendar.objects.get_for_admin(request.user),
|
||||
SharedCalendar.objects.get_for_admin(request.user)
|
||||
)
|
||||
with_owner = True
|
||||
return render_to_json_response({
|
||||
"table": _render_to_string(request, tplname, {
|
||||
"calendars": cals
|
||||
"calendars": cals, "with_owner": with_owner
|
||||
})
|
||||
})
|
||||
|
||||
@@ -60,12 +62,14 @@ def user_calendar(request, pk):
|
||||
"""Edit or remove a calendar.
|
||||
"""
|
||||
try:
|
||||
ucal = UserCalendar.objects.get(pk=pk)
|
||||
ucal = UserCalendar.objects.select_related().get(pk=pk)
|
||||
except UserCalendar.DoesNotExist:
|
||||
raise NotFound
|
||||
if request.user != ucal.mailbox.user and \
|
||||
not request.user.can_access(ucal.mailbox.domain):
|
||||
raise PermDeniedException
|
||||
instances = {"general": ucal, "rights": ucal}
|
||||
if request.method == "DELETE":
|
||||
# Check ownership
|
||||
ucal.delete()
|
||||
return render_to_json_response(_("Calendar removed"))
|
||||
return UserCalendarEditionForm(request, instances=instances).process()
|
||||
@@ -104,12 +108,14 @@ def shared_calendar(request, pk):
|
||||
"""Edit or remove a shared calendar.
|
||||
"""
|
||||
try:
|
||||
scal = SharedCalendar.objects.get(pk=pk)
|
||||
scal = SharedCalendar.objects.select_related().get(pk=pk)
|
||||
except SharedCalendar.DoesNotExist:
|
||||
raise NotFound
|
||||
if not request.user.can_access(scal.domain):
|
||||
raise PermDeniedException
|
||||
if request.method == "DELETE":
|
||||
if not request.user.can_access(scal.domain):
|
||||
raise PermDeniedException
|
||||
scal.delete()
|
||||
return render_to_json_response(_("Calendar removed"))
|
||||
if request.method == "POST":
|
||||
|
||||
@@ -34,6 +34,7 @@ class WizardStep(object):
|
||||
|
||||
@property
|
||||
def title(self):
|
||||
"""Return step title"""
|
||||
if self.index is None:
|
||||
return self._title
|
||||
return "%d. %s" % (self.index + 1, self._title)
|
||||
|
||||
Reference in New Issue
Block a user