diff --git a/README.md b/README.md index 6c7e7da..fa31c76 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,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/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/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 %} + + + +
+ + +
+

Admin Panel

+

To Add New Superuser

+
+ +
+ +
+
+
+
+
+ +
+
+
+ {% csrf_token %} +
+ + +
+ {{form.errors.first_name}} + + +
+ + +
+ {{form.errors.last_name}} + + +
+ + +
+ {{form.errors.username}} + + +
+ + +
+ {{form.errors.email}} + + +
+ + +
+ {{form.errors.password}} + + +
+ + +
+ {{form.errors.password1}} + + +
+ Check if Superuser + +
+ + {{form.non_field_errors.0}} + + +
+
+
+ +
+
+ +
+
+
+ +

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') + + diff --git a/omi_security/tests/test_views.py b/omi_security/tests/test_views.py index f260ec8..aef5e7b 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,29 +10,103 @@ 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', + } + + 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, + } + def test_login(self): user_login = self.client.login(username="testuser", password="secret") self.assertTrue(user_login) - response = self.client.get("/") - 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("/") - 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, 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) - response = self.client.get(reverse('about')) + + + def test_get_signup(self): + response = self.client.get("/signup") self.assertEqual(response.status_code, 200) + def test_post_signup(self): + params = self.form_params() + expected_username = params['username'] + + self.client.post("/signup", params) + + self.assertTrue(User.objects.filter(username=expected_username).exists(), + "User was not created.") + #you = User.objects.filter(username=expected_username) + #for y in you: + #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