Skip to content
This repository has been archived by the owner on Jan 19, 2021. It is now read-only.

Commit

Permalink
Merge pull request #432 from glogiotatidis/query-set-magic
Browse files Browse the repository at this point in the history
Privacy controls
  • Loading branch information
Sancus committed Mar 15, 2013
2 parents 092ac44 + d1f975e commit 6a72b9c
Show file tree
Hide file tree
Showing 30 changed files with 897 additions and 396 deletions.
41 changes: 41 additions & 0 deletions apps/common/helpers.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import logging

from django.conf import settings
from django.template import Context
from django.template.loader import get_template
from django.utils.safestring import mark_safe

from jingo import register
from sorl.thumbnail import get_thumbnail

from apps.users.models import PUBLIC

logger = logging.getLogger('common.helpers')

Expand All @@ -22,3 +26,40 @@ def thumbnail(source, *args, **kwargs):
logger.error('Thumbnail had Exception: %s' % e)
source = getattr(settings, 'DEFAULT_IMAGE_SRC')
return get_thumbnail(source, *args, **kwargs)


@register.function
def field_with_attrs(bfield, **kwargs):
"""Allows templates to dynamically add html attributes to bound
fields from django forms.
Copied from bedrock.
"""
bfield.field.widget.attrs.update(kwargs)
return bfield


@register.function
def bootstrap(element):
"""Renders bootstrap forms in jinja2.
Takes an element that is either a field or an entire form and
renders the appropriate bootstrap elements.
"""
element_type = element.__class__.__name__.lower()
if element_type == 'boundfield':
template = get_template("bootstrapform/field.html")
context = Context({'field': element})
else:
template = get_template("bootstrapform/form.html")
context = Context({'form': element})

return mark_safe(template.render(context))


@register.function
def get_privacy_level(user):
"""Return privacy level user."""
if not user.is_authenticated():
return PUBLIC
return user.userprofile.level
4 changes: 4 additions & 0 deletions apps/common/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from elasticutils.contrib.django import get_es

from apps.users.cron import index_all_profiles
from apps.users.models import MOZILLIANS, UserProfile


class TestCase(test_utils.TestCase):
Expand Down Expand Up @@ -54,6 +55,9 @@ def setUp(self):
self.mozillian_client2.login(email=self.mozillian2.email)
self.pending_client = test.Client()
self.pending_client.login(email=self.pending.email)
self.data_privacy_fields = {}
for field in UserProfile._privacy_fields:
self.data_privacy_fields['privacy_%s' % field] = MOZILLIANS

@classmethod
def tearDownClass(cls):
Expand Down
2 changes: 1 addition & 1 deletion apps/groups/templates/groups/group.html
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ <h1 class="span12">{{ _('Group: {name}')|f(name=group.name) }}</h1>
<div class="span6 steward">
<h3>{{ _('Community Steward') }}</h3>
<div class="avatar">
<img class="profile-photo" src="{{ group.steward.photo_url() }}" alt="{{ _('Profile Photo') }}">
<img class="profile-photo" src="{{ group.steward.get_photo_url() }}" alt="{{ _('Profile Photo') }}">
</div>
<ul>
<li>
Expand Down
85 changes: 37 additions & 48 deletions apps/groups/tests/test_groups.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,9 @@ def test_default_groups(self):
'User should have no groups by default.')

def test_autocomplete_api(self):
self.client.login(email=self.mozillian.email)

r = self.client.get(reverse('group_search'), dict(term='daft'),
HTTP_X_REQUESTED_WITH='XMLHttpRequest')
r = self.mozillian_client.get(reverse('group_search'),
dict(term='daft'),
HTTP_X_REQUESTED_WITH='XMLHttpRequest')

eq_(r['Content-Type'], 'application/json', 'api uses json header')
assert not 'daft_punk' in json.loads(r.content)
Expand All @@ -53,8 +52,9 @@ def test_autocomplete_api(self):
profile.groups.add(robots)

assign_autocomplete_to_groups()
r = self.client.get(reverse('group_search'), dict(term='daft'),
HTTP_X_REQUESTED_WITH='XMLHttpRequest')
r = self.mozillian_client.get(reverse('group_search'),
dict(term='daft'),
HTTP_X_REQUESTED_WITH='XMLHttpRequest')

assert 'daft_punk' in json.loads(r.content)

Expand All @@ -75,12 +75,9 @@ def test_groups_are_case_insensitive(self):
"""Ensure groups are case insensitive."""
profile = self.mozillian.get_profile()

self.client.login(email=self.mozillian.email)

self.client.post(reverse('profile.edit'),
dict(full_name='tofumatt', groups='Awesome,foo,Bar'),
follow=True)

data = self.data_privacy_fields.copy()
data.update(dict(full_name='tofumatt', groups='Awesome,foo,Bar'))
self.mozillian_client.post(reverse('profile.edit'), data, follow=True)
eq_(3, profile.groups.count(), 'Three groups should be saved.')

group_string = stringify_groups(profile.groups.all())
Expand All @@ -92,8 +89,9 @@ def test_groups_are_case_insensitive(self):
'Uppercase group should be transformed to lowercase.')

# Make an AJAX request for a group using a capital letter.
r = self.client.get(reverse('group_search'), dict(term='Awesome'),
HTTP_X_REQUESTED_WITH='XMLHttpRequest')
r = self.mozillian_client.get(reverse('group_search'),
dict(term='Awesome'),
HTTP_X_REQUESTED_WITH='XMLHttpRequest')
for g in json.loads(r.content):
assert g.name == g.name.lower(), (
'Group search is case-insensitive.')
Expand All @@ -103,11 +101,9 @@ def test_pending_user_can_add_groups(self):
profile = self.pending.get_profile()
assert not profile.groups.all(), 'User should have no groups.'

self.client.login(email=self.pending.email)
self.client.post(reverse('profile.edit'),
dict(full_name='McAwesomepants',
groups='Awesome foo Bar'),
follow=True)
data = self.data_privacy_fields.copy()
data.update(dict(full_name='McAwesomepants', groups='Awesome foo Bar'))
self.pending_client.post(reverse('profile.edit'), data, follow=True)

assert profile.groups.all(), (
"Pending user should be able to edit groups.")
Expand All @@ -122,13 +118,10 @@ def test_string_split_works_properly(self):
assert not profile.groups.all(), (
'User has no groups at beginning of test.')

self.client.login(email=self.pending.email)
self.client.post(reverse('profile.edit'),
dict(
full_name='McAwesomepants',
# This should result in four groups
groups='Awesome,,foo bar, Bar,g '),
follow=True)
data = self.data_privacy_fields
data.update(dict(full_name='McAwesomepants',
groups='Awesome,,foo bar, Bar,g '))
self.pending_client.post(reverse('profile.edit'), data, follow=True)

eq_(4, profile.groups.count(), 'User should have four groups.')
assert profile.groups.get(name='foo bar'), (
Expand All @@ -142,13 +135,11 @@ def test_string_split_works_properly(self):
def test_users_cant_add_system_groups(self):
"""Make sure users can't add system groups to their profile."""
profile = self.mozillian.get_profile()

self.client.login(email=self.mozillian.email)
self.client.post(reverse('profile.edit'),
dict(full_name='tofumatt',
groups='%s %s' % (self.NORMAL_GROUP.name,
self.SYSTEM_GROUP.name)),
follow=True)
data = self.data_privacy_fields.copy()
data.update(dict(full_name='tofumatt',
groups='%s %s' % (self.NORMAL_GROUP.name,
self.SYSTEM_GROUP.name)))
self.mozillian_client.post(reverse('profile.edit'), data, follow=True)

groups = profile.groups.all()

Expand All @@ -172,12 +163,11 @@ def test_users_cant_remove_system_groups(self):
eq_(2, profile.groups.count(), 'User should have both groups.')

# Edit this user's profile and remove a group.
self.client.logout()
self.client.login(email=self.mozillian.email)
response = self.client.post(
reverse('profile.edit'),
dict(full_name="McLovin'", username='fo', groups=''),
follow=True)
self.mozillian_client.login(email=self.mozillian.email)
data = self.data_privacy_fields.copy()
data.update(dict(full_name="McLovin'", username='fo', groups=''))
response = self.mozillian_client.post(
reverse('profile.edit'), data, follow=True)

doc = pq(response.content)
assert not doc('#id_groups').attr('value'), (
Expand All @@ -198,8 +188,7 @@ def test_toggle_membership_on_group_page(self):
"""
profile = self.mozillian.get_profile()

self.client.login(email=self.mozillian.email)
response = self.client.get(reverse('group',
response = self.mozillian_client.get(reverse('group',
args=[self.NORMAL_GROUP.url]))
doc = pq(response.content)

Expand All @@ -210,7 +199,8 @@ def test_toggle_membership_on_group_page(self):
'"Join Group" button should be present in the response.')

# Follow the toggle membership form action.
r = self.client.post(doc('#toggle-group').attr('action'), follow=True)
r = self.mozillian_client.post(doc('#toggle-group').attr('action'),
follow=True)
doc = pq(r.content)

assert "Leave Group" in r.content, (
Expand All @@ -220,16 +210,16 @@ def test_toggle_membership_on_group_page(self):
self.NORMAL_GROUP.name)

# Do it again and they should leave the group.
r = self.client.post(doc('#toggle-group').attr('action'), {},
r = self.mozillian_client.post(doc('#toggle-group').attr('action'), {},
xsfollow=True)
assert not profile.groups.filter(id=self.NORMAL_GROUP.id), (
'User should not be in the "%s" group' %
self.NORMAL_GROUP.name)

# Test against a system group, where we shouldn't be able to toggle
# membership.
response = self.client.get(reverse('group',
args=[self.SYSTEM_GROUP.url]))
response = self.mozillian_client.get(
reverse('group', args=[self.SYSTEM_GROUP.url]))
doc = pq(response.content)

assert not profile.groups.filter(id=self.SYSTEM_GROUP.id), (
Expand All @@ -239,9 +229,8 @@ def test_toggle_membership_on_group_page(self):
'"Join Group" button should not be present in the response.')

# Attempt to manually toggle the group membership
r = self.client.post(reverse('group_toggle',
args=[self.SYSTEM_GROUP.url]),
follow=True)
r = self.mozillian_client.post(
reverse('group_toggle', args=[self.SYSTEM_GROUP.url]), follow=True)
assert not profile.groups.filter(id=self.SYSTEM_GROUP.id), (
'User should not be in the "%s" group' %
self.SYSTEM_GROUP.name)
Expand Down
21 changes: 9 additions & 12 deletions apps/groups/tests/test_languages.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,9 @@
class LanguagesTest(common.tests.ESTestCase):

def test_autocomplete_api(self):
self.client.login(email=self.mozillian.email)

r = self.client.get(reverse('language_search'), dict(term='daft'),
HTTP_X_REQUESTED_WITH='XMLHttpRequest')
r = self.mozillian_client.get(reverse('language_search'),
dict(term='daft'),
HTTP_X_REQUESTED_WITH='XMLHttpRequest')

eq_(r['Content-Type'], 'application/json', 'api uses json header')
assert not 'daft_punk' in json.loads(r.content)
Expand All @@ -33,21 +32,19 @@ def test_autocomplete_api(self):
profile.languages.add(robots)

assign_autocomplete_to_groups()
r = self.client.get(reverse('language_search'), dict(term='frenchie'),
HTTP_X_REQUESTED_WITH='XMLHttpRequest')
r = self.mozillian_client.get(reverse('language_search'),
dict(term='frenchie'),
HTTP_X_REQUESTED_WITH='XMLHttpRequest')

assert 'frenchie' in json.loads(r.content)

def test_pending_user_can_add_languages(self):
"""Ensure pending users can add/edit languages."""
profile = self.pending.get_profile()
assert not profile.languages.all(), 'User should have no languages.'

self.client.login(email=self.pending.email)
self.client.post(reverse('profile.edit'),
dict(full_name='McAwesomepants',
languages='frenchie'),
follow=True)
data = self.data_privacy_fields.copy()
data.update(dict(full_name='McAwesomepants', languages='frenchie'))
self.pending_client.post(reverse('profile.edit'), data, follow=True)

assert profile.languages.all(), (
"Pending user should be able to edit languages.")
20 changes: 9 additions & 11 deletions apps/groups/tests/test_skills.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,9 @@
class SkillsTest(common.tests.ESTestCase):

def test_autocomplete_api(self):
self.client.login(email=self.mozillian.email)

r = self.client.get(reverse('skill_search'), dict(term='daft'),
HTTP_X_REQUESTED_WITH='XMLHttpRequest')
r = self.mozillian_client.get(reverse('skill_search'),
dict(term='daft'),
HTTP_X_REQUESTED_WITH='XMLHttpRequest')

eq_(r['Content-Type'], 'application/json', 'api uses json header')
assert not 'daft_punk' in json.loads(r.content)
Expand All @@ -33,8 +32,9 @@ def test_autocomplete_api(self):
profile.skills.add(robots)

assign_autocomplete_to_groups()
r = self.client.get(reverse('skill_search'), dict(term='true'),
HTTP_X_REQUESTED_WITH='XMLHttpRequest')
r = self.mozillian_client.get(reverse('skill_search'),
dict(term='true'),
HTTP_X_REQUESTED_WITH='XMLHttpRequest')

assert 'true love' in json.loads(r.content)

Expand All @@ -43,11 +43,9 @@ def test_pending_user_can_add_skills(self):
profile = self.pending.get_profile()
assert not profile.skills.all(), 'User should have no skills.'

self.client.login(email=self.pending.email)
self.client.post(reverse('profile.edit'),
dict(full_name='McAwesomepants',
skills='Awesome foo Bar'),
follow=True)
data = self.data_privacy_fields.copy()
data.update(dict(full_name='McAwesomepants', skills='Awesome foo Bar'))
self.pending_client.post(reverse('profile.edit'), data, follow=True)

assert profile.skills.all(), (
"Pending user should be able to edit skills.")
1 change: 0 additions & 1 deletion apps/groups/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
from apps.groups.models import Group, Skill
from apps.phonebook import forms
from apps.phonebook.views import vouch_required
from apps.users.models import UserProfile
from apps.users.tasks import update_basket_task

log = commonware.log.getLogger('m.groups')
Expand Down
11 changes: 7 additions & 4 deletions apps/phonebook/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
class SearchForm(happyforms.Form):
q = forms.CharField(widget=forms.HiddenInput, required=False)
limit = forms.CharField(widget=forms.HiddenInput, required=False)
include_non_vouched = forms.BooleanField(label=_lazy(u'Include non-vouched'),
required=False)
include_non_vouched = forms.BooleanField(
label=_lazy(u'Include non-vouched'), required=False)

def clean_limit(self):
"""Validate that this limit is numeric and greater than 1."""
Expand Down Expand Up @@ -101,8 +101,11 @@ class Meta:
model = UserProfile
fields = ('full_name', 'ircname', 'website', 'bio', 'photo', 'country',
'region', 'city', 'allows_community_sites',
'allows_mozilla_sites')
exclude = ('display_name', )
'allows_mozilla_sites', 'privacy_photo', 'privacy_full_name',
'privacy_ircname', 'privacy_email', 'privacy_website',
'privacy_bio', 'privacy_city', 'privacy_region',
'privacy_country', 'privacy_groups', 'privacy_skills',
'privacy_languages')
widgets = {'bio': forms.Textarea()}

def __init__(self, *args, **kwargs):
Expand Down
Loading

0 comments on commit 6a72b9c

Please sign in to comment.