Merge branch 'development' of github.com:Rushilwiz/SkoolOS into development

This commit is contained in:
Nathaniel Kenschaft 2020-06-14 13:11:33 -04:00
commit 0492f17d17
34 changed files with 367 additions and 198 deletions

View File

@ -1 +0,0 @@
{'absences': 2, 'address': None, 'counselor': {'first_name': 'Sean', 'full_name': 'Sean Burke', 'id': 37, 'last_name': 'Burke', 'url': 'https://ion.tjhsst.edu/api/profile/37', 'user_type': 'counselor', 'username': 'SPBurke'}, 'display_name': 'Raffu Khondaker', 'emails': [], 'first_name': 'Raffu', 'full_name': 'Raffu Khondaker', 'grade': {'name': 'sophomore', 'number': 10}, 'graduation_year': 2022, 'id': 36508, 'ion_username': '2022rkhondak', 'is_announcements_admin': False, 'is_eighth_admin': False, 'is_student': True, 'is_teacher': False, 'last_name': 'Khondaker', 'middle_name': 'Al', 'nickname': '', 'phones': [], 'picture': 'https://ion.tjhsst.edu/api/profile/36508/picture', 'sex': 'Male', 'short_name': 'Raffu', 'title': None, 'tj_email': '2022rkhondak@tjhsst.edu', 'user_type': 'student', 'websites': []}

View File

@ -14,7 +14,7 @@
</head> </head>
<body> <body>
<div class="d-flex align-items-center justify-content-center" style="height: 100vh"> <div class="d-flex align-items-center justify-content-center" style="height: 100vh">
<a href="https://ion.tjhsst.edu/oauth/authorize/?response_type=code&client_id=QeZPBSKqdvWFfBv1VYTSv9iFGz5T9pVJtNUjbEr6&redirect_uri=http%3A%2F%2Flocalhost%3A8000%2F&scope=read&state=81xYFv6S9CLi7laXQ64gJWskDJUMMb" title="Ion" class="border border-dark p-3 btn btn-lg mx-auto" style="box-shadow: 5px 10px;"> <a href="https://ion.tjhsst.edu/oauth/authorize/?response_type=code&client_id=QeZPBSKqdvWFfBv1VYTSv9iFGz5T9pVJtNUjbEr6&redirect_uri=http%3A%2F%2Flocalhost%3A8000%2F&scope=read&state=YXN4dnhwLXE7gx6Xq0vwPdvr3z0YSn" title="Ion" class="border border-dark p-3 btn btn-lg mx-auto" style="box-shadow: 5px 10px;">
<img src="https://ion.tjhsst.edu/static/img/favicon.png"> <img src="https://ion.tjhsst.edu/static/img/favicon.png">
Sign in with Ion Sign in with Ion
</a> </a>

View File

@ -52,7 +52,7 @@ def authenticate():
path = os.path.join(cdir, "chromedriver-mac") path = os.path.join(cdir, "chromedriver-mac")
print(path) print(path)
browser = webdriver.Chrome(path) browser = webdriver.Chrome(path)
browser = webdriver.Safari() #browser = webdriver.Safari()
web_dir = os.path.join(os.path.dirname(__file__), 'oauth') web_dir = os.path.join(os.path.dirname(__file__), 'oauth')
os.chdir(web_dir) os.chdir(web_dir)

View File

@ -1,4 +1,4 @@
# Generated by Django 3.0.7 on 2020-06-12 23:18 # Generated by Django 3.0.7 on 2020-06-13 18:15
from django.conf import settings from django.conf import settings
from django.db import migrations, models from django.db import migrations, models

View File

@ -64,9 +64,6 @@ class Student(models.Model):
classes=models.CharField(max_length=100, default="", blank=True) classes=models.CharField(max_length=100, default="", blank=True)
added_to=models.CharField(max_length=100, default="", blank=True) added_to=models.CharField(max_length=100, default="", blank=True)
completed=models.TextField(default="", blank=True) completed=models.TextField(default="", blank=True)
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
return super(Student, self).save(*args, **kwargs) return super(Student, self).save(*args, **kwargs)

View File

@ -13,7 +13,7 @@ class IsOwnerOrReadOnly(permissions.BasePermission):
return True return True
# Write permissions are only allowed to the owner of the snippet. # Write permissions are only allowed to the owner of the snippet.
return obj.owner == request.user return obj.owner == request.user or request.user.is_superuser
class isTeacher(permissions.BasePermission): class isTeacher(permissions.BasePermission):
#only teachers can make classes and assignmenst #only teachers can make classes and assignmenst
@ -22,4 +22,4 @@ class isTeacher(permissions.BasePermission):
return True return True
# Write permissions are only allowed to the owner of the snippet. # Write permissions are only allowed to the owner of the snippet.
return obj.user.groups.filter(name__in=['teachers']).exists() return request.user.groups.filter(name__in=['teachers']).exists() or request.user.is_superuser

View File

@ -2,15 +2,15 @@ from django.contrib.auth.models import User, Group
from .models import Student, Teacher, Classes, Assignment, DefFiles from .models import Student, Teacher, Classes, Assignment, DefFiles
from rest_framework import serializers, permissions from rest_framework import serializers, permissions
from django.contrib.auth.models import User from django.contrib.auth.models import User
from .permissions import IsOwnerOrReadOnly,isTeacher
class UserSerializer(serializers.HyperlinkedModelSerializer): class UserSerializer(serializers.HyperlinkedModelSerializer):
students = serializers.PrimaryKeyRelatedField(many=True, queryset=Student.objects.all()) students = serializers.PrimaryKeyRelatedField(many=True, queryset=Student.objects.all())
owner = serializers.ReadOnlyField(source='owner.username') teachers = serializers.PrimaryKeyRelatedField(many=True, queryset=Teacher.objects.all())
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
class Meta: class Meta:
model = User model = User
fields = ['id', 'username', 'students'] fields = ['id', 'username', 'students','teachers']
# class DefFilesSerializer(serializers.HyperlinkedModelSerializer): # class DefFilesSerializer(serializers.HyperlinkedModelSerializer):
# class Meta: # class Meta:
@ -20,37 +20,36 @@ class UserSerializer(serializers.HyperlinkedModelSerializer):
class AssignmentSerializer(serializers.HyperlinkedModelSerializer): class AssignmentSerializer(serializers.HyperlinkedModelSerializer):
#permissions_classes = [permissions.IsAuthenticatedOrReadOnly] #permissions_classes = [permissions.IsAuthenticatedOrReadOnly]
# files = DefFilesSerializer(many=True, read_only=True,allow_null=True) # files = DefFilesSerializer(many=True, read_only=True,allow_null=True)
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
owner = serializers.ReadOnlyField(source='owner.username') owner = serializers.ReadOnlyField(source='owner.username')
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
class Meta: class Meta:
model = Assignment model = Assignment
fields = ['url','name', 'due_date', 'path' , "classes","teacher",'owner'] # fields = ['url','name', 'due_date', 'path' , "classes","teacher",'owner']
fields = ['name', 'due_date', 'path' , "classes","teacher",'owner']
class ClassesSerializer(serializers.HyperlinkedModelSerializer): class ClassesSerializer(serializers.HyperlinkedModelSerializer):
# assignments = AssignmentSerializer(many=True, read_only=True,allow_null=True) # assignments = AssignmentSerializer(many=True, read_only=True,allow_null=True)
# default_file=DefFilesSerializer(many=True, read_only=True,allow_null=True) # default_file=DefFilesSerializer(many=True, read_only=True,allow_null=True)
owner = serializers.ReadOnlyField(source='owner.username') owner = serializers.ReadOnlyField(source='owner.username')
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
class Meta: class Meta:
model = Classes model = Classes
fields = ['url', 'name', 'repo','path', "teacher",'assignments',"default_file", 'confirmed', 'unconfirmed','owner'] # fields = ['url','name', 'repo','path', "teacher",'assignments',"default_file", 'confirmed', 'unconfirmed','owner']
fields = ['name', 'repo','path', "teacher",'assignments',"default_file", 'confirmed', 'unconfirmed','owner']
class StudentSerializer(serializers.HyperlinkedModelSerializer): class StudentSerializer(serializers.HyperlinkedModelSerializer):
# classes = ClassesSerializer(many=True, read_only=True,allow_null=True) # classes = ClassesSerializer(many=True, read_only=True,allow_null=True)
owner = serializers.ReadOnlyField(source='owner.username') owner = serializers.ReadOnlyField(source='owner.username')
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
class Meta: class Meta:
model = Student model = Student
fields = ['url', 'first_name', 'last_name', 'grade','email','student_id', 'git','ion_user','classes','added_to','completed', 'repo','owner'] # fields = ['url','first_name', 'last_name', 'grade','email','student_id', 'git','ion_user','classes','added_to','completed', 'repo','owner']
fields = ['first_name', 'last_name', 'grade','email','student_id', 'git','ion_user','classes','added_to','completed', 'repo','owner']
class TeacherSerializer(serializers.ModelSerializer): class TeacherSerializer(serializers.ModelSerializer):
# classes = ClassesSerializer(many=True, read_only=True,allow_null=True) # classes = ClassesSerializer(many=True, read_only=True,allow_null=True)
owner = serializers.ReadOnlyField(source='owner.username') owner = serializers.ReadOnlyField(source='owner.username')
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
class Meta: class Meta:
model = Teacher model = Teacher
fields = ['url', 'first_name', 'last_name','git','ion_user', 'email','classes','owner'] # fields = ['url','first_name', 'last_name','git','ion_user', 'email','classes','owner']
fields = ['first_name', 'last_name','git','ion_user', 'email','classes','owner']

View File

@ -0,0 +1,16 @@
from django.urls import path
from rest_framework.urlpatterns import format_suffix_patterns
from . import views
urlpatterns = [
path('students/', views.StudentList.as_view()),
path('students/<str:pk>/', views.StudentDetail.as_view()),
path('teachers/', views.TeacherList.as_view()),
path('teachers/<str:pk>/', views.TeacherDetail.as_view()),
path('assignments/', views.AssignmentList.as_view()),
path('assignments/<str:pk>/', views.AssignmentDetail.as_view()),
path('classes/', views.ClassesList.as_view()),
path('classes/<str:pk>/', views.ClassesDetail.as_view()),
]
urlpatterns = format_suffix_patterns(urlpatterns)

View File

@ -1,131 +1,89 @@
# class StudentList(APIView): from .models import Student, Teacher, Classes, Assignment, DefFiles
# """ from .serializers import StudentSerializer, TeacherSerializer, ClassesSerializer, AssignmentSerializer, UserSerializer
# List all snippets, or create a new snippet. from rest_framework import generics, viewsets, permissions, response, status
# """ from django.http import Http404
# def get(self, request, format=None): from rest_framework.views import APIView
# snippets = Student.objects.all() from django.contrib.auth.models import User
# serializer = StudentSerializer(snippets, many=True) from .permissions import isTeacher, IsOwnerOrReadOnly
# return response.Response(serializer.data) from django.shortcuts import render, redirect
from rest_framework.parsers import JSONParser
from django.http.response import JsonResponse
from rest_framework.response import Response
from rest_framework import mixins
# def post(self, request, format=None):
# serializer = StudentSerializer(data=request.data)
# if serializer.is_valid():
# serializer.save()
# return response.Response(serializer.data, status=status.HTTP_201_CREATED)
# return response.Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
# class StudentDetail(APIView): class StudentList(generics.ListCreateAPIView):
# """ queryset = Student.objects.all()
# Retrieve, update or delete a snippet instance. serializer_class = StudentSerializer
# """ def perform_create(self, serializer):
# def get_object(self, pk): serializer.save(owner=self.request.user)
# try:
# return Student.objects.get(pk=pk)
# except Student.DoesNotExist:
# raise Http404
# def get(self, request, pk, format=None): class StudentDetail(generics.RetrieveAPIView):
# snippet = self.get_object(pk) queryset = Student.objects.all()
# serializer = StudentSerializer(snippet) serializer_class = StudentSerializer
# return response.Response(serializer.data) permissions_classes = [permissions.IsAuthenticated, IsOwnerOrReadOnly]
# def put(self, request, pk, format=None): class TeacherList(generics.ListCreateAPIView):
# snippet = self.get_object(pk) queryset = Teacher.objects.all()
# serializer = StudentSerializer(snippet, data=request.data) serializer_class = TeacherSerializer
# if serializer.is_valid(): def perform_create(self, serializer):
# serializer.save() if(self.request.user.groups.filter(name__in=['teachers']).exists() or self.request.user.is_superuser):
# return response.Response(serializer.data) serializer.save(owner=self.request.user)
# return response.Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) else:
print("UNAUTHORIZED POST")
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
# def delete(self, request, pk, format=None): class TeacherDetail(generics.RetrieveAPIView):
# snippet = self.get_object(pk) queryset = Teacher.objects.all()
# snippet.delete() serializer_class = TeacherSerializer
# return response.Response(status=status.HTTP_204_NO_CONTENT) permissions_classes = [permissions.IsAuthenticated, IsOwnerOrReadOnly]
# class TeacherList(APIView):
# """
# List all snippets, or create a new snippet.
# """
# def get(self, request, format=None):
# snippets = Teacher.objects.all()
# serializer = TeacherSerializer(snippets, many=True)
# return response.Response(serializer.data)
# def post(self, request, format=None):
# serializer = TeacherSerializer(data=request.data)
# if serializer.is_valid():
# serializer.save()
# return response.Response(serializer.data, status=status.HTTP_201_CREATED)
# return response.Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
# class TeacherDetail(APIView):
# """
# Retrieve, update or delete a snippet instance.
# """
# def get_object(self, pk):
# try:
# return Teacher.objects.get(pk=pk)
# except Teacher.DoesNotExist:
# raise Http404
# def get(self, request, pk, format=None):
# snippet = self.get_object(pk)
# serializer = TeacherSerializer(snippet)
# return response.Response(serializer.data)
# def put(self, request, pk, format=None):
# snippet = self.get_object(pk)
# serializer = TeacherSerializer(snippet, data=request.data)
# if serializer.is_valid():
# serializer.save()
# return response.Response(serializer.data)
# return response.Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
# def delete(self, request, pk, format=None):
# snippet = self.get_object(pk)
# snippet.delete()
# return response.Response(status=status.HTTP_204_NO_CONTENT)
# class ClassesList(APIView): class ClassesList(generics.ListCreateAPIView):
# """ queryset = Classes.objects.all()
# List all snippets, or create a new snippet. serializer_class = ClassesSerializer
# """ #permissions_classes = [isTeacher]
# def get(self, request, format=None): def perform_create(self, serializer):
# snippets = Classes.objects.all() if(self.request.user.groups.filter(name__in=['teachers']).exists() or self.request.user.is_superuser):
# serializer = ClassesSerializer(snippets, many=True) serializer.save(owner=self.request.user)
# return response.Response(serializer.data) else:
print("UNAUTHORIZED POST")
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
# def post(self, request, format=None): # class ClassesDetail(generics.RetrieveAPIView):
# serializer = ClassesSerializer(data=request.data) # queryset = Classes.objects.all()
# if serializer.is_valid(): # serializer_class = ClassesSerializer
# serializer.save() # # permissions_classes = [permissions.IsAuthenticated, IsOwnerOrReadOnly]
# return response.Response(serializer.data, status=status.HTTP_201_CREATED)
# return response.Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
# class ClassesDetail(APIView): class ClassesDetail(mixins.RetrieveModelMixin,
# """ mixins.UpdateModelMixin,
# Retrieve, update or delete a snippet instance. mixins.DestroyModelMixin,
# """ generics.GenericAPIView):
# def get_object(self, pk): queryset = Classes.objects.all()
# try: serializer_class = ClassesSerializer
# return Classes.objects.get(pk=pk)
# except Classes.DoesNotExist:
# raise Http404
# def get(self, request, pk, format=None): def get(self, request, *args, **kwargs):
# snippet = self.get_object(pk) return self.retrieve(request, *args, **kwargs)
# serializer = ClassesSerializer(snippet)
# return response.Response(serializer.data)
# def put(self, request, pk, format=None): def put(self, request, *args, **kwargs):
# snippet = self.get_object(pk) print(self.owner)
# serializer = ClassesSerializer(snippet, data=request.data) if(request.user == self.owner):
# if serializer.is_valid(): return self.update(request, *args, **kwargs)
# serializer.save()
# return response.Response(serializer.data)
# return response.Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
# def delete(self, request, pk, format=None): def delete(self, request, *args, **kwargs):
# snippet = self.get_object(pk) return self.destroy(request, *args, **kwargs)
# snippet.delete()
# return response.Response(status=status.HTTP_204_NO_CONTENT) class AssignmentList(generics.ListCreateAPIView):
queryset = Assignment.objects.all()
serializer_class = AssignmentSerializer
def perform_create(self, serializer):
if(self.request.user.groups.filter(name__in=['teachers']).exists() or self.request.user.is_superuser):
serializer.save(owner=self.request.user)
else:
print("UNAUTHORIZED POST")
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class AssignmentDetail(generics.RetrieveAPIView):
queryset = Assignment.objects.all()
serializer_class = AssignmentSerializer
permissions_classes = [permissions.IsAuthenticated, IsOwnerOrReadOnly]

View File

@ -4,10 +4,17 @@ from rest_framework import generics, viewsets, permissions, response, status
from django.http import Http404 from django.http import Http404
from rest_framework.views import APIView from rest_framework.views import APIView
from django.contrib.auth.models import User from django.contrib.auth.models import User
from .permissions import isTeacher, IsOwnerOrReadOnly
from django.shortcuts import render, redirect
from rest_framework.parsers import JSONParser
from rest_framework.response import Response
class UserViewSet(viewsets.ModelViewSet): class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all() queryset = User.objects.all()
serializer_class = UserSerializer serializer_class = UserSerializer
permission_classes = [permissions.IsAuthenticated]
class StudentViewSet(viewsets.ModelViewSet): class StudentViewSet(viewsets.ModelViewSet):
@ -16,8 +23,10 @@ class StudentViewSet(viewsets.ModelViewSet):
""" """
queryset = Student.objects.all() queryset = Student.objects.all()
serializer_class = StudentSerializer serializer_class = StudentSerializer
permissions_classes = [permissions.IsAuthenticatedOrReadOnly] permission_classes = [permissions.IsAuthenticated, IsOwnerOrReadOnly]
def perform_create(self, serializer):
serializer.save(owner=self.request.user)
class TeacherViewSet(viewsets.ModelViewSet): class TeacherViewSet(viewsets.ModelViewSet):
""" """
@ -25,8 +34,10 @@ class TeacherViewSet(viewsets.ModelViewSet):
""" """
queryset = Teacher.objects.all() queryset = Teacher.objects.all()
serializer_class = TeacherSerializer serializer_class = TeacherSerializer
permissions_classes = [permissions.IsAuthenticatedOrReadOnly] permission_classes = [permissions.IsAuthenticated, IsOwnerOrReadOnly]
def perform_create(self, serializer):
serializer.save(owner=self.request.user)
class ClassesViewSet(viewsets.ModelViewSet): class ClassesViewSet(viewsets.ModelViewSet):
""" """
@ -34,7 +45,14 @@ class ClassesViewSet(viewsets.ModelViewSet):
""" """
queryset = Classes.objects.all() queryset = Classes.objects.all()
serializer_class = ClassesSerializer serializer_class = ClassesSerializer
permissions_classes = [permissions.IsAuthenticatedOrReadOnly] permission_classes = [permissions.IsAuthenticated, IsOwnerOrReadOnly]
def perform_create(self, serializer):
if(self.request.user.groups.filter(name__in=['teachers']).exists() or self.request.user.is_superuser):
serializer.save(owner=self.request.user)
else:
print("UNAUTHORIZED POST")
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class AssignmentViewSet(viewsets.ModelViewSet): class AssignmentViewSet(viewsets.ModelViewSet):
@ -43,7 +61,14 @@ class AssignmentViewSet(viewsets.ModelViewSet):
""" """
queryset = Assignment.objects.all() queryset = Assignment.objects.all()
serializer_class = AssignmentSerializer serializer_class = AssignmentSerializer
permissions_classes = [permissions.IsAuthenticatedOrReadOnly] permission_classes = [permissions.IsAuthenticated, isTeacher, IsOwnerOrReadOnly]
def perform_create(self, serializer):
if(self.request.user.groups.filter(name__in=['teachers']).exists() or self.request.user.is_superuser):
serializer.save(owner=self.request.user)
else:
print("UNAUTHORIZED POST")
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
# class DefFilesViewSet(viewsets.ModelViewSet): # class DefFilesViewSet(viewsets.ModelViewSet):
# """ # """

View File

@ -11,6 +11,6 @@ import os
from django.core.asgi import get_asgi_application from django.core.asgi import get_asgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'skoolos.settings') os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')
application = get_asgi_application() application = get_asgi_application()

View File

@ -31,6 +31,7 @@ ALLOWED_HOSTS = []
# Application definition # Application definition
INSTALLED_APPS = [ INSTALLED_APPS = [
'skoolos.apps.SkoolosConfig',
'users.apps.UsersConfig', 'users.apps.UsersConfig',
'django.contrib.admin', 'django.contrib.admin',
'django.contrib.auth', 'django.contrib.auth',
@ -41,6 +42,7 @@ INSTALLED_APPS = [
'rest_framework', 'rest_framework',
'api', 'api',
'crispy_forms', 'crispy_forms',
'django_forms_bootstrap',
] ]
@ -63,7 +65,7 @@ MIDDLEWARE = [
'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware',
] ]
ROOT_URLCONF = 'skoolos.urls' ROOT_URLCONF = 'config.urls'
TEMPLATES = [ TEMPLATES = [
{ {
@ -81,7 +83,7 @@ TEMPLATES = [
}, },
] ]
WSGI_APPLICATION = 'skoolos.wsgi.application' WSGI_APPLICATION = 'config.wsgi.application'
# Database # Database
@ -136,3 +138,5 @@ STATIC_URL = '/static/'
CRISPY_TEMPLATE_PACK = 'bootstrap4' CRISPY_TEMPLATE_PACK = 'bootstrap4'
LOGIN_REDIRECT_URL = '/' LOGIN_REDIRECT_URL = '/'
LOGIN_URL = '/login'

31
Website/config/urls.py Normal file
View File

@ -0,0 +1,31 @@
from django.urls import path
from rest_framework import routers
from api import views as api_views
from django.contrib import admin
from django.conf.urls import include
from django.contrib.auth import views as auth_views
router = routers.DefaultRouter()
router.register(r'students', api_views.StudentViewSet)
router.register(r'teachers', api_views.TeacherViewSet)
router.register(r'assignments', api_views.AssignmentViewSet)
router.register(r'classes', api_views.ClassesViewSet)
# router.register(r'files', api_views.DefFilesViewSet)
router.register(r'users', api_views.UserViewSet)
from users import views as user_views
from users.forms import LoginForm
# Wire up our API using automatic URL routing.
# Additionally, we include login URLs for the browsable API.
urlpatterns = [
path('', include('skoolos.urls')),
path('api/', include(router.urls)),
path('api-auth/', include('rest_framework.urls')),
path('admin/', admin.site.urls),
path('login/', auth_views.LoginView.as_view(template_name='users/login.html', authentication_form=LoginForm), name='login'),
path('logout/', user_views.logout, name='logout'),
path('register/', user_views.register, name='register'),
path('create_account/', user_views.create_account, name='create_account'),
path('callback/', user_views.callback, name='callback'),
]

View File

@ -11,6 +11,6 @@ import os
from django.core.wsgi import get_wsgi_application from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'skoolos.settings') os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')
application = get_wsgi_application() application = get_wsgi_application()

View File

@ -5,7 +5,7 @@ import sys
def main(): def main():
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'skoolos.settings') os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')
try: try:
from django.core.management import execute_from_command_line from django.core.management import execute_from_command_line
except ImportError as exc: except ImportError as exc:

3
Website/skoolos/admin.py Normal file
View File

@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

5
Website/skoolos/apps.py Normal file
View File

@ -0,0 +1,5 @@
from django.apps import AppConfig
class SkoolosConfig(AppConfig):
name = 'skoolos'

View File

View File

@ -0,0 +1,3 @@
from django.db import models
# Create your models here.

View File

@ -0,0 +1,26 @@
{% load static %}
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<link rel="stylesheet" type="text/css" href="{% static 'skoolos/styles.css' %}">
<title>SkoolOS</title>
</head>
<body>
{% block content %}{% endblock %}
<!-- Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</body>
</html>

View File

@ -0,0 +1,5 @@
{% extends "skoolos/base.html" %}
{% block content %}
<h1>welcome to skoolos</h1>
<h2>it's the future you've been waiting for</h2>
{% endblock content %}

3
Website/skoolos/tests.py Normal file
View File

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

View File

@ -1,26 +1,6 @@
from django.urls import path from django.urls import path
from rest_framework import routers
from api import views as api_views
from django.contrib import admin
from django.conf.urls import include
from django.contrib.auth import views as auth_views
router = routers.DefaultRouter()
router.register(r'students', api_views.StudentViewSet)
router.register(r'teachers', api_views.TeacherViewSet)
router.register(r'assignments', api_views.AssignmentViewSet)
router.register(r'classes', api_views.ClassesViewSet)
# router.register(r'files', api_views.DefFilesViewSet)
router.register(r'users', api_views.UserViewSet)
# Wire up our API using automatic URL routing.
# Additionally, we include login URLs for the browsable API.
urlpatterns = [ urlpatterns = [
path('api/', include(router.urls)),
path('api-auth/', include('rest_framework.urls')),
path('admin/', admin.site.urls),
path('login/', auth_views.LoginView.as_view(template_name="users/login.html"), name='login'),
path('register/', user_views.register, name='register'),
path('create_account/', user_views.create_account, name='create_account'),
path('callback/', user_views.callback, name='callback'),
] ]

8
Website/skoolos/views.py Normal file
View File

@ -0,0 +1,8 @@
from django.shortcuts import render
from django.contrib.auth.decorators import login_required
# Create your views here.
@login_required()
def home (request):
return render(request, "skoolos/home.html")

View File

@ -1,5 +1,11 @@
from django import forms from django import forms
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.contrib.auth.forms import AuthenticationForm
class LoginForm(AuthenticationForm):
username = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'Username'}))
password = forms.CharField(widget=forms.PasswordInput(attrs={'placeholder':'Password'}))
class UserCreationForm(forms.ModelForm): class UserCreationForm(forms.ModelForm):
@ -7,13 +13,24 @@ class UserCreationForm(forms.ModelForm):
email = forms.EmailField(disabled=True) email = forms.EmailField(disabled=True)
first_name = forms.CharField(disabled=True) first_name = forms.CharField(disabled=True)
last_name = forms.CharField(disabled=True) last_name = forms.CharField(disabled=True)
password = forms.PasswordInput() isStudent = forms.BooleanField(widget = forms.HiddenInput())
confirm_password = forms.PasswordInput() password = forms.CharField(widget=forms.PasswordInput(attrs={'placeholder': 'Password'}))
confirm_password = forms.CharField(widget=forms.PasswordInput(attrs={'placeholder': 'Confirm Password'}))
token = forms.CharField(widget = forms.HiddenInput())
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(UserCreationForm, self).__init__(*args, **kwargs) super(UserCreationForm, self).__init__(*args, **kwargs)
def clean(self):
cleaned_data = super(UserCreationForm, self).clean()
password = cleaned_data.get("password")
confirm_password = cleaned_data.get("confirm_password")
if password != confirm_password:
raise forms.ValidationError("Passwords do not match!")
return cleaned_data
class Meta: class Meta:
model = User model = User
fields = ['username', 'email', 'first_name', 'password', 'confirm_password'] fields = ('username', 'email', 'first_name', 'last_name', 'password')

View File

@ -99,6 +99,10 @@ body {
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
} }
input:disabled {
background: #d9d9d9;
}
.errorlist { .errorlist {
} }

View File

@ -18,7 +18,6 @@
</head> </head>
<body> <body>
{% block content %}{% endblock %} {% block content %}{% endblock %}
a
<!-- Bootstrap JS --> <!-- Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script> <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>

View File

@ -0,0 +1,22 @@
{% extends "users/base.html" %}
{% load bootstrap_tags %}
{% block content %}
<div class="login-page">
<div class="form">
<form class="login-form" method="POST">
{% csrf_token %}
{% for field in form %}
<div class="fieldWrapper">
{{ field.errors }}
{{ field }}
{% if field.help_text %}
<p class="help">{{ field.help_text|safe }}</p>
{% endif %}
</div>
{% endfor %}
<button type="submit">create</button>
</form>
</div>
</div>
{% endblock %}

View File

@ -1,13 +0,0 @@
{% extends "users/base.html" %}
{% block content %}
<div class="login-page">
<div class="form">
<form class="register-form">
<input type="text" placeholder="name"/>
<input type="password" placeholder="password"/>
<input type="text" placeholder="email address"/>
<button>create</button>
</form>
</div>
</div>
{% endblock %}

View File

@ -1,16 +1,38 @@
{% extends "users/base.html" %} {% extends "users/base.html" %}
{% load crispy_forms_tags %} {% load bootstrap_tags %}
{% block content %} {% block content %}
<div class="login-page"> <div class="login-page">
<div class="form"> <div class="form">
<form class="login-form" method="POST"> <form class="login-form" method="POST">
{% csrf_token %} {% csrf_token %}
{{ form | crispy }} {% if messages %}
{% for message in messages %}
<div class="alert alert-{{ message.tags }} alert-dismissible fade show">
{{ message }}
</div>
{% endfor %}
{% endif %}
{% if form.errors %}
{% for field in form %}
{% for error in field.errors %}
<div class="alert alert-danger">
<strong>{{ error|escape }}</strong>
</div>
{% endfor %}
{% endfor %}
{% for error in form.non_field_errors %}
<div class="alert alert-danger">
<strong>{{ error|escape }}</strong>
</div>
{% endfor %}
{% endif %}
{% for field in form %}
{{ field }}
{% endfor %}
<button type="submit">login</button> <button type="submit">login</button>
<p class="message">Not registered? <a href="{% url 'register' %}">Create an account with Ion</a></p> <p class="message">Not registered? <a href="{% url 'register' %}">Create an account with Ion</a></p>
</form> </form>
</div> </div>
</div> </div>
</div>
{% endblock %} {% endblock %}

View File

@ -4,6 +4,13 @@
<div class="login-page"> <div class="login-page">
<div class="form"> <div class="form">
<div class="content-section"> <div class="content-section">
{% if messages %}
{% for message in messages %}
<div class="alert alert-{{ message.tags }} alert-dismissible fade show">
{{ message }}
</div>
{% endfor %}
{% endif %}
<a href="{{ authorization_url }}" title="Ion" class="border border-dark p-3 btn btn-block btn-lg mx-auto" style="background: black; color: white;"> <a href="{{ authorization_url }}" title="Ion" class="border border-dark p-3 btn btn-block btn-lg mx-auto" style="background: black; color: white;">
<img src="https://ion.tjhsst.edu/static/img/favicon.png" style="filter: invert(1);"> <img src="https://ion.tjhsst.edu/static/img/favicon.png" style="filter: invert(1);">
Register with Ion Register with Ion

View File

@ -7,6 +7,7 @@ from requests_oauthlib import OAuth2Session
from django.contrib import messages from django.contrib import messages
from .models import Token from .models import Token
from .forms import UserCreationForm
from django.contrib.auth import authenticate from django.contrib.auth import authenticate
from django.contrib.auth import login as auth_login from django.contrib.auth import login as auth_login
@ -53,7 +54,7 @@ def callback (request):
if User.objects.filter(username=username).count() != 0: if User.objects.filter(username=username).count() != 0:
messages.success(request, "This user already exists!") messages.success(request, "This user already exists!")
return redirect('register') return redirect('/login/')
else: else:
token = Token(username = username, email = email, first_name = first_name, last_name = last_name, isStudent = isStudent) token = Token(username = username, email = email, first_name = first_name, last_name = last_name, isStudent = isStudent)
token.save() token.save()
@ -63,18 +64,66 @@ def callback (request):
messages.warning(request, "Invalid Callback Response") messages.warning(request, "Invalid Callback Response")
return redirect('register') return redirect('/register/')
def create_account (request): def create_account (request):
if request.method == "POST":
print("POSTPOSTPOSTPOSTPOSTPOSTPOSTPOST")
form = UserCreationForm(request.POST)
print(form.is_valid())
print(request.POST)
cleaned_data = form.clean()
if cleaned_data.get('password') == cleaned_data.get('confirm_password'):
token = Token.objects.get(token=cleaned_data.get('token'))
username = token.username
email = token.email
first_name = token.first_name
last_name = token.last_name
isStudent = token.isStudent
password = cleaned_data.get('password')
user = User.objects.create_user(username=username,
email=email,
first_name=first_name,
last_name=last_name,
password=password)
user.save()
token.delete()
print (user)
messages.success(request, "Your SkoolOS account has successfully been created")
return redirect(f'/login/?username={username}')
else:
print(form.errors)
Token.objects.get(token=request.GET.get('token')).delete()
messages.warning(request, "Passwords did not match!")
return redirect('/register/')
if request.method == "GET" and Token.objects.filter(token=request.GET.get('token')).count() == 1: if request.method == "GET" and Token.objects.filter(token=request.GET.get('token')).count() == 1:
print("GETGETGETGETGETGET")
token = Token.objects.get(token=request.GET.get('token')) token = Token.objects.get(token=request.GET.get('token'))
username = token.username username = token.username
email = token.email email = token.email
first_name = token.first_name first_name = token.first_name
last_name = token.last_name last_name = token.last_name
isStudent = token.isStudent isStudent = token.isStudent
initial = {
'username': username,
'email': email,
'first_name': first_name,
'last_name': last_name,
'isStudent': isStudent,
'token': token.token,
}
form = UserCreationForm(initial=initial)
return render(request, 'users/create_account.html', {'form': form})
messages.warning(request, "Invalid token")
else: return redirect('/register/')
return redirect('/register/')
@login_required
def logout(request):
auth_logout(request)
messages.success(request, "You've been logged out! Have a good rest of your day!")
return redirect(request, "/login/")