-
Notifications
You must be signed in to change notification settings - Fork 51
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Password protect partnered events #407
Closed
Closed
Changes from 3 commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
f14ef31
402 - implemented partner class password protection
ash6851 35309e2
402 - added tests for partner class password access, turned off debug…
ash6851 5511a2f
402 - refactored code to variable
ash6851 dbc2d50
Merge branch 'develop' into feature/password-protect
ash6851 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import factory | ||
from datetime import datetime | ||
from pytz import utc | ||
|
||
from models import Session | ||
from models import Course | ||
from models import Location | ||
from models import Mentor | ||
from models import CDCUser | ||
from models import PartnerPasswordAccess | ||
|
||
|
||
class CourseFactory(factory.DjangoModelFactory): | ||
title = factory.Sequence(lambda n: 'Test Course {}'.format(n)) | ||
slug = factory.Sequence(lambda n: 'test-course-{}'.format(n)) | ||
|
||
class Meta: | ||
model = Course | ||
|
||
|
||
class LocationFactory(factory.DjangoModelFactory): | ||
name = factory.Sequence(lambda n: 'Test Location {}'.format(n)) | ||
address = factory.Sequence(lambda n: '{} Street'.format(n)) | ||
city = 'Chicago' | ||
state = 'IL' | ||
zip = '60605' | ||
|
||
class Meta: | ||
model = Location | ||
|
||
|
||
class CDCUserFactory(factory.DjangoModelFactory): | ||
username = factory.Sequence(lambda n: 'username_{}'.format(n)) | ||
|
||
class Meta: | ||
model = CDCUser | ||
|
||
|
||
class MentorFactory(factory.DjangoModelFactory): | ||
user = factory.SubFactory(CDCUserFactory) | ||
active = True | ||
|
||
class Meta: | ||
model = Mentor | ||
|
||
|
||
class SessionFactory(factory.DjangoModelFactory): | ||
course = factory.SubFactory(CourseFactory) | ||
location = factory.SubFactory(LocationFactory) | ||
start_date = datetime.now(utc) | ||
end_date = datetime.now(utc) | ||
mentor_start_date = datetime.now(utc) | ||
mentor_end_date = datetime.now(utc) | ||
password = '' | ||
teacher = factory.SubFactory(MentorFactory) | ||
|
||
class Meta: | ||
model = Session | ||
|
||
|
||
class PartnerPasswordAccessFactory(factory.DjangoModelFactory): | ||
user = factory.SubFactory(CDCUserFactory) | ||
session = factory.SubFactory(SessionFactory) | ||
|
||
class Meta: | ||
model = PartnerPasswordAccess |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# -*- coding: utf-8 -*- | ||
# Generated by Django 1.9.6 on 2016-09-20 17:46 | ||
from __future__ import unicode_literals | ||
|
||
from django.db import migrations, models | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
('coderdojochi', '0006_session_gender_limitation'), | ||
] | ||
|
||
operations = [ | ||
migrations.AddField( | ||
model_name='session', | ||
name='partner_message', | ||
field=models.TextField(blank=True), | ||
), | ||
migrations.AddField( | ||
model_name='session', | ||
name='password', | ||
field=models.CharField(blank=True, max_length=255), | ||
), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
# -*- coding: utf-8 -*- | ||
# Generated by Django 1.9.6 on 2016-09-20 17:56 | ||
from __future__ import unicode_literals | ||
|
||
from django.conf import settings | ||
from django.db import migrations, models | ||
import django.db.models.deletion | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
('coderdojochi', '0007_partner_session'), | ||
] | ||
|
||
operations = [ | ||
migrations.CreateModel( | ||
name='PartnerPasswordAccess', | ||
fields=[ | ||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||
('created_at', models.DateTimeField(auto_now_add=True)), | ||
('session', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='coderdojochi.Session')), | ||
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), | ||
], | ||
options={ | ||
'db_table': 'partner_password_access', | ||
'verbose_name': 'partner_password_access', | ||
}, | ||
), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
{% extends "_base.html" %} | ||
|
||
{% load i18n coderdojochi_extras %} | ||
|
||
{% block title %}Upcoming Classes{% endblock %} | ||
|
||
{% block extra_meta %} | ||
<meta property="og:url" content="{{ session.get_absolute_url }}"> | ||
<meta property="og:title" content="Check out our upcoming classes!"> | ||
{% endblock %} | ||
|
||
{% block body_class %}page-classes{% endblock %} | ||
|
||
{% block content %} | ||
<div class="container"> | ||
<div id="errors"> | ||
<p>Error: {{ error }}</p> | ||
</div> | ||
<form method="post" action="."> | ||
{% csrf_token %} | ||
<label for="id-password">Password:</label> | ||
<input id="id-password" name="password" type="text"/> | ||
<button class="btn-cdc btn-cdc-sm">Submit</button> | ||
</form> | ||
</div> | ||
{% endblock %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
import mock | ||
import sys | ||
|
||
from django.test import TestCase | ||
from django.test import Client | ||
from django.test import RequestFactory | ||
from django.core.urlresolvers import reverse | ||
from django.contrib.auth import get_user_model | ||
from django.http import HttpResponseRedirect | ||
|
||
from coderdojochi.models import PartnerPasswordAccess | ||
from coderdojochi.factories import SessionFactory | ||
from coderdojochi.factories import PartnerPasswordAccessFactory | ||
from coderdojochi.factories import CDCUserFactory | ||
from coderdojochi.views import session_detail | ||
|
||
|
||
User = get_user_model() | ||
|
||
|
||
class TestPartnerSessionPassword(TestCase): | ||
def setUp(self): | ||
self.partner_session = SessionFactory.create(password='124') | ||
self.url_kwargs = { | ||
'year': self.partner_session.start_date.year, | ||
'month': self.partner_session.start_date.month, | ||
'day': self.partner_session.start_date.day, | ||
'slug': self.partner_session.course.slug, | ||
'session_id': self.partner_session.id | ||
} | ||
self.client = Client() | ||
self.url = reverse('session_password', kwargs=self.url_kwargs) | ||
|
||
def test_session_password_invalid_password(self): | ||
response = self.client.post(self.url, data={'password': 'abc'}) | ||
self.assertContains(response, 'Invalid password.') | ||
|
||
def test_session_password_no_password(self): | ||
response = self.client.post(self.url, data={'password': ''}) | ||
self.assertContains(response, 'Must enter a password.') | ||
|
||
def test_session_password_valid_password_unauthed(self): | ||
response = self.client.post(self.url, data={'password': self.partner_session.password}) | ||
self.assertIsInstance(response, HttpResponseRedirect) | ||
|
||
detail_url = reverse('session_detail', kwargs=self.url_kwargs) | ||
self.assertEqual(response.url, detail_url) | ||
password_access_count = PartnerPasswordAccess.objects.count() | ||
self.assertEqual(password_access_count, 0) | ||
authed_sessions = self.client.session['authed_partner_sessions'] | ||
self.assertFalse(str(self.partner_session.id) in authed_sessions) | ||
|
||
def test_session_password_valid_password_authed(self): | ||
user = User.objects.create_user('user', email='email@email.com', password='pass123') | ||
self.assertTrue(self.client.login(email='email@email.com', password='pass123')) | ||
response = self.client.post(self.url, data={'password': self.partner_session.password}) | ||
self.assertIsInstance(response, HttpResponseRedirect) | ||
|
||
detail_url = reverse('session_detail', kwargs=self.url_kwargs) | ||
self.assertEqual(response.url, detail_url) | ||
partner_password_access = PartnerPasswordAccess.objects.get(session=self.partner_session, | ||
user=user) | ||
self.assertIsNotNone(partner_password_access) | ||
|
||
authed_sessions = self.client.session['authed_partner_sessions'] | ||
self.assertTrue(str(self.partner_session.id) in authed_sessions) | ||
|
||
|
||
class TestSessionDetail(TestCase): | ||
def setUp(self): | ||
super(TestSessionDetail, self).setUp() | ||
self.client = Client() | ||
self.partner_session = SessionFactory.create(password='124') | ||
self.url_kwargs = { | ||
'year': self.partner_session.start_date.year, | ||
'month': self.partner_session.start_date.month, | ||
'day': self.partner_session.start_date.day, | ||
'slug': self.partner_session.course.slug, | ||
'session_id': self.partner_session.id | ||
} | ||
self.url = reverse('session_detail', kwargs=self.url_kwargs) | ||
|
||
def test_redirect_password_unauthed(self): | ||
response = self.client.get(self.url) | ||
self.assertIsInstance(response, HttpResponseRedirect) | ||
|
||
detail_url = reverse('session_password', kwargs=self.url_kwargs) | ||
self.assertEqual(response.url, detail_url) | ||
|
||
def test_redirect_password_authed(self): | ||
User.objects.create_user('user', email='email@email.com', password='pass123') | ||
self.assertTrue(self.client.login(email='email@email.com', password='pass123')) | ||
response = self.client.get(self.url) | ||
self.assertIsInstance(response, HttpResponseRedirect) | ||
|
||
detail_url = reverse('session_password', kwargs=self.url_kwargs) | ||
self.assertEqual(response.url, detail_url) | ||
|
||
def test_redirect_password_partner_password_access(self): | ||
user = User.objects.create_user('user', email='email@email.com', password='pass123') | ||
self.assertTrue(self.client.login(email='email@email.com', password='pass123')) | ||
PartnerPasswordAccessFactory.create(user=user, session=self.partner_session) | ||
response = self.client.get(self.url) | ||
detail_url = reverse('session_password', kwargs=self.url_kwargs) | ||
# don't care what its doing as long as its not redirecting to the password url. | ||
self.assertNotEqual(response.url, detail_url) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ash6851 Can you explain what this addition does?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@karbassi when I was writing tests I was trying to check response url, but the redirect was being intercepted by the redirect debug page and my response url was wrong. Let me know if you need more explanation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ash6851 ah, yes. This needs to be set to default to false. I'll commit a fix ASAP.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ash6851 Merge in #409