diff --git a/app/templates/app/includes/sidebar_profile.html b/app/templates/app/includes/sidebar_profile.html
index 72caa8dcd754a7264bed1dfcc4df6ac901bc56c6..dee25754a44739ec8bc3d9a33fbbea844c7ce629 100644
--- a/app/templates/app/includes/sidebar_profile.html
+++ b/app/templates/app/includes/sidebar_profile.html
@@ -1,6 +1,6 @@
-<ul class="navbar-nav bg-gradient-primary sidebar sidebar-dark accordion" id="accordionSidebar">
-      <!-- Sidebar - Brand -->
-      <a class="sidebar-brand d-flex align-items-center justify-content-center" href="{% url 'daftar_katalog' %}">
+    <ul class="navbar-nav bg-gradient-primary sidebar sidebar-dark accordion" id="accordionSidebar">
+    <!-- Sidebar - Brand -->
+    <a class="sidebar-brand d-flex align-items-center justify-content-center" href="{% url 'daftar_katalog' %}">
         <div class="sidebar-brand-icon rotate-n-15"></div>
         <div class="sidebar-brand-text mx-3">Digipus</div>
     </a>
@@ -10,12 +10,16 @@
 
     <!-- Nav Item - Dashboard -->
     <li class="nav-item">
-    <a class="nav-link" href="/profil/">
-        <span>Halaman Profil</span></a>
+        <a class="nav-link" href="/profil/">
+            <span>Halaman Profil</span></a>
     </li>
 
     <li class="nav-item">
-    <a class="nav-link" href="/sunting/">
-        <span>Sunting Profil</span></a>
+        <a class="nav-link" href="/sunting/">
+            <span>Sunting Profil</span></a>
+    </li>
+    <li class="nav-item">
+        <a class="nav-link" href="/change-password/">
+            <span>Change Password</span></a>
     </li>
 </ul>
\ No newline at end of file
diff --git a/app/templates/change-password.html b/app/templates/change-password.html
new file mode 100644
index 0000000000000000000000000000000000000000..cd9bc26a4dbe54cda04d17359141878e91bc0332
--- /dev/null
+++ b/app/templates/change-password.html
@@ -0,0 +1,17 @@
+{% extends 'app/base_profile.html' %}
+{% block title %}Change Password{% endblock%}
+{% block content %}
+
+
+<h1> Change Password </h1>
+<br/><br/>
+
+<div class = "from-group">
+	<form method="POST">
+		{% csrf_token %}
+		{{ form.as_p }}
+		<button class="btn btn-secondary"> Change Password</button>
+	</form>
+</div>
+
+{% endblock %}
\ No newline at end of file
diff --git a/app/templates/password_success.html b/app/templates/password_success.html
new file mode 100644
index 0000000000000000000000000000000000000000..3c61031a145a7f5cbf6bfa30b7f62368419dba19
--- /dev/null
+++ b/app/templates/password_success.html
@@ -0,0 +1,11 @@
+{% extends 'app/base_profile.html' %}
+{% block title %}Change Password{% endblock%}
+{% block content %}
+
+
+<h1> Password was Changed Successfully!</h1>
+<br/><br/>
+
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/app/tests.py b/app/tests.py
index a233ab6f822bf9590054382bd09b1ec5464561df..1b5bc1b7a5e25923071e85a85ebb7bde4e9c853b 100644
--- a/app/tests.py
+++ b/app/tests.py
@@ -56,6 +56,8 @@ from .views import (
     KatalogPerKontributorView,
     UploadMateriView,
     UploadMateriExcelView,
+    PasswordChangeViews,
+    password_success,
 )
 from app.forms import SuntingProfilForm, year_choices
 from app.utils.fileManagementUtil import get_random_filename, remove_image_exifdata
@@ -2354,4 +2356,46 @@ class YearChoicesTest(TestCase):
     def test_min_release_year_is_2000(self):
         choices = year_choices()
 
-        self.assertEqual((2000, 2000), choices[0])
\ No newline at end of file
+        self.assertEqual((2000, 2000), choices[0])
+class ChangePasswordTest(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 = PasswordChangeViews
+        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()
+
+    
\ No newline at end of file
diff --git a/app/urls.py b/app/urls.py
index baa6bccb6630849347f02cd47363536d7cc68d83..8061b3f691d49e91c8f5ea4f99e66efc780b81e5 100644
--- a/app/urls.py
+++ b/app/urls.py
@@ -5,8 +5,8 @@ from app.views import (DashboardKontributorView, ProfilKontributorView,
                        SuksesLoginAdminView, SuksesLoginKontributorView, DownloadHistoryView,
                        SuntingProfilView, UploadMateriHTML, UploadMateriView, UploadMateriExcelView,
                        ProfilAdminView, PostsView, SuntingProfilAdminView,
-                       ReqMateriView, KatalogPerKontributorView)
-
+                       ReqMateriView, KatalogPerKontributorView, PasswordChangeViews, password_success)
+from django.contrib.auth import views as auth_views
 urlpatterns = [
     path("", views.DaftarKatalog.as_view(), name="daftar_katalog"),
     path("materi/<int:pk>/", views.DetailMateri.as_view(), name="detail-materi"),
@@ -37,4 +37,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/", PasswordChangeViews.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 ce550f5f8f3e95999c111f89f65f3c9f8eb9bcf2..8ad0176a7630e0c6501d330b4a27045a9ef19bf3 100644
--- a/app/views.py
+++ b/app/views.py
@@ -29,6 +29,10 @@ from authentication.models import User
 from .services import DafterKatalogService, DetailMateriService, LikeDislikeService, MateriFieldValidationHelperService, \
     DownloadViewMateriHelperService, UploadMateriService, EditProfileService, RevisiMateriService, \
     DownloadHistoryService, GoogleDriveUploadService
+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"):
@@ -695,4 +699,12 @@ def save_to_gdrive(request, pk):
     else:
         raise Http404("File tidak dapat ditemukan.")
 
-    return HttpResponseRedirect(reverse('detail-materi', kwargs={'pk': pk}))
\ No newline at end of file
+    return HttpResponseRedirect(reverse('detail-materi', kwargs={'pk': pk}))
+
+class PasswordChangeViews(PasswordChangeView):
+    
+    from_class = PasswordChangeForm
+    success_url = reverse_lazy('password_success')
+
+def password_success(request):
+    return render(request, 'password_success.html', {})
\ No newline at end of file
diff --git a/digipus/__pycache__/settings.cpython-36.pyc b/digipus/__pycache__/settings.cpython-36.pyc
index bbd092036ce26932962c8c236860e7899ca31f6f..ee0772144662d7457ede232e8137ab9041115ac7 100644
Binary files a/digipus/__pycache__/settings.cpython-36.pyc and b/digipus/__pycache__/settings.cpython-36.pyc differ