Update permissions metadata at each map save

This fix the issue where the permissions panel was not available
on first save (without reloading the page).
This commit is contained in:
Yohan Boniface 2018-09-23 09:56:30 +02:00
parent e1844483d7
commit f3ecc8ce28
5 changed files with 75 additions and 48 deletions

View file

@ -1074,6 +1074,11 @@ L.U.Map.include({
if (!this.options.umap_id) { if (!this.options.umap_id) {
duration = 100000; // we want a longer message at map creation (TODO UGLY) duration = 100000; // we want a longer message at map creation (TODO UGLY)
this.options.umap_id = data.id; this.options.umap_id = data.id;
this.permissions.setOptions(data.permissions)
} else if (!this.permissions.isDirty) {
// Do not override local changes to permissions,
// but update in case some other editors changed them in the meantime.
this.permissions.setOptions(data.permissions)
} }
// Update URL in case the name has changed. // Update URL in case the name has changed.
if (history && history.pushState) history.pushState({}, this.options.name, data.url); if (history && history.pushState) history.pushState({}, this.options.name, data.url);

View file

@ -10,7 +10,7 @@ L.U.MapPermissions = L.Class.extend({
}, },
initialize: function (map) { initialize: function (map) {
this.options = map.options.permissions || {}; this.setOptions(map.options.permissions);
this.map = map; this.map = map;
var isDirty = false, var isDirty = false,
self = this; self = this;
@ -31,6 +31,10 @@ L.U.MapPermissions = L.Class.extend({
}, },
setOptions: function (options) {
this.options = L.Util.setOptions(this, options);
},
isOwner: function () { isOwner: function () {
return this.map.options.user && this.options.owner && this.map.options.user.id == this.options.owner.id; return this.map.options.user && this.options.owner && this.map.options.user.id == this.options.owner.id;
}, },
@ -49,8 +53,8 @@ L.U.MapPermissions = L.Class.extend({
fields = [], fields = [],
title = L.DomUtil.create('h4', '', container); title = L.DomUtil.create('h4', '', container);
if (this.isAnonymousMap()) { if (this.isAnonymousMap()) {
if (this.map.options.anonymous_edit_url) { if (this.options.anonymous_edit_url) {
var helpText = L._('Secret edit link is:<br>{link}', {link: this.map.options.anonymous_edit_url}); var helpText = L._('Secret edit link is:<br>{link}', {link: this.options.anonymous_edit_url});
fields.push(['options.edit_status', {handler: 'IntSelect', label: L._('Who can edit'), selectOptions: this.map.options.anonymous_edit_statuses, helpText: helpText}]); fields.push(['options.edit_status', {handler: 'IntSelect', label: L._('Who can edit'), selectOptions: this.map.options.anonymous_edit_statuses, helpText: helpText}]);
} }
} else { } else {

View file

@ -33,7 +33,7 @@ describe('L.Permissions', function () {
var button; var button;
it('should only allow edit_status', function () { it('should only allow edit_status', function () {
this.map.options.anonymous_edit_url = 'http://anonymous.url' this.map.permissions.options.anonymous_edit_url = 'http://anonymous.url';
button = qs('a.update-map-permissions'); button = qs('a.update-map-permissions');
happen.click(button); happen.click(button);
expect(qs('select[name="edit_status"]')).to.be.ok; expect(qs('select[name="edit_status"]')).to.be.ok;

View file

@ -35,6 +35,18 @@ def test_create(client, user, post_data):
assert created_map.name == name assert created_map.name == name
assert created_map.center.x == 13.447265624999998 assert created_map.center.x == 13.447265624999998
assert created_map.center.y == 48.94415123418794 assert created_map.center.y == 48.94415123418794
assert j['permissions'] == {
'edit_status': 3,
'share_status': 1,
'owner': {
'id': user.pk,
'name': 'Joe',
'url': '/en/user/Joe/'
},
'editors': [],
'anonymous_edit_url': ('http://umap.org'
+ created_map.get_anonymous_edit_url())
}
def test_map_create_permissions(client, settings): def test_map_create_permissions(client, settings):
@ -315,6 +327,8 @@ def test_anonymous_create(cookieclient, post_data):
j = json.loads(response.content.decode()) j = json.loads(response.content.decode())
created_map = Map.objects.latest('pk') created_map = Map.objects.latest('pk')
assert j['id'] == created_map.pk assert j['id'] == created_map.pk
assert (created_map.get_anonymous_edit_url()
in j['permissions']['anonymous_edit_url'])
assert created_map.name == name assert created_map.name == name
key, value = created_map.signed_cookie_elements key, value = created_map.signed_cookie_elements
assert key in cookieclient.cookies assert key in cookieclient.cookies

View file

@ -382,6 +382,14 @@ class MapDetailMixin:
locale = to_locale(locale) locale = to_locale(locale)
properties['locale'] = locale properties['locale'] = locale
context['locale'] = locale context['locale'] = locale
user = self.request.user
if not user.is_anonymous:
properties['user'] = {
'id': user.pk,
'name': user.get_username(),
'url': reverse(settings.USER_MAPS_URL,
args=(user.get_username(), ))
}
map_settings = self.get_geojson() map_settings = self.get_geojson()
if "properties" not in map_settings: if "properties" not in map_settings:
map_settings['properties'] = {} map_settings['properties'] = {}
@ -416,7 +424,34 @@ class MapDetailMixin:
return None return None
class MapView(MapDetailMixin, DetailView): class PermissionsMixin:
def get_permissions(self):
permissions = {}
permissions['edit_status'] = self.object.edit_status
permissions['share_status'] = self.object.share_status
if self.object.owner:
permissions['owner'] = {
'id': self.object.owner.pk,
'name': self.object.owner.get_username(),
'url': reverse(settings.USER_MAPS_URL,
args=(self.object.owner.get_username(), ))
}
permissions['editors'] = [{
'id': editor.pk,
'name': editor.get_username(),
} for editor in self.object.editors.all()]
if (not self.object.owner
and self.object.is_anonymous_owner(self.request)):
permissions['anonymous_edit_url'] = self.get_anonymous_edit_url()
return permissions
def get_anonymous_edit_url(self):
anonymous_url = self.object.get_anonymous_edit_url()
return f'{settings.SITE_URL}{anonymous_url}'
class MapView(MapDetailMixin, PermissionsMixin, DetailView):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
self.object = self.get_object() self.object = self.get_object()
@ -455,36 +490,7 @@ class MapView(MapDetailMixin, DetailView):
if "properties" not in map_settings: if "properties" not in map_settings:
map_settings['properties'] = {} map_settings['properties'] = {}
map_settings['properties']['name'] = self.object.name map_settings['properties']['name'] = self.object.name
permissions = {} map_settings['properties']['permissions'] = self.get_permissions()
permissions['edit_status'] = self.object.edit_status
permissions['share_status'] = self.object.share_status
if self.object.owner:
permissions['owner'] = {
'id': self.object.owner.pk,
'name': self.object.owner.get_username(),
'url': reverse(settings.USER_MAPS_URL,
args=(self.object.owner.get_username(), ))
}
permissions['editors'] = [{
'id': editor.pk,
'name': editor.get_username(),
} for editor in self.object.editors.all()]
map_settings['properties']['permissions'] = permissions
user = self.request.user
if not user.is_anonymous:
map_settings['properties']['user'] = {
'id': user.pk,
'name': user.get_username(),
'url': reverse(settings.USER_MAPS_URL,
args=(user.get_username(), ))
}
if (not self.object.owner
and self.object.is_anonymous_owner(self.request)):
anonymous_url = "%s%s" % (
settings.SITE_URL,
self.object.get_anonymous_edit_url()
)
map_settings['properties']['anonymous_edit_url'] = anonymous_url
return map_settings return map_settings
@ -502,7 +508,7 @@ class MapNew(MapDetailMixin, TemplateView):
template_name = "umap/map_detail.html" template_name = "umap/map_detail.html"
class MapCreate(FormLessEditMixin, CreateView): class MapCreate(FormLessEditMixin, PermissionsMixin, CreateView):
model = Map model = Map
form_class = MapSettingsForm form_class = MapSettingsForm
@ -510,11 +516,8 @@ class MapCreate(FormLessEditMixin, CreateView):
if self.request.user.is_authenticated: if self.request.user.is_authenticated:
form.instance.owner = self.request.user form.instance.owner = self.request.user
self.object = form.save() self.object = form.save()
anonymous_url = self.get_anonymous_edit_url()
if not self.request.user.is_authenticated: if not self.request.user.is_authenticated:
anonymous_url = "%s%s" % (
settings.SITE_URL,
self.object.get_anonymous_edit_url()
)
msg = _( msg = _(
"Your map has been created! If you want to edit this map from " "Your map has been created! If you want to edit this map from "
"another computer, please use this link: %(anonymous_url)s" "another computer, please use this link: %(anonymous_url)s"
@ -522,9 +525,13 @@ class MapCreate(FormLessEditMixin, CreateView):
) )
else: else:
msg = _("Congratulations, your map has been created!") msg = _("Congratulations, your map has been created!")
permissions = self.get_permissions()
# User does not have the cookie yet.
permissions['anonymous_edit_url'] = anonymous_url
response = simple_json_response( response = simple_json_response(
id=self.object.pk, id=self.object.pk,
url=self.object.get_absolute_url(), url=self.object.get_absolute_url(),
permissions=permissions,
info=msg info=msg
) )
if not self.request.user.is_authenticated: if not self.request.user.is_authenticated:
@ -537,7 +544,7 @@ class MapCreate(FormLessEditMixin, CreateView):
return response return response
class MapUpdate(FormLessEditMixin, UpdateView): class MapUpdate(FormLessEditMixin, PermissionsMixin, UpdateView):
model = Map model = Map
form_class = MapSettingsForm form_class = MapSettingsForm
pk_url_kwarg = 'map_id' pk_url_kwarg = 'map_id'
@ -548,7 +555,8 @@ class MapUpdate(FormLessEditMixin, UpdateView):
return simple_json_response( return simple_json_response(
id=self.object.pk, id=self.object.pk,
url=self.object.get_absolute_url(), url=self.object.get_absolute_url(),
info=_("Map has been updated!") permissions=self.get_permissions(),
info=_("Map has been updated!"),
) )
@ -607,7 +615,7 @@ class MapDelete(DeleteView):
return simple_json_response(redirect="/") return simple_json_response(redirect="/")
class MapClone(View): class MapClone(PermissionsMixin, View):
def post(self, *args, **kwargs): def post(self, *args, **kwargs):
if not getattr(settings, "UMAP_ALLOW_ANONYMOUS", False) \ if not getattr(settings, "UMAP_ALLOW_ANONYMOUS", False) \
@ -623,14 +631,10 @@ class MapClone(View):
value=value, value=value,
max_age=ANONYMOUS_COOKIE_MAX_AGE max_age=ANONYMOUS_COOKIE_MAX_AGE
) )
anonymous_url = "%s%s" % (
settings.SITE_URL,
self.object.get_anonymous_edit_url()
)
msg = _( msg = _(
"Your map has been cloned! If you want to edit this map from " "Your map has been cloned! If you want to edit this map from "
"another computer, please use this link: %(anonymous_url)s" "another computer, please use this link: %(anonymous_url)s"
% {"anonymous_url": anonymous_url} % {"anonymous_url": self.get_anonymous_edit_url()}
) )
else: else:
msg = _("Congratulations, your map has been cloned!") msg = _("Congratulations, your map has been cloned!")