Skip to content
This repository has been archived by the owner on Jul 25, 2018. It is now read-only.

Commit

Permalink
Fix admin patch and add show website permission.
Browse files Browse the repository at this point in the history
Switches from using the funfactory admin object specifically
to patching the django.contrib.admin.site object with it
so that permissions and other default admin pages show up
properly.

Adds a new permission that controls who can display
a website link in their place on the leaderboard.

bug 760631
  • Loading branch information
Michael Kelly committed Oct 12, 2012
1 parent f8996e7 commit 104f193
Show file tree
Hide file tree
Showing 8 changed files with 142 additions and 30 deletions.
8 changes: 3 additions & 5 deletions apps/badges/admin.py
Expand Up @@ -2,21 +2,19 @@

from django.contrib import admin

from funfactory.admin import site

from badges.models import BadgePreview, Category, ClickStats, Subcategory
from shared.admin import BaseModelAdmin
from stats.options import ModelStats


class CategoryAdmin(BaseModelAdmin):
change_list_template = 'smuggler/change_list.html'
site.register(Category, CategoryAdmin)
admin.site.register(Category, CategoryAdmin)


class SubcategoryAdmin(BaseModelAdmin):
change_list_template = 'smuggler/change_list.html'
site.register(Subcategory, SubcategoryAdmin)
admin.site.register(Subcategory, SubcategoryAdmin)


class BadgePreviewInline(admin.TabularInline):
Expand All @@ -36,4 +34,4 @@ class ClickStatsDisplay(ModelStats):

def default_start(self):
return datetime.now() - timedelta(days=100)
site.register_stats(ClickStats, ClickStatsDisplay)
admin.site.register_stats(ClickStats, ClickStatsDisplay)
3 changes: 2 additions & 1 deletion apps/badges/templates/badges/include/leaderboard.html
Expand Up @@ -33,7 +33,8 @@ <h4>
<li>
<span class="download-number">{{ standing.ranking|babel_number }}</span>
<span class="display-name">
{% if standing.user.userprofile.website is not none %}
{% if standing.user.userprofile.website is not none
and standing.user.has_perm('users.can_share_website') %}
<a href="{{ standing.user.userprofile.website }}">
{{ display_name(standing.user) }}
</a>
Expand Down
11 changes: 4 additions & 7 deletions apps/banners/admin.py
@@ -1,7 +1,5 @@
from django.contrib import admin

from funfactory.admin import site

from badges.admin import BadgePreviewInline
from badges.models import ClickStats
from banners.models import Banner, BannerImage, BannerInstance
Expand All @@ -24,7 +22,7 @@ def changelist_view(self, request, extra_context={}):
return super(BannerAdmin, self).changelist_view(request,
extra_context=extra_context)

site.register(Banner, BannerAdmin)
admin.site.register(Banner, BannerAdmin)


class BannerImageAdmin(BaseModelAdmin):
Expand All @@ -33,7 +31,7 @@ class BannerImageAdmin(BaseModelAdmin):
list_editable = ('color', 'image')
list_filter = ('banner', 'color', 'locale')
formfield_overrides = {}
site.register(BannerImage, BannerImageAdmin)
admin.site.register(BannerImage, BannerImageAdmin)


class BannerInstanceAdmin(BaseModelAdmin):
Expand All @@ -44,12 +42,11 @@ class BannerInstanceAdmin(BaseModelAdmin):

def user_display_name(self, instance):
return instance.user.userprofile.display_name

site.register(BannerInstance, BannerInstanceAdmin)
admin.site.register(BannerInstance, BannerInstanceAdmin)


class BannerInstanceStats(ModelStats):
display_name = 'BannerInstances created'
datetime_field = 'created'
filters = ['badge', 'image__locale']
site.register_stats(BannerInstance, BannerInstanceStats)
admin.site.register_stats(BannerInstance, BannerInstanceStats)
4 changes: 2 additions & 2 deletions apps/news/admin.py
@@ -1,4 +1,4 @@
from funfactory.admin import site
from django.contrib import admin

from news.models import NewsItem
from shared.admin import BaseModelAdmin
Expand All @@ -7,4 +7,4 @@
class NewsItemAdmin(BaseModelAdmin):
list_display = ('title', 'enabled', 'created', 'modified')
list_editable = ('enabled',)
site.register(NewsItem, NewsItemAdmin)
admin.site.register(NewsItem, NewsItemAdmin)
14 changes: 5 additions & 9 deletions apps/users/admin.py
@@ -1,8 +1,7 @@
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin as DjangoUserAdmin
from django.contrib.auth.models import User

from funfactory.admin import site

from users.models import UserProfile
from shared.admin import BaseModelAdmin

Expand All @@ -12,23 +11,20 @@ class UserProfileInline(admin.StackedInline):
max_num = 1
can_delete = False
fieldsets = (
(None, {'fields': ('display_name',)}),
(None, {'fields': ('display_name', 'website')}),
('Address', {'fields': ('name', 'address_1', 'address_2', 'city',
'state', 'postal_code', 'country')}),
)


class UserAdmin(BaseModelAdmin):
class UserAdmin(BaseModelAdmin, DjangoUserAdmin):
list_display = ('user_displayname', 'email', 'is_active', 'last_login',
'date_joined')
list_filter = ('is_active',)
fieldsets = (
(None, {'fields': ('email', 'is_active')}),
)
inlines = [UserProfileInline]
search_fields = ('userprofile__display_name', 'email')

def user_displayname(self, instance):
return instance.userprofile.display_name

site.register(User, UserAdmin)
admin.site.unregister(User)
admin.site.register(User, UserAdmin)
101 changes: 101 additions & 0 deletions apps/users/migrations/0003_add_cannot_share_website_permission.py
@@ -0,0 +1,101 @@
# encoding: utf-8
from django.contrib.contenttypes.models import ContentType

from south.v2 import DataMigration


class Migration(DataMigration):

def forwards(self, orm):
"""Add permission."""
# south doesn't freeze model attributes, so we need to use the real
# model class to get the ContentType we need.
content_type = ContentType.objects.get_for_model(orm.UserProfile)

# Furthermore, south doesn't like using non-frozen model objects when
# creating things, so we need a frozen version of the content type.
content_type = orm['contenttypes.ContentType'].objects.get(id=content_type.id)

can_share_website = orm['auth.Permission'].objects.create(
content_type=content_type, codename='can_share_website',
name="Can share website link on leaderboard")

# Add the permission to every existing user by default.
for user in orm['auth.User'].objects.all():
user.user_permissions.add(can_share_website)
user.save()

def backwards(self, orm):
"""Remove permission."""
orm['auth.Permission'].objects.get(codename='cannot_share_website').delete()

models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.message': {
'Meta': {'object_name': 'Message'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'message': ('django.db.models.fields.TextField', [], {}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'_message_set'", 'to': "orm['auth.User']"})
},
'auth.permission': {
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'auth.user': {
'Meta': {'object_name': 'User'},
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'users.registerprofile': {
'Meta': {'object_name': 'RegisterProfile'},
'activation_key': ('django.db.models.fields.CharField', [], {'max_length': '40'}),
'display_name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'email': ('django.db.models.fields.EmailField', [], {'unique': 'True', 'max_length': '75'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True', 'null': 'True'})
},
'users.userprofile': {
'Meta': {'object_name': 'UserProfile'},
'address_1': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
'address_2': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
'city': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
'country': ('django.db.models.fields.CharField', [], {'max_length': '2', 'blank': 'True'}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'display_name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'postal_code': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}),
'state': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True', 'primary_key': 'True'}),
'website': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True'})
}
}

complete_apps = ['contenttypes', 'auth', 'users']
22 changes: 19 additions & 3 deletions apps/users/models.py
Expand Up @@ -4,10 +4,11 @@
import re

from django.conf import settings
from django.contrib.auth.models import User
from django.contrib.auth.models import Permission, User
from django.contrib.sites.models import Site
from django.core import mail
from django.db import models
from django.dispatch import receiver
from django.template.loader import render_to_string

from funfactory.urlresolvers import reverse
Expand Down Expand Up @@ -48,6 +49,16 @@ def get_linked_account(self):
User.add_to_class('get_linked_account', get_linked_account)


@receiver(models.signals.post_save, sender=User)
def add_default_permissions(sender, **kwargs):
"""Add default set of permissions to users when they are first created."""
if kwargs['created']:
user = kwargs['instance']
can_share_website = Permission.objects.get(codename='can_share_website')
user.user_permissions.add(can_share_website)
user.save()


class UserProfile(ModelBase):
"""
Stores information about a user account. Created post-activation.
Expand All @@ -68,9 +79,9 @@ class UserProfile(ModelBase):
address_2 = models.CharField(max_length=255, blank=True, null=True,
verbose_name=_lazy(u'Address Line 2'))
city = models.CharField(max_length=255, blank=True, null=True,
verbose_name=_lazy(u'City'))
verbose_name=_lazy(u'City'))
state = models.CharField(max_length=255, blank=True, null=True,
verbose_name=_lazy(u'State or Province'))
verbose_name=_lazy(u'State or Province'))
postal_code = models.CharField(max_length=32, blank=True, null=True,
verbose_name=_lazy(u'Zip or Postal Code'))
country = models.CharField(max_length=2, choices=COUNTRIES, blank=True,
Expand All @@ -81,6 +92,11 @@ class UserProfile(ModelBase):
def __unicode__(self):
return unicode(self.display_name)

class Meta:
permissions = (
('can_share_website', 'Can share website link on leaderboard'),
)


class RegisterManager(models.Manager):
"""
Expand Down
9 changes: 6 additions & 3 deletions urls.py
Expand Up @@ -2,16 +2,19 @@

from django.conf import settings
from django.conf.urls.defaults import include, patterns
from django.contrib.admin import autodiscover
from django.contrib import admin

from funfactory import admin
from funfactory.admin import site as patched_site

from stats.monkeypatches import patch

# TODO: Remove once Affiliates is upgraded to the latest funfactory, as it
# patches this.
admin.site = patched_site # Patch with session_csrf fix

# Patch admin site for stats application
patch(admin.site)
autodiscover()
admin.autodiscover()

handler404 = 'shared.views.view_404'
handler500 = 'shared.views.view_500'
Expand Down

0 comments on commit 104f193

Please sign in to comment.