WIP: final bit to make sending edit link working
This commit is contained in:
parent
eb32dcc9b6
commit
8f52d34bb2
7 changed files with 87 additions and 28 deletions
|
@ -114,6 +114,8 @@ INSTALLED_APPS = (
|
||||||
)
|
)
|
||||||
DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
|
DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
|
||||||
|
|
||||||
|
EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# Calculation of directories relative to the project module location
|
# Calculation of directories relative to the project module location
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
|
|
|
@ -748,6 +748,10 @@ input[type=hidden].blur + .button {
|
||||||
.umap-alert .error .umap-action:hover {
|
.umap-alert .error .umap-action:hover {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
.umap-alert input {
|
||||||
|
padding: 5px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
/* *********** */
|
/* *********** */
|
||||||
/* Tooltip */
|
/* Tooltip */
|
||||||
|
|
|
@ -1345,10 +1345,9 @@ L.U.Map.include({
|
||||||
if (data.permissions && data.permissions.anonymous_edit_url) {
|
if (data.permissions && data.permissions.anonymous_edit_url) {
|
||||||
alert.actions = [
|
alert.actions = [
|
||||||
{
|
{
|
||||||
label: L._('Send me edit link by email'),
|
label: L._('Send me the link'),
|
||||||
callback: function () {
|
input: L._('Email'),
|
||||||
this.sendEditLink()
|
callback: this.sendEditLink,
|
||||||
},
|
|
||||||
callbackContext: this,
|
callbackContext: this,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
@ -1374,8 +1373,16 @@ L.U.Map.include({
|
||||||
},
|
},
|
||||||
|
|
||||||
sendEditLink: function () {
|
sendEditLink: function () {
|
||||||
var url = L.Util.template(this.options.urls.map_send_edit_link, {
|
const url = L.Util.template(this.options.urls.map_send_edit_link, {
|
||||||
map_id: this.options.umap_id,
|
map_id: this.options.umap_id,
|
||||||
|
}),
|
||||||
|
input = this.ui._alert.querySelector('input'),
|
||||||
|
email = input.value
|
||||||
|
|
||||||
|
const formData = new FormData()
|
||||||
|
formData.append('email', email)
|
||||||
|
this.post(url, {
|
||||||
|
data: formData,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,6 @@ L.U.UI = L.Evented.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
popAlert: function (e) {
|
popAlert: function (e) {
|
||||||
const self = this
|
|
||||||
if (!e) {
|
if (!e) {
|
||||||
if (this.ALERTS.length) e = this.ALERTS.pop()
|
if (this.ALERTS.length) e = this.ALERTS.pop()
|
||||||
else return
|
else return
|
||||||
|
@ -108,20 +107,25 @@ L.U.UI = L.Evented.extend({
|
||||||
)
|
)
|
||||||
L.DomUtil.add('div', '', this._alert, e.content)
|
L.DomUtil.add('div', '', this._alert, e.content)
|
||||||
if (e.actions) {
|
if (e.actions) {
|
||||||
let action, el
|
let action, el, input
|
||||||
for (let i = 0; i < e.actions.length; i++) {
|
for (let i = 0; i < e.actions.length; i++) {
|
||||||
action = e.actions[i]
|
action = e.actions[i]
|
||||||
|
if (action.input) {
|
||||||
|
input = L.DomUtil.element(
|
||||||
|
'input',
|
||||||
|
{ className: 'umap-alert-input', placeholder: action.input },
|
||||||
|
this._alert
|
||||||
|
)
|
||||||
|
}
|
||||||
el = L.DomUtil.element('a', { className: 'umap-action' }, this._alert)
|
el = L.DomUtil.element('a', { className: 'umap-action' }, this._alert)
|
||||||
el.href = '#'
|
el.href = '#'
|
||||||
el.textContent = action.label
|
el.textContent = action.label
|
||||||
L.DomEvent.on(el, 'click', L.DomEvent.stop).on(el, 'click', close, this)
|
L.DomEvent.on(el, 'click', L.DomEvent.stop).on(el, 'click', close, this)
|
||||||
if (action.callback)
|
if (action.callback)
|
||||||
L.DomEvent.on(
|
L.DomEvent.on(el, 'click', () => {
|
||||||
el,
|
action.callback.bind(action.callbackContext || this.map)()
|
||||||
'click',
|
close.bind(this)()
|
||||||
action.callback,
|
})
|
||||||
action.callbackContext || this.map
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (e.duration !== Infinity) {
|
if (e.duration !== Infinity) {
|
||||||
|
|
|
@ -4,6 +4,8 @@ from umap.settings.base import * # pylint: disable=W0614,W0401
|
||||||
|
|
||||||
SECRET_KEY = "justfortests"
|
SECRET_KEY = "justfortests"
|
||||||
COMPRESS_ENABLED = False
|
COMPRESS_ENABLED = False
|
||||||
|
FROM_EMAIL = "test@test.org"
|
||||||
|
EMAIL_BACKEND = 'django.core.mail.backends.locmem.EmailBackend'
|
||||||
|
|
||||||
if "TRAVIS" in os.environ:
|
if "TRAVIS" in os.environ:
|
||||||
DATABASES = {
|
DATABASES = {
|
||||||
|
|
|
@ -2,9 +2,10 @@ import json
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
|
from django.core import mail
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
|
||||||
from django.core.signing import Signer
|
from django.core.signing import Signer
|
||||||
|
|
||||||
from umap.models import DataLayer, Map, Star
|
from umap.models import DataLayer, Map, Star
|
||||||
|
|
||||||
from .base import login_required
|
from .base import login_required
|
||||||
|
@ -568,3 +569,32 @@ def test_user_can_see_their_star(client, map, user):
|
||||||
response = client.get(url)
|
response = client.get(url)
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
assert map.name in response.content.decode()
|
assert map.name in response.content.decode()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.usefixtures("allow_anonymous")
|
||||||
|
def test_cannot_send_link_on_owned_map(client, map):
|
||||||
|
assert len(mail.outbox) == 0
|
||||||
|
url = reverse("map_send_edit_link", args=(map.pk,))
|
||||||
|
resp = client.post(url, {"email": "foo@bar.org"})
|
||||||
|
assert resp.status_code == 200
|
||||||
|
assert json.loads(resp.content.decode()) == {"login_required": "/en/login/"}
|
||||||
|
assert len(mail.outbox) == 0
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.usefixtures("allow_anonymous")
|
||||||
|
def test_cannot_send_link_on_anonymous_map_without_cookie(client, anonymap):
|
||||||
|
assert len(mail.outbox) == 0
|
||||||
|
url = reverse("map_send_edit_link", args=(anonymap.pk,))
|
||||||
|
resp = client.post(url, {"email": "foo@bar.org"})
|
||||||
|
assert resp.status_code == 403
|
||||||
|
assert len(mail.outbox) == 0
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.usefixtures("allow_anonymous")
|
||||||
|
def test_can_send_link_on_anonymous_map_with_cookie(cookieclient, anonymap):
|
||||||
|
assert len(mail.outbox) == 0
|
||||||
|
url = reverse("map_send_edit_link", args=(anonymap.pk,))
|
||||||
|
resp = cookieclient.post(url, {"email": "foo@bar.org"})
|
||||||
|
assert resp.status_code == 200
|
||||||
|
assert len(mail.outbox) == 1
|
||||||
|
assert mail.outbox[0].subject == "Your secret edit link"
|
||||||
|
|
|
@ -12,6 +12,7 @@ from django.contrib.auth import logout as do_logout
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
from django.contrib.gis.measure import D
|
from django.contrib.gis.measure import D
|
||||||
from django.contrib.postgres.search import SearchQuery, SearchVector
|
from django.contrib.postgres.search import SearchQuery, SearchVector
|
||||||
|
from django.core.mail import send_mail
|
||||||
from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
|
from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
|
||||||
from django.core.signing import BadSignature, Signer
|
from django.core.signing import BadSignature, Signer
|
||||||
from django.core.validators import URLValidator, ValidationError
|
from django.core.validators import URLValidator, ValidationError
|
||||||
|
@ -33,7 +34,7 @@ from django.utils.translation import to_locale
|
||||||
from django.views.generic import DetailView, TemplateView, View
|
from django.views.generic import DetailView, TemplateView, View
|
||||||
from django.views.generic.base import RedirectView
|
from django.views.generic.base import RedirectView
|
||||||
from django.views.generic.detail import BaseDetailView
|
from django.views.generic.detail import BaseDetailView
|
||||||
from django.views.generic.edit import CreateView, DeleteView, UpdateView
|
from django.views.generic.edit import CreateView, DeleteView, FormView, UpdateView
|
||||||
from django.views.generic.list import ListView
|
from django.views.generic.list import ListView
|
||||||
|
|
||||||
from .forms import (
|
from .forms import (
|
||||||
|
@ -44,6 +45,7 @@ from .forms import (
|
||||||
DataLayerForm,
|
DataLayerForm,
|
||||||
FlatErrorList,
|
FlatErrorList,
|
||||||
MapSettingsForm,
|
MapSettingsForm,
|
||||||
|
SendLinkForm,
|
||||||
UpdateMapPermissionsForm,
|
UpdateMapPermissionsForm,
|
||||||
)
|
)
|
||||||
from .models import DataLayer, Licence, Map, Pictogram, Star, TileLayer
|
from .models import DataLayer, Licence, Map, Pictogram, Star, TileLayer
|
||||||
|
@ -618,26 +620,34 @@ class AttachAnonymousMap(View):
|
||||||
return simple_json_response()
|
return simple_json_response()
|
||||||
|
|
||||||
|
|
||||||
class SendEditLink(FormLessEditMixin, PermissionsMixin, UpdateView):
|
class SendEditLink(FormLessEditMixin, FormView):
|
||||||
model = Map
|
form_class = SendLinkForm
|
||||||
pk_url_kwarg = 'map_id'
|
|
||||||
|
|
||||||
def form_valid(self, form):
|
def post(self, form, **kwargs):
|
||||||
if (self.object.owner
|
self.object = kwargs["map_inst"]
|
||||||
|
if (
|
||||||
|
self.object.owner
|
||||||
or not self.object.is_anonymous_owner(self.request)
|
or not self.object.is_anonymous_owner(self.request)
|
||||||
or not self.object.can_edit(self.request.user, self.request)):
|
or not self.object.can_edit(self.request.user, self.request)
|
||||||
|
):
|
||||||
return HttpResponseForbidden()
|
return HttpResponseForbidden()
|
||||||
|
form = self.get_form()
|
||||||
|
if form.is_valid():
|
||||||
email = form.cleaned_data["email"]
|
email = form.cleaned_data["email"]
|
||||||
from django.core.mail import send_mail
|
else:
|
||||||
|
return HttpResponseBadRequest("Invalid")
|
||||||
|
link = self.object.get_anonymous_edit_url()
|
||||||
|
|
||||||
send_mail(
|
send_mail(
|
||||||
_('Your secret edit link'),
|
_("Your secret edit link"),
|
||||||
_('Here is your secret edit link: %(link)s' % {"link": link}),
|
_("Here is your secret edit link: %(link)s" % {"link": link}),
|
||||||
settings.FROM_EMAIL,
|
settings.FROM_EMAIL,
|
||||||
[email],
|
[email],
|
||||||
fail_silently=False,
|
fail_silently=False,
|
||||||
)
|
)
|
||||||
return simple_json_response(info=_("Email sent to %(email)s" % {"email": email}))
|
return simple_json_response(
|
||||||
|
info=_("Email sent to %(email)s" % {"email": email})
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class MapDelete(DeleteView):
|
class MapDelete(DeleteView):
|
||||||
|
|
Loading…
Reference in a new issue