Repository: DjangoGirls/djangogirls

Issue:
Organizers can see other workshops' pages that aren't live when logged in
How I noticed this:
- I was logged in as Django Girls Santa Maria organizer.
- I typed "djangogirls.org/brasilia" in the browser, which is an event that I know it will happen in four months
- It returned the template page for Brasilia, with the message "Hi there! You can see this page because you're logged in admin. When you want to make it public, go to your website section in the admin and click on 'Is live'."

This probably shouldn't happen. No "live" pages should be shown; only the event's own organizers and Django Girls staff/admin should be able to see them.


Discussion:
Can i work on this issue :)

Resolving patch:
diff --git a/core/models.py b/core/models.py
--- a/core/models.py
+++ b/core/models.py
@@ -205,6 +205,13 @@ def organizers(self):
                    for x in self.team.all()]
         return ", ".join(members)
 
+    def has_organizer(self, user):
+        """
+        Return whether a specific user is an organizer of the event
+        """
+        return self.main_organizer == user or self.team.filter(
+            id=user.id).exists()
+
     @property
     def has_stats(self):
         return bool(self.applicants_count and self.attendees_count)
diff --git a/core/views.py b/core/views.py
--- a/core/views.py
+++ b/core/views.py
@@ -55,8 +55,12 @@ def event(request, city):
     if event.page_url != city:
         return redirect('core:event', city=event.page_url, permanent=True)
 
-    can_show = request.user.is_authenticated() or 'preview' in request.GET
-    if not event.is_page_live and not can_show:
+    user = request.user
+    user_is_organizer = user.is_authenticated() and event.has_organizer(user)
+    is_preview = 'preview' in request.GET
+    previewable = user.is_superuser or user_is_organizer or is_preview
+
+    if not (event.is_page_live or previewable):
         return render(
             request,
             'applications/event_not_live.html',
@@ -152,4 +156,4 @@ def crowdfunding_donors(request):
     return render(request, 'core/crowdfunding_donors.html', {
         'donor_list': donor_list,
         'quotes': DONOR_QUOTES,
-    })
\ No newline at end of file
+    })


Test patch:
diff --git a/tests/core/test_models.py b/tests/core/test_models.py
--- a/tests/core/test_models.py
+++ b/tests/core/test_models.py
@@ -82,3 +82,24 @@ def test_add_to_organizers_group(user):
     Group.objects.create(name="Organizers")
     user.add_to_organizers_group()
     assert user.groups.count() == 1
+
+
+def test_has_organizer_no_organizer(user, future_event):
+    future_event.main_organizer = None
+    future_event.team.clear()
+
+    assert not future_event.has_organizer(user)
+
+
+def test_has_organizer_in_team(user, future_event):
+    future_event.main_organizer = None
+    future_event.team.add(user)
+
+    assert future_event.has_organizer(user)
+
+
+def test_has_organizer_main_organizer(user, future_event):
+    future_event.main_organizer = user
+    future_event.team.clear()
+
+    assert future_event.has_organizer(user)
diff --git a/tests/core/test_views.py b/tests/core/test_views.py
--- a/tests/core/test_views.py
+++ b/tests/core/test_views.py
@@ -78,15 +78,64 @@ def test_event_unpublished_with_future_and_past_dates(client, no_date_event):
     assert 'has already happened' in str(resp.content)
 
 
-def test_event_unpublished_with_authenticated_user(admin_client, hidden_event):
+def test_event_unpublished_with_auth_normal(user, client, hidden_event):
+    """ Test that an unpublished page can not be accessed when the user is
+    authenticated and not a superuser"""
+
+    client.force_login(user)
+    url = '/' + hidden_event.page_url + '/'
+    resp = client.get(url)
+
+    assert resp.status_code == 200
+    assert 'city' and 'past' in resp.context
+
+
+def test_event_unpublished_with_auth_superuser(admin_client, hidden_event):
     """ Test that an unpublished page can be accessed when the user is
-    authenticated """
+    authenticated and a superuser"""
 
     url = '/' + hidden_event.page_url + '/'
     resp = admin_client.get(url)
 
     assert resp.status_code == 200
-    # Check if website is returning correct data
+    assert hidden_event.page_title in resp.content.decode('utf-8')
+
+
+def test_event_unpublished_with_auth_not_organizer(user, client, hidden_event):
+    """ Test that an unpublished page can not be accessed if the user
+    is not an organizer"""
+
+    client.force_login(user)
+    url = '/' + hidden_event.page_url + '/'
+    resp = client.get(url)
+
+    assert resp.status_code == 200
+    assert 'city' and 'past' in resp.context
+
+
+def test_event_unpublished_with_auth_in_team(user, client, hidden_event):
+    """ Test that an unpublished page can be accessed if the user
+    is an organizer"""
+    hidden_event.team.add(user)
+
+    client.force_login(user)
+    url = '/' + hidden_event.page_url + '/'
+    resp = client.get(url)
+
+    assert resp.status_code == 200
+    assert hidden_event.page_title in resp.content.decode('utf-8')
+
+
+def test_event_unpublished_with_auth_organizer(user, client, hidden_event):
+    """ Test that an unpublished page can be accessed if the user
+    is the main organizer"""
+    hidden_event.main_organizer = user
+
+    client.force_login(user)
+    url = '/' + hidden_event.page_url + '/'
+    resp = client.get(url)
+
+    assert resp.status_code == 200
     assert hidden_event.page_title in resp.content.decode('utf-8')