Repository: pretalx/pretalx

Issue:
Speaker Submission Confirm URL - 404 Response
## Expected Behavior
The mailed submission confirm links should redirect to the login page if the speaker is not
logged in.

## Current Behavior
404 Error:
```
WARNING 2018-05-27 09:22:30,574 django.request base Not Found: /EVENT/me/submissions/CODE/confirm
```

## Steps to Reproduce (for bugs)
Open link: /EVENT/me/submissions/CODE/confirm without permission (not logged in)

## Your Environment
<!--- Include as many relevant details about the environment you experienced the bug in -->
* Version used: 0.6.1
* Environment name and version: Chrome 66
* Operating System and version (desktop or mobile): Desktop
* Link to your project: https://fahrplan.podstock.de/



Discussion:
Hm, yes, this should show a login page instead.

Resolving patch:
diff --git a/src/pretalx/cfp/views/event.py b/src/pretalx/cfp/views/event.py
--- a/src/pretalx/cfp/views/event.py
+++ b/src/pretalx/cfp/views/event.py
@@ -14,7 +14,8 @@ def get_permission_object(self):
         return getattr(self.request, 'event', None)
 
 
-class LoggedInEventPageMixin(EventPageMixin, LoginRequiredMixin):
+# check login first, then permission so users get redirected to /login, if they are missing one
+class LoggedInEventPageMixin(LoginRequiredMixin, EventPageMixin):
 
     def get_login_url(self) -> str:
         return reverse('cfp:event.login', kwargs={
diff --git a/src/pretalx/cfp/views/user.py b/src/pretalx/cfp/views/user.py
--- a/src/pretalx/cfp/views/user.py
+++ b/src/pretalx/cfp/views/user.py
@@ -140,8 +140,6 @@ def get_permission_object(self):
         return self.get_object()
 
     def post(self, request, *args, **kwargs):
-        if request.user.is_anonymous:
-            return redirect(request.event.urls.login)
         submission = self.get_object()
         if submission.state == SubmissionStates.ACCEPTED:
             submission.confirm(person=request.user)


Test patch:
diff --git a/src/tests/functional/cfp/test_submission_accept.py b/src/tests/functional/cfp/test_submission_accept.py
new file mode 100644
--- /dev/null
+++ b/src/tests/functional/cfp/test_submission_accept.py
@@ -0,0 +1,53 @@
+import pytest
+
+from pretalx.submission.models import SubmissionStates
+
+
+@pytest.mark.django_db
+def test_submission_accept(speaker_client, submission):
+    submission.state = SubmissionStates.ACCEPTED
+    submission.save()
+
+    response = speaker_client.post(submission.urls.confirm, follow=True)
+    submission.refresh_from_db()
+
+    assert response.status_code == 200
+    assert submission.state == SubmissionStates.CONFIRMED
+
+
+@pytest.mark.django_db
+def test_submission_accept_nologin(client, submission):
+    submission.state = SubmissionStates.ACCEPTED
+    submission.save()
+
+    response = client.post(submission.urls.confirm, follow=True)
+    submission.refresh_from_db()
+
+    assert response.status_code == 200
+    assert response.redirect_chain[-1][1] == 302
+    assert 'login?next=' in response.redirect_chain[-1][0]
+    assert submission.state == SubmissionStates.ACCEPTED
+
+
+@pytest.mark.django_db
+def test_submission_accept_wrong_code(client, submission):
+    submission.state = SubmissionStates.ACCEPTED
+    submission.save()
+
+    assert submission.code in submission.urls.confirm
+    response = client.post(submission.urls.confirm.replace(submission.code, "foo"), follow=True)
+
+    assert response.status_code == 200
+    assert response.redirect_chain[-1][1] == 302
+    assert 'login?next=' in response.redirect_chain[-1][0]
+
+
+@pytest.mark.django_db
+def test_submission_withdraw(speaker_client, submission):
+    submission.state = SubmissionStates.SUBMITTED
+    submission.save()
+
+    response = speaker_client.post(submission.urls.withdraw, follow=True)
+    assert response.status_code == 200
+    submission.refresh_from_db()
+    assert submission.state == SubmissionStates.WITHDRAWN