diff --git a/app/tests.py b/app/tests.py
index 1dcd63c3cecdfa0c581fce89553d39d7713dca1c..c124aa8a2e5ef49fe0bd31ad1f299e5736f30815 100644
--- a/app/tests.py
+++ b/app/tests.py
@@ -2114,3 +2114,51 @@ class MateriModelTest(TestCase):
 
         Like.objects.create(timestamp=datetime.now(), materi=self.materi, session_id="dummysessionid2")
         self.assertEqual(2, self.materi.like_count)
+
+class ChangePassword(TestCase):
+    def setUp(self):
+        self.client = Client()
+        self.kontributor = User.objects.create_contributor(email="kontributor@gov.id", password="kontributor")
+        self.admin = User.objects.create_admin(email="admin@gov.id", password="admin")
+        self.url = "/change-password/"
+        self.view = PasswordChangeView
+        self.template_name = "change-password.html"
+
+    def test_change_password_view(self):
+        found = resolve(self.url)
+        self.assertEqual(found.func.__name__, self.view.as_view().__name__)
+
+    def test_change_password_template(self):
+        # Login
+        self.client.login(email="kontributor@gov.id", password="kontributor")
+        # Test
+        response = self.client.get(self.url)
+        self.assertTemplateUsed(response, self.template_name)
+        # Logout
+        self.client.logout()
+
+    def test_change_password_url(self):
+        # Login
+        self.client.login(email="kontributor@gov.id", password="kontributor")
+        # Test
+        response = self.client.get(self.url)
+        self.assertEqual(response.status_code, 200)
+        # Logout
+        self.client.logout()
+
+    def test_change_password_access(self):
+        # Kontributor
+        # Login
+        self.client.login(email="kontributor@gov.id", password="kontributor")
+        # Test
+        response = self.client.get(self.url)
+        self.assertEqual(response.status_code, 200)
+        # Logout
+        self.client.logout()
+
+    def test_change_password_anonymous(self):
+        # Test
+        response = self.client.get(self.url)
+        self.assertEqual(response.status_code, 403)
+
+    
\ No newline at end of file
diff --git a/app/urls.py b/app/urls.py
index 7ccc70c3a5dc1c82dbcb59772f950b9a04e9c2da..3f0cc7dfdb02eb480b55a178cb0a7a5baa5f8df5 100644
--- a/app/urls.py
+++ b/app/urls.py
@@ -5,7 +5,8 @@ from app.views import (DashboardKontributorView, ProfilKontributorView,
                        SuksesLoginAdminView, SuksesLoginKontributorView, DownloadHistoryView,
                        SuntingProfilView, UploadMateriHTML, UploadMateriView, UploadMateriExcelView,
                        ProfilAdminView, PostsView, SuntingProfilAdminView,
-                       ReqMateriView, KatalogPerKontributorView)
+                       ReqMateriView, KatalogPerKontributorView, PasswordChangeView, password_success)
+from django.contrib.auth import views as auth_views
 
 urlpatterns = [
     path("", views.DaftarKatalog.as_view(), name="daftar_katalog"),
@@ -34,4 +35,6 @@ urlpatterns = [
          name="katalog-per-kontributor"),
     path("materi/rate/", views.add_rating_materi, name="rate-materi"),
     path("materi/<int:pk>/save-to-gdrive/", views.save_to_gdrive, name="save-to-gdrive"),
+    path("change-password/", PasswordChangeView.as_view(template_name='change-password.html')),
+    path("password_success/", views.password_success, name="password_success"),
 ]
diff --git a/app/views.py b/app/views.py
index 4f582eab8d7781c15239b589e6d2c350d9fc72e5..c943052b0cf7cd4cfe67c7fa67b34395ac21d6b3 100644
--- a/app/views.py
+++ b/app/views.py
@@ -35,6 +35,10 @@ from io import BytesIO
 from pydrive.auth import GoogleAuth
 from pydrive.drive import GoogleDrive
 from pydrive.auth import AuthenticationRejected
+from django.contrib.auth.views import PasswordChangeForm
+from django.urls import reverse_lazy
+from django.contrib.auth.views import PasswordChangeView
+from django.shortcuts import render
 
 
 def permission_denied(request, exception, template_name="error_403.html"):
@@ -854,4 +858,11 @@ def save_to_gdrive(request, pk):
         raise Http404("File tidak dapat ditemukan.")
 
     return HttpResponseRedirect(reverse("detail-materi", kwargs={"pk": pk}))
-
+    
+# class PasswordChangeView(PasswordChangeView):
+    
+#     from_class = PasswordChangeForm
+#     success_url = reverse_lazy('password_success')
+
+# def password_success(request):
+#     return render(request, 'password_success.html', {})