From cb7b5fe646b587e1366e6190900ab7594cbc4de1 Mon Sep 17 00:00:00 2001 From: Aisha Saeed Date: Sat, 7 Jul 2018 22:34:23 +0300 Subject: [PATCH 1/4] modifying test according to new token imeplementation --- .../migrations/0005_auto_20180620_1122.py | 18 +++++++++++ omi_security/tests/test_views.py | 31 +++++++++++++++++-- 2 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 omi_security/security_node/migrations/0005_auto_20180620_1122.py diff --git a/omi_security/security_node/migrations/0005_auto_20180620_1122.py b/omi_security/security_node/migrations/0005_auto_20180620_1122.py new file mode 100644 index 0000000..26f1427 --- /dev/null +++ b/omi_security/security_node/migrations/0005_auto_20180620_1122.py @@ -0,0 +1,18 @@ +# Generated by Django 2.0.4 on 2018-06-20 11:22 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('security_node', '0004_auto_20180508_1830'), + ] + + operations = [ + migrations.AlterField( + model_name='group', + name='group_name', + field=models.CharField(error_messages={'unique': 'This group name has already been registered.'}, max_length=200, unique=True), + ), + ] diff --git a/omi_security/tests/test_views.py b/omi_security/tests/test_views.py index f260ec8..0c43d55 100644 --- a/omi_security/tests/test_views.py +++ b/omi_security/tests/test_views.py @@ -15,12 +15,13 @@ def setUp(self): def test_login(self): user_login = self.client.login(username="testuser", password="secret") self.assertTrue(user_login) - response = self.client.get("/") + response = self.client.get("create_oauth_token") self.assertEqual(response.status_code, 200) + def test_logout(self): self.client.login(username="testuser", password="secret") - response1 = self.client.get("/") + response1 = self.client.get("create_oauth_token") self.assertEquals(response1.status_code, 200) self.client.logout() response2 = self.client.get("/") @@ -28,13 +29,37 @@ def test_logout(self): def test_about(self): self.client.login(username='testuser', password='secret') - response = self.client.get("/") + response = self.client.get("create_oauth_token") self.assertEqual(response.status_code, 200) response = self.client.get(reverse('about')) self.assertEqual(response.status_code, 200) +class signupTest(TestCase): + + def form_params(self): + return {'first_name': 'foobar', + 'last_name': 'foobar', + 'username': 'foobar', + 'email': 'foobar@gmail.com', + 'password': 'foobar', + 'password1': 'foobar', + 'is_superuser':'false', + 'superuser_secret': 'Iamsuperuser12345',} + def test_view_renders(self): + response = self.client.get(reverse('signup')) + self.assertEqual(response.status_code, 200) + + def test_user_created(self): + params = self.form_params() + expected_username = params['username'] + self.client.post(reverse('signup'), params) + + self.assertTrue(User.objects.filter(username=expected_username).exists(), + "User was not created.") + response = self.client.get("/") + self.assertEqual(response.status_code, 302) From b303f35709ad16c7024badac5873eee3b9086a6f Mon Sep 17 00:00:00 2001 From: Aisha Saeed Date: Sat, 7 Jul 2018 23:28:27 +0300 Subject: [PATCH 2/4] Tests running --- omi_security/tests/test_views.py | 57 +++++++++++++++++--------------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/omi_security/tests/test_views.py b/omi_security/tests/test_views.py index 0c43d55..cca60ef 100644 --- a/omi_security/tests/test_views.py +++ b/omi_security/tests/test_views.py @@ -1,6 +1,4 @@ from django.test import TestCase -#from django.test import Client -from django.urls import reverse from django.contrib.auth.models import User # Create your tests here. @@ -12,54 +10,59 @@ def setUp(self): 'password': 'secret'} User.objects.create_user(**self.credentials) + def form_params(self): + return {'first_name': 'foobar', + 'last_name': 'foobar', + 'username': 'foobar', + 'email': 'foobar@gmail.com', + 'password': 'foobar', + 'password1': 'foobar', + 'is_superuser': True, + 'superuser_secret': 'Iamsuperuser12345',} + def test_login(self): user_login = self.client.login(username="testuser", password="secret") self.assertTrue(user_login) - response = self.client.get("create_oauth_token") - self.assertEqual(response.status_code, 200) + response = self.client.get("/create_oauth_token") + self.assertEqual(response.status_code, 302) def test_logout(self): self.client.login(username="testuser", password="secret") - response1 = self.client.get("create_oauth_token") - self.assertEquals(response1.status_code, 200) + response1 = self.client.get("/create_oauth_token") + self.assertEquals(response1.status_code, 302) self.client.logout() response2 = self.client.get("/") self.assertEquals(response2.status_code, 302) def test_about(self): self.client.login(username='testuser', password='secret') - response = self.client.get("create_oauth_token") - self.assertEqual(response.status_code, 200) - response = self.client.get(reverse('about')) + response = self.client.get("/create_oauth_token") + self.assertEqual(response.status_code, 302) + response = self.client.get("/about") self.assertEqual(response.status_code, 200) + def test_home(self): + self.client.login(username='testuser', password='secret') + response = self.client.get("/create_oauth_token") + self.assertEqual(response.status_code, 302) + response = self.client.get("/") + self.assertEqual(response.status_code, 200) -class signupTest(TestCase): - - def form_params(self): - return {'first_name': 'foobar', - 'last_name': 'foobar', - 'username': 'foobar', - 'email': 'foobar@gmail.com', - 'password': 'foobar', - 'password1': 'foobar', - 'is_superuser':'false', - 'superuser_secret': 'Iamsuperuser12345',} - def test_view_renders(self): - response = self.client.get(reverse('signup')) + def test_get_signup(self): + response = self.client.get("/signup") self.assertEqual(response.status_code, 200) - def test_user_created(self): + def test_post_signup(self): params = self.form_params() expected_username = params['username'] - self.client.post(reverse('signup'), params) + self.client.post("/signup", params) self.assertTrue(User.objects.filter(username=expected_username).exists(), "User was not created.") - response = self.client.get("/") - self.assertEqual(response.status_code, 302) - + #you = User.objects.filter(username=expected_username) + #for y in you: + #print(y.__dict__) \ No newline at end of file From e08907887ace69269eba5dd5ae544cf963a6f3c1 Mon Sep 17 00:00:00 2001 From: Aisha Saeed Date: Tue, 10 Jul 2018 17:52:34 +0300 Subject: [PATCH 3/4] Added admin panel to add/remove superusers. Removed superuser option from sign up page. --- README.md | 3 +- omi_security/security_node/form.py | 42 +++- .../security_node/templates/base.html | 3 + .../security_node/templates/signup.html | 4 +- .../templates/superusers_panel.html | 184 ++++++++++++++++++ omi_security/security_node/urls.py | 4 +- omi_security/security_node/views.py | 37 +++- 7 files changed, 271 insertions(+), 6 deletions(-) create mode 100644 omi_security/security_node/templates/superusers_panel.html diff --git a/README.md b/README.md index 48d42a8..1775085 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,8 @@ Initial dependencies 1. Install python and pip: `sudo apt-get install python3 python3-pip` 2. Install other dependencies: `sudo apt-get install libsasl2-dev python-dev libldap2-dev libssl-dev python-ldap django-auth-ldap` -1. Install python library: `pip3 install -r requirements.txt` +3. Install python library: `pip3 install -r requirements.txt` +4. To create admin: `python3 manage.py createsuperuser` To configure NGINX as proxy, use the following method diff --git a/omi_security/security_node/form.py b/omi_security/security_node/form.py index a21bf3a..71c353c 100644 --- a/omi_security/security_node/form.py +++ b/omi_security/security_node/form.py @@ -12,8 +12,8 @@ class UserForm(forms.ModelForm): email = forms.EmailField(label='Email', max_length=64, widget=forms.TextInput(attrs={'placeholder': 'Email'})) password = forms.CharField(min_length=6, max_length=32, label='Password', widget=forms.PasswordInput) password1 = forms.CharField(min_length=6, max_length=32, label='Password confirmation', widget=forms.PasswordInput) - is_superuser = forms.BooleanField(label='Superuser', required=False) - superuser_secret = forms.CharField(label='superuser secret', max_length=64, required=False, widget=forms.TextInput(attrs={'placeholder': 'superuser secret'})) + #is_superuser = forms.BooleanField(label='Superuser', required=False) + #superuser_secret = forms.CharField(label='superuser secret', max_length=64, required=False, widget=forms.TextInput(attrs={'placeholder': 'superuser secret'})) class Meta: fields = ['first_name', 'last_name', 'username', 'email', 'password', 'password1', 'is_superuser'] model=User @@ -25,6 +25,7 @@ def clean(self): raise forms.ValidationError( "Password and Confirm Password does not match" ) + """ if cleaned_data.get("is_superuser"): cleaned_data = super(UserForm, self).clean() superuser_secret = cleaned_data.get("superuser_secret") @@ -33,6 +34,7 @@ def clean(self): raise forms.ValidationError( "Please enter valid superuser secret or uncheck the superuser checkbox" ) + """ def clean_email(self): email = self.cleaned_data.get('email') username = self.cleaned_data.get('username') @@ -55,3 +57,39 @@ class Meta: model = Group +class SuperuserForm(forms.ModelForm): + first_name = forms.CharField(label='First Name', max_length=64,widget=forms.TextInput(attrs={'placeholder': 'First name'})) + last_name = forms.CharField(label='Last Name', max_length=64,widget=forms.TextInput(attrs={'placeholder': 'Last Name'})) + username = forms.CharField(min_length=6, label='Username', max_length=32, widget=forms.TextInput(attrs={'placeholder': 'Username'})) + email = forms.EmailField(label='Email', max_length=64, widget=forms.TextInput(attrs={'placeholder': 'Email'})) + password = forms.CharField(min_length=6, max_length=32, label='Password', widget=forms.PasswordInput) + password1 = forms.CharField(min_length=6, max_length=32, label='Password confirmation', widget=forms.PasswordInput) + is_superuser = forms.BooleanField(label='Superuser', required=False) + + class Meta: + fields = ['first_name', 'last_name', 'username', 'email', 'password', 'password1', 'is_superuser'] + model = User + + def clean(self): + cleaned_data = super(SuperuserForm, self).clean() + password = cleaned_data.get("password") + password1 = cleaned_data.get("password1") + if password != password1: + raise forms.ValidationError( + "Password and Confirm Password does not match" + ) + + def clean_email(self): + email = self.cleaned_data.get('email') + username = self.cleaned_data.get('username') + if email and User.objects.filter(email=email).exclude(username=username).exists(): + raise forms.ValidationError(u'Email addresses must be unique.') + return email + + def save(self, commit=True): + # Save the provided password in hashed format + user = super(SuperuserForm, self).save(commit=False) + user.set_password(self.cleaned_data["password"]) + if commit: + user.save() + return user \ No newline at end of file diff --git a/omi_security/security_node/templates/base.html b/omi_security/security_node/templates/base.html index 4ce8040..d31e38b 100644 --- a/omi_security/security_node/templates/base.html +++ b/omi_security/security_node/templates/base.html @@ -22,7 +22,10 @@

OMI Security Module

Home {% if user.is_authenticated %} + {% if user.is_superuser %} Authorization Module + Admin Panel + {% endif %} About Log out {{request.user}} {% else %} diff --git a/omi_security/security_node/templates/signup.html b/omi_security/security_node/templates/signup.html index b0bfaba..cfdd3f7 100644 --- a/omi_security/security_node/templates/signup.html +++ b/omi_security/security_node/templates/signup.html @@ -63,7 +63,7 @@

Login or Sign Up

{{form.errors.password1}} - + diff --git a/omi_security/security_node/templates/superusers_panel.html b/omi_security/security_node/templates/superusers_panel.html new file mode 100644 index 0000000..615b1e3 --- /dev/null +++ b/omi_security/security_node/templates/superusers_panel.html @@ -0,0 +1,184 @@ +{% extends 'base.html' %} + +{% block content %} + + + +
+ + + + +

To Modify Existing User Roles

+ + + + + + + + + + + {% for user in list_users %} + + + + + + + {% if user.is_superuser %} + + + {% else %} + + + {% endif %} + + {% endfor %} +
First NameLast NameEmailUsernameIs_superuserChange Status
{{ user.first_name }}{{ user.last_name }}{{ user.email }}{{ user.username }}{{ user.is_superuser }}
+ {% csrf_token %} + +
+ {% csrf_token %} + +
+ + + +
+ + + + +{% endblock %} + + + + + + + + + +

Sign up

+
+ {% csrf_token %} + {{ form }} + +
+ + + + + + + + + + + + + diff --git a/omi_security/security_node/urls.py b/omi_security/security_node/urls.py index 0b607c2..a9bff96 100644 --- a/omi_security/security_node/urls.py +++ b/omi_security/security_node/urls.py @@ -1,4 +1,4 @@ -from django.urls import path +from django.urls import path, re_path from . import views @@ -11,6 +11,8 @@ path(r'omi_authquery', views.omi_authquery, name='omi_authquery'), path(r'about', views.about, name='about'), path(r'create_oauth_token', views.create_oauth_token, name='create_oauth_token'), + path(r'superusers_panel', views.superusers_panel, name='superusers_panel'), + re_path(r'^userRole/(?P[0-9]+)/$', views.userRole, name='userRole'), ] diff --git a/omi_security/security_node/views.py b/omi_security/security_node/views.py index 85b7719..3d96348 100644 --- a/omi_security/security_node/views.py +++ b/omi_security/security_node/views.py @@ -4,7 +4,7 @@ from django.http import HttpResponse, JsonResponse from security_node.models import Group, User_Group_Relation, Rule from django.contrib.auth.models import User -from security_node.form import UserForm, GroupForm +from security_node.form import UserForm, GroupForm, SuperuserForm from django.contrib.auth.decorators import login_required from django.contrib.auth import authenticate from django.contrib.auth import login as auth_login @@ -173,6 +173,41 @@ def omi_authquery(request): #{'allow': [], 'deny': [], 'isAdmin': true|false} +@login_required +@csrf_protect +def superusers_panel(request): + + if not token_validator(request): + return redirect('logout') + + if request.user.is_superuser: + if request.method == 'POST': + form = SuperuserForm(request.POST) + if form.is_valid(): + form.save() + return redirect('home') + else: + form = SuperuserForm() + users = User.objects.all() + return render(request, 'superusers_panel.html', {'form': form, "list_users": users}) + else: + return redirect('home') + + +@login_required +@csrf_protect +def userRole(request, user_id): + + if not token_validator(request): + return redirect('logout') + + user = User.objects.get(id=user_id) + modify_user = request.POST.get('user_superuser') + user.is_superuser = False if modify_user == "superuser" else True + user.save() + return redirect('superusers_panel') + + From f5b4958bb920f5317682de03318fd5eef7912a0d Mon Sep 17 00:00:00 2001 From: Aisha Saeed Date: Wed, 11 Jul 2018 01:13:52 +0300 Subject: [PATCH 4/4] Added admin panel to add/remove superusers. Removed superuser option from sign up page. --- omi_security/tests/test_views.py | 48 ++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/omi_security/tests/test_views.py b/omi_security/tests/test_views.py index cca60ef..aef5e7b 100644 --- a/omi_security/tests/test_views.py +++ b/omi_security/tests/test_views.py @@ -17,8 +17,17 @@ def form_params(self): 'email': 'foobar@gmail.com', 'password': 'foobar', 'password1': 'foobar', + } + + def form_params_admin_panel(self): + return {'first_name': 'hellobar', + 'last_name': 'hellobar', + 'username': 'hellobar', + 'email': 'hellobar@gmail.com', + 'password': 'hellobar', + 'password1': 'hellobar', 'is_superuser': True, - 'superuser_secret': 'Iamsuperuser12345',} + } def test_login(self): user_login = self.client.login(username="testuser", password="secret") @@ -65,4 +74,39 @@ def test_post_signup(self): #you = User.objects.filter(username=expected_username) #for y in you: - #print(y.__dict__) \ No newline at end of file + #print(y.__dict__) + def test_admin_panel(self): + password = 'adminpassword' + my_admin = User.objects.create_superuser('adminuser', 'adminemail@test.com', password) + self.client.login(username=my_admin.username, password=password) + response = self.client.get("/create_oauth_token") + self.assertEqual(response.status_code, 302) + u = User.objects.get(username='adminuser') + self.assertTrue(u.is_superuser) + response = self.client.get("/superusers_panel") + self.assertEqual(response.status_code, 200) + + def test_admin_panel_normal_user(self): + self.client.login(username='testuser', password='secret') + response = self.client.get("/create_oauth_token") + self.assertEqual(response.status_code, 302) + u = User.objects.get(username='testuser') + self.assertFalse(u.is_superuser) + response = self.client.get("/superusers_panel") + self.assertEqual(response.status_code, 302) + + def test_post_admin_panel(self): + params = self.form_params_admin_panel() + expected_username = params['username'] + + password = 'adminpassword' + my_admin = User.objects.create_superuser('adminuser', 'adminemail@test.com', password) + self.client.login(username=my_admin.username, password=password) + self.client.get("/create_oauth_token") + self.client.post("/superusers_panel", params) + + self.assertTrue(User.objects.filter(username=expected_username).exists(), + "SuperUser was not created.") + + new_user = User.objects.get(username=expected_username) + self.assertTrue(new_user.is_superuser) \ No newline at end of file