more basic auth
diff --git a/AppMgr/admin.py b/AppMgr/admin.py
index e7ad9fd..093b6bc 100644
--- a/AppMgr/admin.py
+++ b/AppMgr/admin.py
@@ -4,22 +4,20 @@
from django.forms import ModelChoiceField
-from custom_user.models import EmailUser
+from django.contrib.auth import get_user_model
from custom_user.admin import EmailUserAdmin as BaseUserAdmin
+from guardian.admin import GuardedModelAdmin
+
from AppMgr.models import UserProfile, Organization, Membership, Application, AppVersion
# Register your models here.
-class UserProfileInline(admin.StackedInline):
- model = UserProfile
- readonly_fields = ['id']
- fields = ['id']
+class UserAdmin(BaseUserAdmin, GuardedModelAdmin):
+ list_display = ['id', 'email', 'public_contact']
+# pass
-class UserAdmin(BaseUserAdmin):
- inlines = (UserProfileInline, )
-
-class OrganizationAdmin(admin.ModelAdmin):
+class OrganizationAdmin(GuardedModelAdmin):
search_fields = ['name']
list_display = ['id', 'name']
@@ -32,7 +30,7 @@
ct_field = 'content_type'
ct_fk_field = 'object_id'
-class ApplicationAdmin(admin.ModelAdmin):
+class ApplicationAdmin(GuardedModelAdmin):
inlines = [ApplicationInline]
search_fields = ['name']
@@ -41,8 +39,8 @@
search_fields = ['name', 'app']
list_display = ['id', 'name', 'app', 'domain', 'aliases',]
-admin.site.unregister(EmailUser)
-admin.site.register(EmailUser, UserAdmin)
+#admin.site.unregister(get_user_model())
+admin.site.register(get_user_model(), UserAdmin)
admin.site.register(Organization, OrganizationAdmin)
admin.site.register(Membership, MembershipAdmin)
diff --git a/AppMgr/migrations/0001_initial.py b/AppMgr/migrations/0001_initial.py
index 3e21a8d..001fa67 100644
--- a/AppMgr/migrations/0001_initial.py
+++ b/AppMgr/migrations/0001_initial.py
@@ -1,11 +1,12 @@
# -*- coding: utf-8 -*-
-# Generated by Django 1.9.7 on 2016-06-21 07:29
+# Generated by Django 1.9.7 on 2016-06-23 22:51
from __future__ import unicode_literals
from django.conf import settings
import django.contrib.postgres.fields.jsonb
from django.db import migrations, models
import django.db.models.deletion
+import django.utils.timezone
class Migration(migrations.Migration):
@@ -14,7 +15,7 @@
dependencies = [
('contenttypes', '0002_remove_content_type_name'),
- migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+ ('auth', '0007_alter_validators_add_error_messages'),
]
operations = [
@@ -28,7 +29,7 @@
('content_type', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType', verbose_name=b'application owner')),
],
options={
- 'permissions': (('admin', 'All application privileges'), ('edit', 'add/modify application attributes'), ('view', 'read access to the application')),
+ 'permissions': (('view_application', 'read access to the application'),),
},
),
migrations.CreateModel(
@@ -55,20 +56,32 @@
('name', models.CharField(max_length=255)),
],
options={
- 'permissions': (('admin', 'All organizational privileges'), ('change_apps', "Create/Modify/Delete Org's Applications"), ('change_members', 'Add/Remove Users')),
+ 'permissions': (('view_organization', 'view organization information'),),
},
),
migrations.CreateModel(
name='UserProfile',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
+ ('password', models.CharField(max_length=128, verbose_name='password')),
+ ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
+ ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
+ ('email', models.EmailField(db_index=True, max_length=255, unique=True, verbose_name='email address')),
+ ('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')),
+ ('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')),
+ ('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
+ ('public_contact', models.BooleanField(default=False)),
+ ('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups')),
+ ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions')),
],
+ options={
+ 'permissions': (('view_userprofile', 'view profile information'),),
+ },
),
migrations.AddField(
model_name='organization',
name='members',
- field=models.ManyToManyField(through='AppMgr.Membership', to='AppMgr.UserProfile'),
+ field=models.ManyToManyField(through='AppMgr.Membership', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='membership',
@@ -78,6 +91,6 @@
migrations.AddField(
model_name='membership',
name='user',
- field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='AppMgr.UserProfile'),
+ field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
),
]
diff --git a/AppMgr/models.py b/AppMgr/models.py
index 37715bc..c915013 100644
--- a/AppMgr/models.py
+++ b/AppMgr/models.py
@@ -5,12 +5,24 @@
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey
+from django.contrib.auth import get_user_model
+
+from custom_user.models import AbstractEmailUser
+
+from guardian.mixins import GuardianUserMixin
+
# Create your models here.
-class UserProfile(models.Model):
- user = models.OneToOneField(settings.AUTH_USER_MODEL)
+class UserProfile(AbstractEmailUser, GuardianUserMixin):
+
+ public_contact = models.BooleanField(default=False)
+
+ class Meta:
+ permissions = (
+ ("view_userprofile", "view profile information"),
+ )
def __unicode__(self):
- return self.user.email
+ return self.email
class Organization(models.Model):
name = models.CharField(max_length=255)
@@ -19,9 +31,7 @@
class Meta:
permissions = (
- ("admin", "All organizational privileges"),
- ("change_apps", "Create/Modify/Delete Org's Applications"),
- ("change_members", "Add/Remove Users"),
+ ("view_organization", "view organization information"),
)
def __unicode__(self):
@@ -57,9 +67,7 @@
class Meta:
permissions = (
- ("admin", "All application privileges"),
- ("edit", "add/modify application attributes"),
- ("view", "read access to the application"),
+ ("view_application", "read access to the application"),
)
def __unicode__(self):
diff --git a/AppMgr/serializers.py b/AppMgr/serializers.py
index fc669e4..bccab28 100644
--- a/AppMgr/serializers.py
+++ b/AppMgr/serializers.py
@@ -1,6 +1,6 @@
from rest_framework import serializers
-from custom_user.models import EmailUser
+from django.contrib.auth import get_user_model
from AppMgr.models import UserProfile, Organization, Membership, Application, AppVersion
@@ -11,18 +11,13 @@
model = Membership
fields = ('org', 'user', 'join_date')
-class UserSerializer(serializers.ModelSerializer):
- class Meta:
- model = EmailUser
- fields = ('id', 'email', 'date_joined',
- 'is_staff', 'is_active', )
-
class UserProfileSerializer(serializers.ModelSerializer):
memberships = MembershipSerializer(source='membership_set', many=True)
- user_details = UserSerializer(source='user', many=False)
class Meta:
model = UserProfile
- fields = ('id', 'user_details', 'memberships')
+ fields = ('id', 'email', 'date_joined',
+ 'is_staff', 'is_active', 'public_contact',
+ 'memberships')
class OrganizationSerializer(serializers.ModelSerializer):
memberships = MembershipSerializer(source='membership_set', many=True)
diff --git a/AppMgr/views.py b/AppMgr/views.py
index b273dc4..9bf3349 100644
--- a/AppMgr/views.py
+++ b/AppMgr/views.py
@@ -11,8 +11,15 @@
from django.db import IntegrityError
from axes.decorators import watch_login
-from rest_framework import generics
+from rest_framework import generics
+from rest_framework.authentication import BasicAuthentication
+from rest_framework.permissions import IsAuthenticated
+from rest_framework.response import Response
+
+from guardian.shortcuts import assign_perm
+
+from AppMgr.permissions import ViewControlObjectPermissions
from AppMgr.models import UserProfile, Organization, Application, AppVersion
from AppMgr.serializers import UserProfileSerializer, OrganizationSerializer, ApplicationSerializer
@@ -27,6 +34,9 @@
"""
Returns a list of all user profiles.
"""
+ authentication_classes = (BasicAuthentication,)
+ permission_classes = (IsAuthenticated,)
+
queryset = UserProfile.objects.all()
serializer_class = UserProfileSerializer
@@ -49,9 +59,22 @@
"""
Returns a single user.
"""
+ authentication_classes = (BasicAuthentication,)
+ #permission_classes = (IsAuthenticated,)
+ permission_classes = (ViewControlObjectPermissions,)
+ _ignore_model_permissions = True
+
queryset = UserProfile.objects.all()
serializer_class = UserProfileSerializer
+ #def retrieve(self, request):
+ # queryset = self.get_queryset()
+ # serializer = UserProfileSerializer
+ # print request.user.id
+ # print request.user.email
+ # print request.user.has_perms(view_userprofile)
+ # return Response(serializer.data)
+
class OrganizationInstanceView(generics.RetrieveUpdateDestroyAPIView):
"""
Returns a single org.
@@ -104,14 +127,23 @@
# Now sort out the UserProfile instance.
# Since we need to set the user attribute ourselves, we set commit=False.
# This delays saving the model until we're ready to avoid integrity problems.
- userprofile = UserProfile()
- userprofile.user = user
+ ###userprofile = UserProfile()
+ ###userprofile.user = user
# Now we save the UserProfile model instance.
- userprofile.save()
+ ###userprofile.save()
+
+ # Set permissions for own profile
+ assign_perm('view_userprofile', user, user)
+ assign_perm('change_userprofile', user, user)
+ assign_perm('delete_userprofile', user, user)
+ #assign_perm('view_userprofile', user, userprofile)
+ #assign_perm('change_userprofile', user, userprofile)
+ #assign_perm('delete_userprofile', user, userprofile)
# Update our variable to tell the template registration was successful.
registrationSuccessful = True
+
# add some logic to log events, log in users directly
print "successful registration of " + request.POST['email'] +" "+ datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
request.POST['email_to'] = user.email
@@ -130,7 +162,7 @@
Log users out and re-direct them to the main page.
"""
logout(request)
- return HttpResponseRedirect('/')
+ return HttpResponseRedirect('/AppMgr/login')
@watch_login
def login_user(request):
diff --git a/requirements.txt b/requirements.txt
index 4b8cb65..a620e48 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -3,6 +3,7 @@
django-custom-user==0.6
django-extensions==1.6.7
django-grappelli==2.8.1
+django-guardian==1.4.4
djangorestframework==3.3.3
gunicorn==19.6.0
psycopg2==2.6.1
diff --git a/tap/settings/base.py b/tap/settings/base.py
index 133e055..804014f 100644
--- a/tap/settings/base.py
+++ b/tap/settings/base.py
@@ -58,6 +58,7 @@
'django.contrib.messages',
'django.contrib.sites',
'django.contrib.staticfiles',
+ 'guardian',
'custom_user',
'AppMgr',
'axes',
@@ -79,9 +80,18 @@
AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend',
+ 'guardian.backends.ObjectPermissionBackend',
)
+GUARDIAN_MONKEY_PATCH = False
-AUTH_USER_MODEL = 'custom_user.EmailUser'
+AUTH_USER_MODEL = 'AppMgr.UserProfile'
+
+REST_FRAMEWORK = {
+ 'DEFAULT_AUTHENTICATION_CLASSES': (
+ 'rest_framework.authentication.BasicAuthentication',
+ )
+}
+LOGIN_REDIRECT_URL = '/AppMgr/users'
TEMPLATES = [
{
diff --git a/tap/settings/production.py b/tap/settings/production.py
index dd9aadc..2787a1f 100644
--- a/tap/settings/production.py
+++ b/tap/settings/production.py
@@ -16,7 +16,7 @@
'django_extensions',
)
-DEBUG = False
+#DEBUG = False
for T in TEMPLATES:
T['OPTIONS']['debug'] = DEBUG
diff --git a/tap/urls.py b/tap/urls.py
index 7492fe5..7637cd0 100644
--- a/tap/urls.py
+++ b/tap/urls.py
@@ -19,4 +19,5 @@
url(r'^grappelli/', include('grappelli.urls')),
url(r'^admin/', include(admin.site.urls)),
url(r'^AppMgr/', include('AppMgr.urls', namespace='AppMgr')),
+ url(r'^api-auth/', include('rest_framework.urls')),
]