Fakultas Ilmu Komputer UI

Commit 6fd9fe87 authored by Rizkhi PH's avatar Rizkhi PH 🤔
Browse files

[#2] Auth: Admin Activation

parent 4ccb88e8
......@@ -134,3 +134,15 @@ class PeriodForm(forms.Form):
if start_date > end_date:
self.add_error("end_date",
"waktu selesai sebelum waktu mulai")
class EditAdminStatusForm(forms.ModelForm):
is_active = forms.BooleanField(required=False)
class Meta:
model = User
fields = ["is_active"]
def __init__(self, *args, **kwargs):
super(EditAdminStatusForm, self).__init__(*args, **kwargs)
{% extends 'administration/base_administrasi.html' %}
{% load static %}
{% block content %}
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
Edit {{ page_title }}
</h6>
</div>
<div class="card-body">
<form method="POST">
{% csrf_token %}
{{ item.name }}
<div class="status d-flex align-items-baseline">
{{ form.is_active }} <br> Active
</div>
<div class="">
<button class="btn-sm btn-primary rounded p-12" type="submit">
<i class="far fa-save" aria-hidden="true"></i>
Simpan
</button>
</div>
</form>
</div>
</div>
{% endblock %}
\ No newline at end of file
......@@ -27,30 +27,39 @@
<table class="table table-bordered" id="dataTable" width="100%" cellspacing="0">
<thead>
<tr>
<th>Nama</th>
<th>NIK</th>
<th>Instansi</th>
<th>Pilihan</th>
<th scope="col">Nama</th>
<th scope="col">NIK</th>
<th scope="col">Instansi</th>
<th scope="col">Status</th>
<th scope="col">Pilihan</th>
</tr>
</thead>
<tfoot>
<tr>
<th>Nama</th>
<th>NIK</th>
<th>Instansi</th>
<th>Pilihan</th>
<th scope="col">Nama</th>
<th scope="col">NIK</th>
<th scope="col">Instansi</th>
<th scope="col">Status</th>
<th scope="col">Pilihan</th>
</tr>
</tr>
</tfoot>
<tbody>
{% for current in users_list %}
<tr>
<td>{{ current.name }}</td>
<td>{% if current.name %} {{ current.name }} {% else %} Superadmin {% endif %}</td>
<td>{{ current.nik }}</td>
<td>{{ current.instansi }}</td>
<td>{% if current.is_active %} Active {% else %} Inactive {% endif %}</td>
<td class="verif-buttons">
<span>
{% if user.is_superuser %}
{% if not current.is_superuser %}
<a href="/administration/setting/admin/{{ current.id }}/edit" class="accept-button button-decoration" role="button">Edit</a>
{% endif %}
{% endif %}
<a href="/administration/profil-admin/{{ current.id }}/" class="accept-button button-decoration">Detail</a>
{% if not current.is_superuser %}
<button type="button" class="reject-button button-decoration" data-toggle="modal" data-target="#confirmModal{{ current.id }}">Hapus</button>
<div class="modal fade" id="confirmModal{{ current.id }}" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
......@@ -80,6 +89,7 @@
</div>
</div>
</div>
{% endif %}
</span>
</td>
</tr>
......
......@@ -5,9 +5,12 @@ from django.urls import resolve
from administration import models, views
from administration.utils import id_generator
from administration.forms import EditAdminStatusForm
from app.models import Category, Materi
from authentication.models import User
from bs4 import BeautifulSoup
EDIT_ENDPOINT = "/edit"
class VerifikasiMateriTest(TestCase):
def setUp(self):
......@@ -809,7 +812,7 @@ class EditVerificationTest(TestCase):
**self.admin_credential, name="Admin", is_admin=True)
models.VerificationSetting(title='test', description="desc test").save()
self.verification = models.VerificationSetting.objects.first()
self.url = "/administration/setting/verification/" + str(self.verification.id) +"/edit"
self.url = "/administration/setting/verification/" + str(self.verification.id) + EDIT_ENDPOINT
def test_edit_verification_admin_access(self):
self.client.login(**self.admin_credential)
......@@ -891,7 +894,7 @@ class EditCategoryTest(TestCase):
**self.admin_credential, name="Admin", is_admin=True)
Category(name='test', description="desc test").save()
self.category = Category.objects.first()
self.url = "/administration/setting/category/" + str(self.category.id) +"/edit"
self.url = "/administration/setting/category/" + str(self.category.id) + EDIT_ENDPOINT
def test_edit_category_admin_access(self):
self.client.login(**self.admin_credential)
......@@ -961,3 +964,150 @@ class EditCategoryTest(TestCase):
self.assertTemplateUsed(response, self.template_name)
self.assertContains(response, "Edit Kategori Materi")
class EditAdminStatusFormTests(TestCase):
def test_set_active_admin(self):
form = EditAdminStatusForm(data={"is_active": True})
self.assertEqual(form.is_valid(), True)
def test_set_inactive_admin(self):
form = EditAdminStatusForm(data={"is_active": False})
self.assertEqual(form.is_valid(), True)
class DeleteAdminTests(TestCase):
def setUp(self):
self.client = Client()
self.user_credential = {
"email": "user@gov.id",
"password": id_generator()
}
self.admin_credential = {
"email": "admin@gov.id",
"password": id_generator()
}
self.superuser_credential = {
"email": "superuser@gov.id",
"password": id_generator()
}
self.user = get_user_model().objects.create_user(
**self.user_credential, name="User", is_contributor=True)
self.admin = get_user_model().objects.create_user(
**self.admin_credential, name="Admin", is_admin=True)
self.superuser = get_user_model().objects.create_user(
**self.superuser_credential, name="Superuser", is_admin=True, is_superuser=True)
User(name='dummy_admin', is_admin=True, email="dummy_admin@example.com").save()
User(name='dummy_superuser', is_admin=True, is_superuser=True, email="dummy_superuser@example.com").save()
self.dummy_admin = User.objects.filter(name="dummy_admin").get()
self.dummy_superuser = User.objects.filter(name="dummy_superuser").get()
self.delete_url_dummy_admin = self.url_generator_delete_admin(self.dummy_admin.id)
self.delete_url_dummy_superuser = self.url_generator_delete_admin(self.dummy_superuser.id)
def url_generator_delete_admin(self, id):
return "/administration/hapus-admin/" + str(id) + "/"
def test_delete_admin_as_admin_user(self):
self.client.login(**self.admin_credential)
self.assertEqual(User.objects.filter(
name="dummy_admin").count(), 1)
self.client.get(self.delete_url_dummy_admin)
self.assertEqual(User.objects.filter(
name="dummy_admin").count(), 0)
def test_cannot_delete_admin_as_user(self):
self.client.login(**self.user_credential)
response = self.client.get(self.delete_url_dummy_admin)
self.assertEqual(response.status_code, 403)
def test_cannot_delete_superuser_as_user_or_admin(self):
self.client.login(**self.user_credential)
response = self.client.get(self.delete_url_dummy_superuser)
self.assertEqual(response.status_code, 403)
self.client.login(**self.admin_credential)
response = self.client.get(self.delete_url_dummy_superuser)
self.assertEqual(response.status_code, 403)
def test_redirect_after_delet_admin(self):
self.client.login(**self.admin_credential)
response = self.client.get(self.delete_url_dummy_admin)
self.assertEqual(response.status_code, 302)
class EditAdminStatusTests(TestCase):
def setUp(self):
self.client = Client()
self.admin_credential = {
"email": "admin@gov.id",
"password": id_generator()
}
self.superuser_credential = {
"email": "superuser@gov.id",
"password": id_generator()
}
self.admin = get_user_model().objects.create_user(
**self.admin_credential, name="Admin", is_admin=True)
self.superuser = get_user_model().objects.create_user(
**self.superuser_credential, name="Superuser", is_admin=True, is_superuser=True)
User(name='dummy_admin', is_admin=True, email="dummy_admin@example.com").save()
User(name='dummy_superuser', is_admin=True, is_superuser=True, email="dummy_superuser@example.com").save()
self.dummy_admin = User.objects.filter(name="dummy_admin").get()
self.dummy_superuser = User.objects.filter(name="dummy_superuser").get()
self.edit_url_dummy_admin = self.url_generator_edit_admin(self.dummy_admin.id)
self.edit_url_dummy_superuser = self.url_generator_edit_admin(self.dummy_superuser.id)
def url_generator_edit_admin(self, id):
return "/administration/setting/admin/" + str(id) + EDIT_ENDPOINT
def test_get_edit_admin_html_content(self):
self.client.login(**self.superuser_credential)
response = self.client.get(self.edit_url_dummy_admin)
self.assertContains(response, self.dummy_admin.name)
response = self.client.get(self.edit_url_dummy_superuser)
self.assertContains(response, self.dummy_superuser.name)
def test_cannot_edit_set_active_admin_as_admin(self):
self.client.login(**self.admin_credential)
self.client.get(self.edit_url_dummy_admin)
response = self.client.post(self.edit_url_dummy_admin, {"is_active": "on"})
self.assertEqual(response.status_code, 403)
def test_edit_set_active_admin_as_superuser(self):
self.dummy_admin.is_active = False
self.client.login(**self.superuser_credential)
self.client.get(self.edit_url_dummy_admin)
response = self.client.post(self.edit_url_dummy_admin, {"is_active": "on"})
self.dummy_admin.refresh_from_db()
self.assertEqual(response.status_code, 302)
self.assertEqual(self.dummy_admin.is_active, True)
def test_edit_set_inactive_admin_as_superuser(self):
self.dummy_admin.is_active = True
self.client.login(**self.superuser_credential)
self.client.get(self.edit_url_dummy_admin)
response = self.client.post(self.edit_url_dummy_admin, {"is_active": "false"})
self.dummy_admin.refresh_from_db()
self.assertEqual(response.status_code, 302)
self.assertEqual(self.dummy_admin.is_active, False)
def test_cannot_edit_set_active_superuser_as_superuser(self):
self.client.login(**self.superuser_credential)
self.client.get(self.edit_url_dummy_superuser)
response = self.client.post(self.edit_url_dummy_superuser, {"is_active": "on"})
self.assertEqual(response.status_code, 403)
def test_cannot_access_edit_page_as_user(self):
self.client.login(**self.admin_credential)
response = self.client.get(self.edit_url_dummy_superuser)
self.assertEqual(response.status_code, 403)
from django.urls import path
from administration.views import VerificationView, DetailVerificationView, VerificationSettingView, CategorySettingView, KelolaKontributorView, ProfileContributorAdminView, ProfileAdminAdministrationView, KelolaAdminView, RegistrasiAdminView, EditVerificationView, delete_admin, delete_contributor, delete_verification, StatisticsView, StatisticApiView, EditCategoryView, delete_category, generatedummy
from administration.views import VerificationView, DetailVerificationView, VerificationSettingView, CategorySettingView, KelolaKontributorView, ProfileContributorAdminView, ProfileAdminAdministrationView, KelolaAdminView, RegistrasiAdminView, EditVerificationView, delete_admin, delete_contributor, delete_verification, StatisticsView, StatisticApiView, EditCategoryView, EditAdminStatusView, delete_category, generatedummy
app_name = "administration"
......@@ -22,6 +22,8 @@ urlpatterns = [
path("profil-admin/<int:pk>/", ProfileAdminAdministrationView.as_view()),
path("kelola-admin/", KelolaAdminView.as_view()),
path("kelola-admin/tambah/", RegistrasiAdminView.as_view()),
path("setting/admin/<int:pk>/edit",
EditAdminStatusView.as_view(), name="edit-admin-status"),
path("hapus-admin/<int:pk>/", delete_admin),
path("hapus-kontributor/<int:pk>/", delete_contributor),
path("generate-dummy", generatedummy),
......
......@@ -10,7 +10,7 @@ from django.contrib import messages
from django.utils import timezone, lorem_ipsum
from dateutil.relativedelta import relativedelta
from administration.models import VerificationReport, VerificationSetting, DeletionHistory
from administration.forms import CategoryForm, VerificationSettingForm, RegistrasiAdminForm, PeriodForm
from administration.forms import CategoryForm, VerificationSettingForm, RegistrasiAdminForm, PeriodForm, EditAdminStatusForm
from app.models import Category, Materi, ViewStatistics, DownloadStatistics, Comment, Like, getRandomColor
from authentication.models import User
from datetime import datetime
......@@ -19,6 +19,7 @@ from administration.utils import generate_time_step
from django.core import management
ADMINISTRATION_MANAGEMENT = "/administration/kelola-admin/"
def get_start_end_date(period):
if period == 'ALL_TIME':
......@@ -450,7 +451,7 @@ class RegistrasiAdminView(TemplateView):
new_user.password = make_password(data["password"])
new_user.is_admin = True
new_user.save()
return HttpResponseRedirect("/administration/kelola-admin/")
return HttpResponseRedirect(ADMINISTRATION_MANAGEMENT)
else:
context = self.get_context_data(**kwargs)
context["form"] = form
......@@ -520,12 +521,42 @@ class EditCategoryView(TemplateView):
context["form"] = form
return self.render_to_response(context)
class EditAdminStatusView(TemplateView):
template_name = "edit_admin.html"
def dispatch(self, request, *args, **kwargs):
if not request.user.is_authenticated or not request.user.is_superuser:
raise PermissionDenied(request)
return super(EditAdminStatusView, self).dispatch(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super(EditAdminStatusView, self).get_context_data(**kwargs)
context["page_title"] = "Admin Status"
context["item"] = User.objects.get(id=kwargs["pk"])
context["form"] = EditAdminStatusForm(instance=context["item"])
return context
def get(self, request, *args, **kwargs):
context = self.get_context_data(**kwargs)
return self.render_to_response(context=context)
def post(self, request, *args, **kwargs):
user_object = self.get_context_data(**kwargs)["item"]
if user_object.is_superuser:
raise PermissionDenied(request)
form = EditAdminStatusForm(
request.POST, instance=user_object)
form.save()
return HttpResponseRedirect(ADMINISTRATION_MANAGEMENT)
def delete_admin(request, *args, **kwargs):
if not request.user.is_authenticated or not request.user.is_admin:
raise PermissionDenied(request)
user_to_be_deleted = User.objects.get(pk=kwargs["pk"])
if (user_to_be_deleted.is_superuser):
raise PermissionDenied(request)
DeletionHistory.objects.create(
deleted_user_name=user_to_be_deleted.name,
deleted_user_role="Admin",
......@@ -533,7 +564,7 @@ def delete_admin(request, *args, **kwargs):
)
User.objects.filter(pk=kwargs["pk"]).delete()
return HttpResponseRedirect("/administration/kelola-admin/")
return HttpResponseRedirect(ADMINISTRATION_MANAGEMENT)
def delete_contributor(request, *args, **kwargs):
......
from django.contrib import admin
from .models import User
# Register your models here.
admin.site.register(User)
\ No newline at end of file
......@@ -34,6 +34,9 @@
<main>
<div class="limiter">
{% if message %}
<h1>{{ message }}</h1>
{% endif %}
<div class="container-login100">
<div class="wrap-login100">
<form class="login100-form validate-form" method="POST" action="">
......
......@@ -2,6 +2,7 @@ from django.test import Client, TestCase
from django.urls import resolve
from authentication.models import User
from administration.utils import id_generator
from register import views
......@@ -121,6 +122,7 @@ class RegisterPageTest(TestCase):
class RegisterAdminTest(TestCase):
def setUp(self):
self.client = Client()
self.random_password = id_generator()
def test_register_url_is_exist(self):
# Positive tests
......@@ -208,8 +210,8 @@ class RegisterAdminTest(TestCase):
"alamat": "bekasi",
"email": "bob@company.com",
"nomor_telpon": "087878726602",
"password": "1234",
"password2": "1234",
"password": self.random_password,
"password2": self.random_password,
},
)
self.assertEqual(User.objects.all().count(), 1)
......@@ -222,10 +224,43 @@ class RegisterAdminTest(TestCase):
"alamat": "bekasi",
"email": "bob@company.com",
"nomor_telpon": "087878726602",
"password": "1234",
"password2": "1234",
"password": self.random_password,
"password2": self.random_password,
},
)
self.assertEqual(User.objects.all().count(), 1)
self.assertIn(
b"Email sudah digunakan untuk mendaftar akun.", response.content)
def test_create_user_success_but_status_is_inactive(self):
self.client.post(
"/registrasi/admin/",
{
"name": "bob",
"instansi": "university",
"nik": "1706074940",
"alamat": "bekasi",
"email": "bob@company.com",
"nomor_telpon": "087878726602",
"password": self.random_password,
"password2": self.random_password,
},
)
self.assertEqual(User.objects.filter(name="bob").get().is_active, False)
def test_create_user_success_and_show_message_to_wait_for_internal_team(self):
response = self.client.post(
"/registrasi/admin/",
{
"name": "bob",
"instansi": "university",
"nik": "1706074940",
"alamat": "bekasi",
"email": "bob@company.com",
"nomor_telpon": "087878726602",
"password": self.random_password,
"password2": self.random_password,
},
)
self.assertEqual(User.objects.count(), 1)
self.assertIn("Please wait for our internal team to accept your admin account", response.content.decode())
......@@ -46,19 +46,20 @@ class RegistrasiAdmin(TemplateView):
def post(self, request, *args, **kwargs):
data = request.POST.copy()
form = UserForm(request.POST)
context = self.get_context_data(**kwargs)
context["form"] = form
if form.is_valid():
new_user = form.save(commit=False)
new_user.password = make_password(data["password"])
new_user.is_admin = True
new_user.is_active = False
new_user.save()
login(request, new_user)
return HttpResponseRedirect("/sukses-admin/")
else:
context = self.get_context_data(**kwargs)
context["form"] = form
context["message"] = "Please wait for our internal team to accept your admin account"
return self.render_to_response(context)
return self.render_to_response(context)
def get(self, request, *args, **kwargs):
context = self.get_context_data(**kwargs)
context["form"] = UserForm
return self.render_to_response(context=context)
\ No newline at end of file
return self.render_to_response(context=context)
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment