wip: Radicale extension.

Check permissions and generate owner access rules.
This commit is contained in:
Antoine Nguyen
2014-06-12 17:27:07 +02:00
parent fae22c8dc8
commit bdbd4b0250
7 changed files with 51 additions and 12 deletions
+5 -1
View File
@@ -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()
+13
View File
@@ -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>
+10 -4
View File
@@ -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":
+1
View File
@@ -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)