-
Notifications
You must be signed in to change notification settings - Fork 2
Django Authentication Basics
A VERY BASIC and not very secure cookie-based authentication system has been implemented in Django for the OPS. The actual storage and management of the authentication (in the database) is secure, but how clients authenticate (by passing simple cookies and plain-text passwords) is not.
Telling Django to include the models (database schema) for authentication is as simple as including the following lines in the settings.py file.
Add 'django.contrib.auth',
to INSTALLED_APPS
Add 'django.contrib.auth.middleware.AuthenticationMiddleware',
to MIDDLEWARE_CLASSES
With those two lines on the syncdb
command all the framework needed to store basic Django users is created.
To have a custom user profile tied to each Django user (containing custom permissions) we need to add a few things in settings.py AND create some new files.
The new files created are in ops/opsuser/*
. The only key one is models.py:
from django.contrib.gis.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
class UserProfile(models.Model):
user = models.OneToOneField(User,related_name="profile", unique=True)
rds_season_groups = models.ManyToManyField('rds.season_groups',null=True)
rds_layer_groups = models.ManyToManyField('rds.layer_groups',null=True)
accum_season_groups = models.ManyToManyField('accum.season_groups',null=True)
accum_layer_groups = models.ManyToManyField('accum.layer_groups',null=True)
snow_season_groups = models.ManyToManyField('snow.season_groups',null=True)
snow_layer_groups = models.ManyToManyField('snow.layer_groups',null=True)
kuband_season_groups = models.ManyToManyField('kuband.season_groups',null=True)
kuband_layer_groups = models.ManyToManyField('kuband.layer_groups',null=True)
layerGroupRelease = models.BooleanField(default=False)
seasonRelease = models.BooleanField(default=False)
createData = models.BooleanField(default=False)
bulkDeleteData = models.BooleanField(default=False)
isRoot = models.BooleanField(default=False)
def create_profile(sender, instance, created, **kwargs):
if created:
profile, created = UserProfile.objects.get_or_create(user=instance)
profile.rds_season_groups = [1]
profile.accum_season_groups = [1]
profile.snow_season_groups = [1]
profile.kuband_season_groups = [1]
profile.rds_layer_groups = [1,2]
profile.accum_layer_groups = [1,2]
profile.snow_layer_groups = [1,2]
profile.kuband_layer_groups = [1,2]
post_save.connect(create_profile, sender=User)
This file defines an additional schema in the database for a user profile. Note the last line post_save.connect(create_profile, sender=User)
which tells Django to create a new profile with a 1-1 relationship with a Django user each time a new user is created.
In settings.py we need to add the following:
Add the line AUTH_PROFILE_MODULE = 'opsuser.UserProfile'
Add 'opsuser',
to INSTALLED_APPS
Creating users is simple. One can use the createUser() view or follow the procedure outlined below:
- Become user root
sudo -i
- Activate the virtual environment
source /usr/bin/venv/bin/activate
- Start the Django shell
python /var/django/ops/mange.py shell
- Modify the following code (set username,email,password) and paste into the Django shell. You can also edit the default permissions if you want to. The permissions shown are for a default CReSIS internal data user.
from django.contrib.auth.models import User
# set new user properties
userName=''
userEmail=''
userPassword=''
# create the new user
newUser = User.objects.create_user(userName, userEmail, userPassword)
# set the user profile options (example for cresis superuser)
newUser.profile.rds_layer_groups = [1,2,4] #4=atm(OPS2)
newUser.profile.accum_layer_groups = [1,2]
newUser.profile.kuband_layer_groups = [1,2]
newUser.profile.snow_layer_groups = [1,2]
newUser.profile.rds_season_groups = [1,2]
newUser.profile.accum_season_groups = [1,2]
newUser.profile.kuband_season_groups = [1,2]
newUser.profile.snow_season_groups = [1,2]
newUser.profile.layerGroupRelease = True
newUser.profile.bulkDeleteData = False
newUser.profile.createData = True
newUser.profile.seasonRelease = True
# save the user profile
newUser.profile.save()
To add/remove permissions from an existing user, root users can use the alterUserPermissions() view. Administrators can also execute the following commands in the Django shell:
from django.contrib.auth.models import User
userObj = User.objects.get(username_exact='ENTERNAMEHERE')
userProf = userObj.profile
# TO ADD SOMETHING
userProf.rds_layer_groups.add(SOMEGROUPID)
# TO REMOVE SOMETHING
userProf.rds_layer_groups.delete(SOMEGROUPID)
# TO SAVE CHANGES
userProf.save()
An example would be to check if a user is allowed to create data. From createPath in views.py:
models,data,app,cookies = utility.getInput(request) # get the input and models
userProfileObj,status = utility.getUserProfile(cookies)
if status:
if not userProfileObj.createData:
return utility.response(0,'ERROR: USER NOT AUTHORIZED TO CREATE DATA.',{})
else:
return utility.response(0,userProfileObj,{});
The cookies (from whatever client, see getData
in utility.py) are retrieved in the call to getInput
. Then the function getUserProfile(cookies)
is used to retrieve the user profile object. At that point it's just logical checks against permissions.