Fakultas Ilmu Komputer UI

Commit d857e942 authored by Ryan Karyadiputera's avatar Ryan Karyadiputera
Browse files

test2

parent 8d40a352
Pipeline #76802 failed with stages
in 22 minutes and 57 seconds
stages:
- test
- flake8
- build
- sonarqube
- deploy
variables:
......@@ -25,6 +27,65 @@ before_script:
- echo "AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY" >> sip/settings/.env
- echo "AWS_STORAGE_BUCKET_NAME=$AWS_STORAGE_BUCKET_NAME" >> sip/settings/.env
dev-test:
stage: test
script:
- python3 manage.py collectstatic --settings=sip.settings.staging --no-input
- python3 manage.py makemigrations --settings=sip.settings.dev
- python3 manage.py migrate --settings=sip.settings.dev
- python3 manage.py test --settings=sip.settings.dev
only:
- development
- /^.*PBI-.*$/
staging-test:
stage: test
script:
- python3 manage.py collectstatic --settings=sip.settings.staging --no-input
- python3 manage.py makemigrations --settings=sip.settings.staging
- python3 manage.py migrate --settings=sip.settings.staging
- python3 manage.py test --settings=sip.settings.staging
only:
- staging
lint:
stage: flake8
script:
- flake8
allow_failure: true
except:
- CI-CD
sonarqube:
image: nuga99/sonar-scanner-python
stage: sonarqube
cache:
key: sonarqube
paths:
- .cache/pip
before_script:
- python3 -V
- pip3 install -r requirements.txt
- echo "DJANGO_SECRET_KEY=$DJANGO_SECRET_KEY" > sip/settings/.env
- echo "AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID" >> sip/settings/.env
- echo "AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY" >> sip/settings/.env
- echo "AWS_STORAGE_BUCKET_NAME=$AWS_STORAGE_BUCKET_NAME" >> sip/settings/.env
script:
- if [[ $CI_COMMIT_REF_NAME == staging ]]; then ENVIRON="sip.settings.staging"; else ENVIRON="sip.settings.dev"; fi
- coverage run --omit='manage.py,**/venv/*,**/python3*/**,core/**,laporan_praktikum/error_message/**,laporan_praktikum/custom_module/**,authentication/cas_wrapper.py,/usr/**' manage.py test --settings=${ENVIRON}
- coverage report -m
- coverage xml -i
- sonar-scanner
-Dsonar.host.url=https://pmpl.cs.ui.ac.id/sonarqube
-Dsonar.projectKey=$SONARQUBE_PROJECT_KEY
-Dsonar.login=$SONARQUBE_TOKEN
-Dsonar.branch.name=$CI_COMMIT_REF_NAME
only:
- master
- staging
- development
- /^.*PBI-.*$/
heroku-deploy:
image: ruby:2.4
stage: deploy
......
......@@ -42,7 +42,10 @@ POSTGRES_DB=postgres_db_name
```
### __How To Run on Local Development__
1. Buat .env di folder sip/settings/ dengan secret key-nya
1. Buat .env di folder sip/settings/ dengan secret key-nya. Tambahin line ini di file-nya:
```bash
DJANGO_SECRET_KEY="s3cr3t_k3y_c4nn0t_h4ck3d_by_l33t_1337"
```
2. Lakukan makemigrations dan migrate
```bash
python manage.py makemigrations --settings=sip.settings.dev
......@@ -54,5 +57,6 @@ POSTGRES_DB=postgres_db_name
```
### __Pipelines and Coverage__
[![pipeline status](https://gitlab.cs.ui.ac.id/ppl-fasilkom-ui/itproject-2020/group-a/praktikum-backend/badges/staging/pipeline.svg)](https://gitlab.cs.ui.ac.id/ppl-fasilkom-ui/itproject-2020/group-a/praktikum-backend) [![coverage report](https://gitlab.cs.ui.ac.id/ppl-fasilkom-ui/itproject-2020/group-a/praktikum-backend/badges/staging/coverage.svg)](https://gitlab.cs.ui.ac.id/ppl-fasilkom-ui/itproject-2020/group-a/praktikum-backend)
[![pipeline status](https://gitlab.cs.ui.ac.id/ppl-fasilkom-ui/2021/BB/departemen-ilmu-kesejahteraan-sosial-ui-sistem-informasi-penilaian-dan-database-praktikum-i-dan-ii/praktikum-backend/badges/staging/pipeline.svg)](https://gitlab.cs.ui.ac.id/ppl-fasilkom-ui/2021/BB/departemen-ilmu-kesejahteraan-sosial-ui-sistem-informasi-penilaian-dan-database-praktikum-i-dan-ii/praktikum-backend/commits/staging/)
[![coverage report](https://gitlab.cs.ui.ac.id/ppl-fasilkom-ui/2021/BB/departemen-ilmu-kesejahteraan-sosial-ui-sistem-informasi-penilaian-dan-database-praktikum-i-dan-ii/praktikum-backend/badges/staging/coverage.svg)](https://gitlab.cs.ui.ac.id/ppl-fasilkom-ui/2021/BB/departemen-ilmu-kesejahteraan-sosial-ui-sistem-informasi-penilaian-dan-database-praktikum-i-dan-ii/praktikum-backend/commits/staging/)
#
# Automated API request
#
# Python version : >= 3
#
# Tutorial : Gw ga make teori-teori segala kayak clean code, maklumin kalo kode-nya jelek. Ini contoh basic cara make toolnya:
#
# 1. Jalanin "python api_tester.py default"
# 2. Login dengan masukin username, password, sama role
# 3. kasih api yang mau dipake habis selesai login, contoh /auth/profile/mahasiwa (Kalo login jadi mahasiswa)
# 4. Masukin data yang perlu make json, kalo ga perlu data pas request ke api-nya, teken enter aja
# 5. Liat response-nya
# 6. Kalo mau keluar dari programnya, teken CTRL-C aja
#
# Note yang penting : urllib.request setau gw cuman bisa nebak method GET sama POST buat http kalo ga dispecify tipe requestnya, kalo make method lain kayak PUT buat upload file nanti gw bikin socket manual buat itu.
#
import sys
import json
import getpass
import urllib.request
invalid_login_flag = True
def banner():
print("")
print(" (`\ .-') /` ('-. _ (`-. ('-. _ (`-. _ (`-. ")
print(" `.( OO ),' ( OO ).-. ( (OO ) _( OO) ( (OO ) ( (OO ) ")
print(" ,----. ,--./ .--. .-----. / . --. /_.` \(,------. _.` \ _.` \ ,--. ")
print(" ' .-./-') | | | ' .--./ | \-. \(__...--'' | .---' (__...--''(__...--'' | |.-') ")
print(" | |_( O- )| | | |, | |('-..-'-' | || / | | | | | / | | | / | | | | OO ) ")
print(" | | .--, \| |.'.| |_) /_) |OO )\| |_.' || |_.' |(| '--. | |_.' | | |_.' | | |`-' | ")
print("(| | '. (_/| | || |`-'| | .-. || .___.' | .--' | .___.' | .___.'(| '---.' ")
print(" | '--' | | ,'. | (_' '--'\ | | | || | | `---. | | | | | | ")
print(" `------' '--' '--' `-----' `--' `--'`--' `------' `--' `--' `------' ")
print("")
def list_command():
print("[*] List command yang tersedia (buat sesi awal doang) : ")
print("\tapi , langsung akses api tanpa login")
print("\tbanner , buat nge-print banner")
print("\tcommands , buat buka tulisan list command ini")
print("\tlogin , biar login dulu baru langsung akses api\n")
def api_req(api_obj):
global invalid_login_flag
while True:
print("[NOTE] Pastiin awalan alamat api-nya pake '/' (ex: /api/v1/mahasiswa)")
api = input("api_tester.py >> Alamat API (kalo mau keluar dari sesi api masukin 'exit', kalo mau liat tokennya masukin 'token') : ")
if api == "exit":
if invalid_login_flag == False:
invalid_login_flag = True
break
if invalid_login_flag:
break
elif api == "token":
try:
print("Token : " + api_obj.get_token() + "\n")
except:
print("[-] Tidak ada token\n")
elif api == "banner":
banner()
else:
api_obj.set_api(api)
print("Berikut bakal nanya data, kalo api-nya gaperlu data teken enter aja\n")
data_json = input("api_tester.py >> Data (dalem bentuk json) : ")
api_obj.set_data(data_json)
api_obj.request()
return
class APITester:
def __init__(self, domain):
self.domain = domain
def set_api(self, api):
self.api = api
def set_data(self, data):
self.data = data
def get_token(self):
return self.token
def login(self):
global invalid_login_flag
tipe_ = int(input("[*] Tipe akun (1 buat SSO, 2 buat django admin) : "))
if tipe_ == 1:
self.api = "/auth/login/sso/"
elif tipe_ == 2:
self.api = "/auth/login/supervisor-lembaga/"
else:
print("[*] Tipe akun invalid")
return
username = input("[*] Username : ")
passwd = input("[*] Password (tidak ke-echo, pastiin passwordnya bener) : ")
role = int(input("[*] Role ( 1 untuk Mahasiswa, 2 untuk Spv Sekolah, 3 untuk Koor Kuliah, 4 untuk Spv Lembaga, 5 untuk Admin) : "))
if role == 1:
self.data = "{\"username\":\""+username.replace("\"", "\\\"")+"\",\"password\":\""+passwd.replace("\"", "\\\"")+"\",\"role\":\"Mahasiswa\"}"
elif role == 2:
self.data = "{\"username\":\""+username.replace("\"", "\\\"")+"\",\"password\":\""+passwd.replace("\"", "\\\"")+"\",\"role\":\"Supervisor Sekolah\"}"
elif role == 3:
self.data = "{\"username\":\""+username.replace("\"", "\\\"")+"\",\"password\":\""+passwd.replace("\"", "\\\"")+"\",\"role\":\"Koordinator Kuliah\"}"
elif role == 4:
self.data = "{\"username\":\""+username.replace("\"", "\\\"")+"\",\"password\":\""+passwd.replace("\"", "\\\"")+"\",\"role\":\"Supervisor Lembaga\"}"
elif role == 5:
self.data = "{\"username\":\""+username.replace("\"", "\\\"")+"\",\"password\":\""+passwd.replace("\"", "\\\"")+"\",\"role\":\"Administrator\"}"
else:
print("[-] Role tidak valid")
print("[-] Mohon coba lagi dari awal")
return False
# Request ke API-nya
header = {
"User-Agent" : "Mozilla/5.0",
"Accept" : "*/*",
"Accept-Encoding" : "text/plain,application/json",
"Content-Type" : "application/json",
"Content-Length" : str(len(self.data)),
}
req = urllib.request.Request(self.domain+self.api, self.data.encode("ascii"), header)
try:
res = urllib.request.urlopen(req)
resData = res.read().decode("ascii")
apiRes = json.loads(resData)
self.token = apiRes["token"]
print("[+] Login berhasil")
print("[+] Token : " + str(self.token)[:15] + "...\n")
invalid_login_flag = False
return True
except urllib.error.HTTPError:
print("[-] Gagal Login")
print("[*] Mohon coba lagi")
return False
def request(self):
print("[*] Mengirim request ke " + self.api)
header = {
"User-Agent" : "Mozilla/5.0",
"Accept" : "*/*",
"Accept-Encoding" : "text/plain,application/json",
"Content-Type" : "application/json",
"Content-Length" : str(len(self.data)),
}
try:
if self.token:
header["Authorization"] = "Bearer "+self.token
except:
print("[*] Tidak ada token")
if self.data == "":
req = urllib.request.Request(self.domain+self.api, headers=header)
else:
req = urllib.request.Request(self.domain+self.api, self.data.encode("ascii"), header)
try:
res = urllib.request.urlopen(req)
resData = res.read().decode("ascii")
apiRes = json.loads(resData)
print("\n+ - Response - +\n\n" + str(apiRes) + "\n\n+ - Response - +\n")
except urllib.error.HTTPError as e:
if "404" in str(e):
print("[-] API tidak ditemukan")
else:
print("[-] Terjadi suatu kesalahan")
print(str(e)+"\n")
if __name__ == "__main__":
if len(sys.argv) < 2:
banner()
print("[Cara make] python api_tester.py (domain)")
print("[Catatan] Kasih 'default' di bagian 'domain' buat konek ke ppl-berkah-backend.herokuapp.com")
else:
try:
if sys.argv[1] == "default":
domain = "https://ppl-berkah-backend.herokuapp.com"
else:
domain = sys.argv[1]
banner()
list_command()
api_obj = APITester(domain)
while True:
cmd = input(sys.argv[0]+" > ")
if cmd == "login":
print("[*] Login terlebih dahulu")
while invalid_login_flag:
result = api_obj.login()
if result:
api_req(api_obj)
print("[*] Sesi login selesai\n")
break
elif cmd == "api":
api_req(api_obj)
elif cmd == "banner":
banner()
elif cmd == "commands":
list_command()
elif cmd == "exit":
sys.exit()
else:
print("[-] Command invalid\n")
except KeyboardInterrupt:
print("\n\n[-] CTRL-C keteken\n")
sys.exit()
\ No newline at end of file
......@@ -12,7 +12,6 @@ from lembaga.models import (
Institusi,
Tema,
Lembaga,
LingkupKerja,
)
from .serializers import (
UserSerializer,
......@@ -108,11 +107,6 @@ class ModelsTest(TestCase):
tema = Tema.objects.create(
nama="testing"
)
lingkup_kerja = LingkupKerja.objects.create(
nama="testing"
)
self.lembaga = Lembaga.objects.create(
nama="testing",
jenis_pelayanan="testing",
......@@ -124,7 +118,6 @@ class ModelsTest(TestCase):
beneficaries="test_beneficaries"
)
self.lembaga.lingkup_kerja.add(lingkup_kerja)
self.lembaga.gambar = self.get_image_file()
self.lembaga.save()
......@@ -300,10 +293,6 @@ class SerializersTest(TestCase):
nama="testing"
)
lingkup_kerja = LingkupKerja.objects.create(
nama="testing"
)
self.lembaga = Lembaga.objects.create(
nama="testing",
jenis_pelayanan="testing",
......@@ -315,7 +304,6 @@ class SerializersTest(TestCase):
alamat="test_alamat"
)
self.lembaga.lingkup_kerja.add(lingkup_kerja)
self.lembaga.gambar = self.get_image_file()
self.lembaga.save()
......@@ -557,17 +545,11 @@ class SSOUITest(TestCase):
supervisor_sekolah=None
)
def test_login_url_exists(self):
"""Test if login url exists and redirects to CAS server (response code 302)."""
response = self.client.get(reverse('authentication:login-sivitas'))
self.assertEqual(response.status_code, 302)
self.assertTrue(response.url.startswith(settings.CAS_SERVER_URL))
def test_logout_url_exists(self):
"""Test if logout url exists and redirects to CAS server (response code 302)."""
response = self.client.get(reverse('authentication:logout'))
self.assertEqual(response.status_code, 302)
self.assertTrue(response.url.startswith(settings.CAS_SERVER_URL))
# def test_login_url_exists(self):
# """Test if login url exists and redirects to CAS server (response code 302)."""
# response = self.client.get(reverse('authentication:login-sivitas'))
# self.assertEqual(response.status_code, 302)
# self.assertTrue(response.url.startswith(settings.CAS_SERVER_URL))
# def test_profile_can_save_attributes_if_user_mahasiswa_not_yet_registered(self):
# """Test if Profile Mahasiswa model can save the attributes from CAS."""
......@@ -726,10 +708,6 @@ class AuthenticationJSONWebTokenTest(APITestCase):
nama="testing"
)
lingkup_kerja = LingkupKerja.objects.create(
nama="testing"
)
self.lembaga = Lembaga.objects.create(
nama="testing",
jenis_pelayanan="testing",
......@@ -741,7 +719,6 @@ class AuthenticationJSONWebTokenTest(APITestCase):
alamat="test_alamat"
)
self.lembaga.lingkup_kerja.add(lingkup_kerja)
self.lembaga.gambar = self.get_image_file()
self.lembaga.save()
......
......@@ -5,7 +5,8 @@ from django.urls import include, path
app_name = 'authentication'
urlpatterns = [
path('login/sivitas/', APILoginView.as_view(), name='login-sivitas'),
path('logout/', APILogoutView.as_view(), name='logout'),
# path('logout/', APILogoutView.as_view(), name='logout'),
path('logout/', views.ManualLogoutView.as_view(), name='logout'),
path('register/supervisor-lembaga/', views.UserRegistrationView.as_view(), name='register-supervisor-lembaga'),
path('login/supervisor-lembaga/', views.UserLoginView.as_view(), name='login-supervisor-lembaga'),
path('register/supervisor-lembaga/', views.UserRegistrationView.as_view(), name='register-supervisor-lembaga'),
......@@ -19,5 +20,5 @@ urlpatterns = [
path('profile/administrator', views.UserProfileAdministratorView.as_view(), name='profile-administrator'),
path('profile/user', views.UserProfileUserView.as_view(), name='profile-user'),
path('periode/list', views.PeriodeListView.as_view(), name='periode-list'),
path('login/sso/', views.ManualSSOLoginView.as_view(), name='login-sso')
path('login/sso/', views.ManualSSOLoginView.as_view(), name='login-sso'),
]
......@@ -21,8 +21,10 @@ from .serializers import (
AdministratorLoginSerializer
)
from .role import Role
from datetime import datetime
from django.contrib.auth.decorators import login_required
from django.http import JsonResponse
from django.http import JsonResponse, HttpResponseRedirect
from django.contrib.auth.models import update_last_login
from django.shortcuts import render
from rest_framework import status
from rest_framework.decorators import api_view
......@@ -105,6 +107,14 @@ class ManualSSOLoginView(RetrieveAPIView):
return Response(response, status=status.HTTP_200_OK)
class ManualLogoutView(RetrieveAPIView):
permission_classes = (AllowAny,)
def get(self, request):
update_last_login(datetime.now(), request.user)
return HttpResponseRedirect("http://ppl-berkah.herokuapp.com/")
class UserProfileMahasiswaView(RetrieveAPIView): # pragma: no cover
permission_classes = (IsAuthenticated,)
......
This diff is collapsed.
from django.db import models
from lembaga.models import Lembaga, LingkupKerja
from lembaga.models import Lembaga
from authentication.models import Administrator, KoordinatorKuliah, Mahasiswa, \
SupervisorLembaga, SupervisorSekolah
from django.core.files.storage import FileSystemStorage
......
from laporan_praktikum.models import Praktikum, KelolaLaporanPraktikum, MahasiswaPraktikum
from authentication.models import Mahasiswa, SupervisorLembaga, SupervisorSekolah, User, Periode
from lembaga.models import Lembaga, Tema, Institusi, LingkupKerja
from lembaga.models import Lembaga, Tema, Institusi
from django.test import TestCase
from django.core.files import File
from io import BytesIO
......@@ -91,8 +91,6 @@ class SupervisorSekolahDashboardAPITest(APITestCase):
Institusi
), tema=mixer.blend(
Tema
), lingkup_kerja=mixer.blend(
LingkupKerja
), gambar=self.get_image_file()
), user=mixer.blend(User)
)
......
......@@ -15,7 +15,7 @@ from laporan_praktikum.models import (
from laporan_praktikum.serializers import (
RiwayatLaporanPraktikumMahasiswaSerializer
)
from lembaga.models import Lembaga, Tema, Institusi, LingkupKerja
from lembaga.models import Lembaga, Tema, Institusi
from laporan_praktikum.models import LaporanAkhirPraktikum
from django.test import TestCase
......@@ -365,8 +365,6 @@ class PeriodeAPITest(APITestCase):
Institusi
), tema=mixer.blend(
Tema
), lingkup_kerja=mixer.blend(
LingkupKerja
), gambar=self.get_image_file()
), user=mixer.blend(
User
......@@ -487,8 +485,6 @@ class KoordinatorKuliahDashboardAPITest(APITestCase):
Institusi
), tema=mixer.blend(
Tema
), lingkup_kerja=mixer.blend(
LingkupKerja
), gambar=self.get_image_file()
), user=mixer.blend(
User
......@@ -859,9 +855,7 @@ class AdministratorDashboardAPITest(APITestCase):
Institusi
), tema=mixer.blend(
Tema
), lingkup_kerja=mixer.blend(
LingkupKerja
)
),
), user=mixer.blend(
User,
username="username2",
......
......@@ -214,6 +214,14 @@ def get_list_laporan_praktikum_detail(request):
response_field[1]: status_code,
response_field[2]: error_message_404_praktikum
}
except TemplateBorangPenilaianPraktikum.DoesNotExist:
status_code = status.HTTP_404_NOT_FOUND
response = {
response_field[0]: 'False',
response_field[1]: status_code,
response_field[2]: "Your Supervisor Sekolah hasn't been uploaded the Template Borang"
}
return Response(response, status=status_code)
......
......@@ -5,4 +5,4 @@ from lembaga import models
admin.site.register(models.Lembaga)
admin.site.register(models.Institusi)
admin.site.register(models.Tema)
admin.site.register(models.LingkupKerja)
admin.site.register(models.ErrorMessage)
......@@ -20,13 +20,6 @@ class Migration(migrations.Migration):
('nama', models.CharField(max_length=255)),
],
),
migrations.CreateModel(
name='LingkupKerja',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('nama', models.CharField(max_length=255)),
],
),
migrations.CreateModel(
name='Tema',
fields=[
......@@ -46,7 +39,6 @@ class Migration(migrations.Migration):
('alamat', models.CharField(max_length=1024)),
('praktikum_ke', models.IntegerField()),
('institusi', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='lembaga.Institusi')),
('lingkup_kerja', models.ManyToManyField(related_name='lembaga', to='lembaga.LingkupKerja')),
('tema', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='lembaga.Tema')),
],
),
......
......@@ -15,11 +15,6 @@ class Migration(migrations.Migration):
name='nama',
field=models.CharField(max_length=255, unique=True),
),
migrations.AlterField(
model_name='lingkupkerja',
name='nama',
field=models.CharField(max_length=255, unique=True),
),
migrations.AlterField(
model_name='tema',
name='nama',
......
# Generated by Django 3.1.3 on 2021-03-25 10:31
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('lembaga', '0004_auto_20201105_2133'),
]
operations = [
migrations.CreateModel(
name='ErrorMessage',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
],
),
]
# Generated by Django 3.1.3 on 2021-04-25 22:25
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('lembaga', '0005_errormessage'),
]
......@@ -20,14 +20,6 @@ class Tema(models.Model):
return self.nama
class LingkupKerja(models.Model):
""" Models for Lingkup Kerja """
nama = models.CharField(max_length=255, unique=True)
def __str__(self):
return self.nama
def upload_location(instance, filename):
_, extension = filename.split('.')
return '%s.%s' % (instance.nama, extension)
......@@ -36,7 +28,6 @@ def upload_location(instance, filename):
class Lembaga(models.Model):
""" Models for Lembaga """
nama = models.CharField(max_length=255)
lingkup_kerja = models.ManyToManyField(LingkupKerja, related_name="lembaga")
jenis_pelayanan = models.CharField(max_length=255)
institusi = models.ForeignKey(Institusi, on_delete=models.CASCADE)
tema = models.ForeignKey(Tema, on_delete=models.CASCADE)
......@@ -47,3 +38,9 @@ class Lembaga(models.Model):
def __str__(self):
return self.nama
class ErrorMessage(models.Model):
""" Models for Error Messages """