fix: catch login_required from map page and add a way to login

This commit is contained in:
Yohan Boniface 2024-07-29 14:49:07 +02:00
parent 8c7ff52f5f
commit 3bdd5bedf1
7 changed files with 67 additions and 15 deletions

View file

@ -152,7 +152,7 @@ WSGI_APPLICATION = "umap.wsgi.application"
LOGIN_URL = "/login/"
LOGOUT_URL = "/logout/"
LOGIN_REDIRECT_URL = "/"
LOGIN_REDIRECT_URL = "login_popup_end"
STATIC_URL = "/static/"
MEDIA_URL = "/uploads/"

View file

@ -640,7 +640,7 @@ const ControlsMixin = {
L.DomEvent.on(shareStatusButton, 'click', this.permissions.edit, this.permissions)
}
this.on('postsync', L.bind(update, this))
if (this.options.user) {
if (this.options.user?.id) {
L.DomUtil.createLink(
'umap-user',
rightContainer,

View file

@ -393,7 +393,7 @@ U.Map = L.Map.extend({
this._controls.search = new U.SearchControl()
this._controls.embed = new L.Control.Embed(this)
this._controls.tilelayersChooser = new U.TileLayerChooser(this)
if (this.options.user) this._controls.star = new U.StarControl(this)
if (this.options.user?.id) this._controls.star = new U.StarControl(this)
this._controls.editinosm = new L.Control.EditInOSM({
position: 'topleft',
widgetOptions: {
@ -1048,7 +1048,15 @@ U.Map = L.Map.extend({
if (error) {
return
}
if (data.login_required) {
window.onLogin = () => this.saveSelf()
window.open(data.login_required)
return
}
if (data.user?.id) {
this.options.user = data.user
this.renderEditToolbar()
}
if (!this.options.umap_id) {
this.options.umap_id = data.id
this.permissions.setOptions(data.permissions)

View file

@ -1,5 +1,10 @@
{% extends "base.html" %}
{% load i18n %}
{% block head_title %}
{% trans "Login" %}
{% endblock head_title %}
{% load umap_tags i18n %}
{% block extra_head %}

View file

@ -5,10 +5,13 @@
</h3>
<script type="text/javascript">
function proceed() {
if (window.opener && window.opener.umap_proceed) {
window.opener.umap_proceed()
if (window.opener?.onLogin) {
// We are in the normal process login
window.opener.onLogin()
window.close()
} else {
// Trade off as Twitter does not allow us to access window.opener
// we may be in login process that includes a magic link, so user
// has opened a new window from this link, and we cannot close it then.
window.location.href = '{% url "user_dashboard" %}'
}
}

View file

@ -1,6 +1,10 @@
import re
import pytest
from playwright.sync_api import expect
from umap.models import Map
def test_page_title(page, live_server):
page.goto(live_server.url)
@ -66,3 +70,28 @@ def test_cannot_put_script_tag_in_datalayer_name_or_description(
expect(page.get_by_text('<script>alert("attack")</script>')).to_be_visible()
# Description should contain escaped HTML
expect(page.get_by_text("before after")).to_be_visible()
def test_login_from_map_page(live_server, page, tilelayer, settings, user, context):
settings.ENABLE_ACCOUNT_LOGIN = True
assert Map.objects.count() == 0
page.goto(f"{live_server.url}/en/map/new/")
with (
page.expect_response(re.compile(r".*/map/create/")),
context.expect_page() as login_page_info,
):
page.get_by_role("button", name="Save").click()
assert Map.objects.count() == 0
login_page = login_page_info.value
expect(login_page).to_have_title("Login")
login_page.get_by_placeholder("Username").fill(user.username)
login_page.get_by_placeholder("Password").fill("123123")
with page.expect_response(re.compile(r".*/map/create/")):
login_page.locator('#login_form input[type="submit"]').click()
# Login page should be closed
page.wait_for_timeout(500) # Seems needed from time to time…
assert len(context.pages) == 1
# Save should have proceed
assert Map.objects.count() == 1
# Use name should now appear on the header toolbar
expect(page.get_by_text("My Dashboard (Joe)")).to_be_visible()

View file

@ -456,6 +456,17 @@ def simple_json_response(**kwargs):
# ############## #
class SessionMixin:
def get_user_data(self):
if self.request.user.is_anonymous:
return {}
return {
"id": self.request.user.pk,
"name": str(self.request.user),
"url": reverse("user_dashboard"),
}
class FormLessEditMixin:
http_method_names = [
"post",
@ -470,7 +481,7 @@ class FormLessEditMixin:
return self.get_form_class()(**kwargs)
class MapDetailMixin:
class MapDetailMixin(SessionMixin):
model = Map
pk_url_kwarg = "map_id"
@ -522,12 +533,7 @@ class MapDetailMixin:
if self.get_short_url():
properties["shortUrl"] = self.get_short_url()
if not user.is_anonymous:
properties["user"] = {
"id": user.pk,
"name": str(user),
"url": reverse("user_dashboard"),
}
properties["user"] = self.get_user_data()
return properties
def get_context_data(self, **kwargs):
@ -755,7 +761,7 @@ class MapPreview(MapDetailMixin, TemplateView):
return properties
class MapCreate(FormLessEditMixin, PermissionsMixin, CreateView):
class MapCreate(FormLessEditMixin, PermissionsMixin, SessionMixin, CreateView):
model = Map
form_class = MapSettingsForm
@ -772,6 +778,7 @@ class MapCreate(FormLessEditMixin, PermissionsMixin, CreateView):
id=self.object.pk,
url=self.object.get_absolute_url(),
permissions=permissions,
user=self.get_user_data(),
)
if not self.request.user.is_authenticated:
key, value = self.object.signed_cookie_elements