From 743325be5234f27f5a5c4750f1db883da8d81de8 Mon Sep 17 00:00:00 2001 From: rushilwiz <rushilwiz@gmail.com> Date: Sat, 13 Jun 2020 23:34:08 -0400 Subject: [PATCH 1/4] Registration with tokens working --- Website/skoolos/settings.py | 1 + Website/skoolos/urls.py | 5 +- Website/users/forms.py | 34 ++++++++++--- Website/users/models.py | 2 +- .../users/templates/users/create_account.html | 22 ++++++++ .../templates/users/create_password.html | 13 ----- Website/users/templates/users/login.html | 13 +++-- Website/users/views.py | 50 +++++++++++++++++-- 8 files changed, 109 insertions(+), 31 deletions(-) create mode 100644 Website/users/templates/users/create_account.html delete mode 100644 Website/users/templates/users/create_password.html diff --git a/Website/skoolos/settings.py b/Website/skoolos/settings.py index c312991..4912bfc 100644 --- a/Website/skoolos/settings.py +++ b/Website/skoolos/settings.py @@ -41,6 +41,7 @@ INSTALLED_APPS = [ 'rest_framework', 'api', 'crispy_forms', + 'django_forms_bootstrap', ] diff --git a/Website/skoolos/urls.py b/Website/skoolos/urls.py index 00553b1..dda5383 100644 --- a/Website/skoolos/urls.py +++ b/Website/skoolos/urls.py @@ -13,13 +13,16 @@ 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('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('login/', auth_views.LoginView.as_view(template_name='users/login.html', authentication_form=LoginForm), 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'), diff --git a/Website/users/forms.py b/Website/users/forms.py index 956b95d..ffcaa81 100644 --- a/Website/users/forms.py +++ b/Website/users/forms.py @@ -1,19 +1,37 @@ from django import forms from django.contrib.auth.models import User +from django.contrib.auth.forms import AuthenticationForm +from django.db.models import Q + + +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): - username = forms.CharField(disabled=True) - email = forms.EmailField(disabled=True) - first_name = forms.CharField(disabled=True) - last_name = forms.CharField(disabled=True) - password = forms.PasswordInput() - confirm_password = forms.PasswordInput() - + username = forms.CharField() + email = forms.EmailField() + first_name = forms.CharField() + last_name = forms.CharField() + isStudent = forms.BooleanField(widget = forms.HiddenInput()) + 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): 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: model = User - fields = ['username', 'email', 'first_name', 'password', 'confirm_password'] + fields = ('username', 'email', 'first_name', 'last_name', 'password') diff --git a/Website/users/models.py b/Website/users/models.py index bed1e0f..29b216c 100644 --- a/Website/users/models.py +++ b/Website/users/models.py @@ -18,4 +18,4 @@ class Token(models.Model): return super(Token, self).save(*args, **kwargs) def __str__(self): - return f"{self.username}'s Token"; + return self.token; diff --git a/Website/users/templates/users/create_account.html b/Website/users/templates/users/create_account.html new file mode 100644 index 0000000..f3f814d --- /dev/null +++ b/Website/users/templates/users/create_account.html @@ -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 %} diff --git a/Website/users/templates/users/create_password.html b/Website/users/templates/users/create_password.html deleted file mode 100644 index 6018ee3..0000000 --- a/Website/users/templates/users/create_password.html +++ /dev/null @@ -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 %} diff --git a/Website/users/templates/users/login.html b/Website/users/templates/users/login.html index 40837e2..efde965 100644 --- a/Website/users/templates/users/login.html +++ b/Website/users/templates/users/login.html @@ -1,16 +1,23 @@ {% extends "users/base.html" %} -{% load crispy_forms_tags %} +{% load bootstrap_tags %} {% block content %} <div class="login-page"> <div class="form"> <form class="login-form" method="POST"> {% csrf_token %} - {{ form | crispy }} + {% 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">login</button> <p class="message">Not registered? <a href="{% url 'register' %}">Create an account with Ion</a></p> </form> </div> </div> -</div> {% endblock %} diff --git a/Website/users/views.py b/Website/users/views.py index c8bf1af..b14099f 100644 --- a/Website/users/views.py +++ b/Website/users/views.py @@ -7,6 +7,7 @@ from requests_oauthlib import OAuth2Session from django.contrib import messages from .models import Token +from .forms import UserCreationForm from django.contrib.auth import authenticate from django.contrib.auth import login as auth_login @@ -53,7 +54,7 @@ def callback (request): if User.objects.filter(username=username).count() != 0: messages.success(request, "This user already exists!") - return redirect('register') + return redirect('/login/') else: token = Token(username = username, email = email, first_name = first_name, last_name = last_name, isStudent = isStudent) token.save() @@ -63,18 +64,57 @@ def callback (request): messages.warning(request, "Invalid Callback Response") - return redirect('register') + return redirect('/login/') def create_account (request): + if request.method == "POST": + print("POSTPOSTPOSTPOSTPOSTPOSTPOSTPOST") + form = UserCreationForm(request.POST) + print(form.is_valid()) + print(request.POST) + if form.is_valid(): + cleaned_data = form.cleaned_data + 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) + return redirect(f'/login/?username={username}') + else: + print(form.errors) + Token.objects.get(token=request.GET.get('token')).delete() + return redirect('/register/?error=password') + 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')) + tokenHash = request.GET.get('token') username = token.username email = token.email first_name = token.first_name last_name = token.last_name isStudent = token.isStudent + initial = { + 'username': username, + 'email': email, + 'first_name': first_name, + 'last_name': last_name, + 'isStudent': isStudent, + 'token': token, + } + form = UserCreationForm(initial=initial) + return render(request, 'users/create_account.html', {'form': form}) - - else: - return redirect('/register/') + return redirect('/login/') From 714d85689dcbe38ffc45a90937249401b3b32a62 Mon Sep 17 00:00:00 2001 From: Raffu Khondaker <2022rkhondak@tjhsst.edu> Date: Sun, 14 Jun 2020 01:15:16 -0400 Subject: [PATCH 2/4] permissions --- Website/api/migrations/0001_initial.py | 2 +- Website/api/permissions.py | 4 +- Website/api/serializers.py | 23 ++- Website/api/urls.py | 16 ++ Website/api/views-back.py | 196 ++++++++++--------------- Website/api/views.py | 33 ++++- Website/skoolos/urls.py | 2 + 7 files changed, 138 insertions(+), 138 deletions(-) diff --git a/Website/api/migrations/0001_initial.py b/Website/api/migrations/0001_initial.py index 4d13567..37f2d7e 100644 --- a/Website/api/migrations/0001_initial.py +++ b/Website/api/migrations/0001_initial.py @@ -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.db import migrations, models diff --git a/Website/api/permissions.py b/Website/api/permissions.py index 6aab8bf..2d64429 100644 --- a/Website/api/permissions.py +++ b/Website/api/permissions.py @@ -13,7 +13,7 @@ class IsOwnerOrReadOnly(permissions.BasePermission): return True # 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): #only teachers can make classes and assignmenst @@ -22,4 +22,4 @@ class isTeacher(permissions.BasePermission): return True # 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 diff --git a/Website/api/serializers.py b/Website/api/serializers.py index 97a9383..2b4bb54 100644 --- a/Website/api/serializers.py +++ b/Website/api/serializers.py @@ -2,15 +2,15 @@ from django.contrib.auth.models import User, Group from .models import Student, Teacher, Classes, Assignment, DefFiles from rest_framework import serializers, permissions from django.contrib.auth.models import User +from .permissions import IsOwnerOrReadOnly,isTeacher class UserSerializer(serializers.HyperlinkedModelSerializer): students = serializers.PrimaryKeyRelatedField(many=True, queryset=Student.objects.all()) - owner = serializers.ReadOnlyField(source='owner.username') - permission_classes = [permissions.IsAuthenticatedOrReadOnly] + teachers = serializers.PrimaryKeyRelatedField(many=True, queryset=Teacher.objects.all()) class Meta: model = User - fields = ['id', 'username', 'students'] + fields = ['id', 'username', 'students','teachers'] # class DefFilesSerializer(serializers.HyperlinkedModelSerializer): # class Meta: @@ -20,37 +20,36 @@ class UserSerializer(serializers.HyperlinkedModelSerializer): class AssignmentSerializer(serializers.HyperlinkedModelSerializer): #permissions_classes = [permissions.IsAuthenticatedOrReadOnly] # files = DefFilesSerializer(many=True, read_only=True,allow_null=True) - permission_classes = [permissions.IsAuthenticatedOrReadOnly] owner = serializers.ReadOnlyField(source='owner.username') - permission_classes = [permissions.IsAuthenticatedOrReadOnly] class Meta: 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): # assignments = AssignmentSerializer(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') - permission_classes = [permissions.IsAuthenticatedOrReadOnly] class Meta: 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): # classes = ClassesSerializer(many=True, read_only=True,allow_null=True) owner = serializers.ReadOnlyField(source='owner.username') - permission_classes = [permissions.IsAuthenticatedOrReadOnly] class Meta: 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): # classes = ClassesSerializer(many=True, read_only=True,allow_null=True) owner = serializers.ReadOnlyField(source='owner.username') - permission_classes = [permissions.IsAuthenticatedOrReadOnly] class Meta: 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'] diff --git a/Website/api/urls.py b/Website/api/urls.py index e69de29..f130d15 100644 --- a/Website/api/urls.py +++ b/Website/api/urls.py @@ -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) \ No newline at end of file diff --git a/Website/api/views-back.py b/Website/api/views-back.py index 5c936f9..011d81a 100644 --- a/Website/api/views-back.py +++ b/Website/api/views-back.py @@ -1,131 +1,89 @@ -# class StudentList(APIView): -# """ -# List all snippets, or create a new snippet. -# """ -# def get(self, request, format=None): -# snippets = Student.objects.all() -# serializer = StudentSerializer(snippets, many=True) -# return response.Response(serializer.data) +from .models import Student, Teacher, Classes, Assignment, DefFiles +from .serializers import StudentSerializer, TeacherSerializer, ClassesSerializer, AssignmentSerializer, UserSerializer +from rest_framework import generics, viewsets, permissions, response, status +from django.http import Http404 +from rest_framework.views import APIView +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 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): -# """ -# Retrieve, update or delete a snippet instance. -# """ -# def get_object(self, pk): -# try: -# return Student.objects.get(pk=pk) -# except Student.DoesNotExist: -# raise Http404 +class StudentList(generics.ListCreateAPIView): + queryset = Student.objects.all() + serializer_class = StudentSerializer + def perform_create(self, serializer): + serializer.save(owner=self.request.user) -# def get(self, request, pk, format=None): -# snippet = self.get_object(pk) -# serializer = StudentSerializer(snippet) -# return response.Response(serializer.data) +class StudentDetail(generics.RetrieveAPIView): + queryset = Student.objects.all() + serializer_class = StudentSerializer + permissions_classes = [permissions.IsAuthenticated, IsOwnerOrReadOnly] -# def put(self, request, pk, format=None): -# snippet = self.get_object(pk) -# serializer = StudentSerializer(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) +class TeacherList(generics.ListCreateAPIView): + queryset = Teacher.objects.all() + serializer_class = TeacherSerializer + 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) -# def delete(self, request, pk, format=None): -# snippet = self.get_object(pk) -# snippet.delete() -# return response.Response(status=status.HTTP_204_NO_CONTENT) +class TeacherDetail(generics.RetrieveAPIView): + queryset = Teacher.objects.all() + serializer_class = TeacherSerializer + 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): -# """ -# List all snippets, or create a new snippet. -# """ -# def get(self, request, format=None): -# snippets = Classes.objects.all() -# serializer = ClassesSerializer(snippets, many=True) -# return response.Response(serializer.data) +class ClassesList(generics.ListCreateAPIView): + queryset = Classes.objects.all() + serializer_class = ClassesSerializer + #permissions_classes = [isTeacher] + 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) -# def post(self, request, format=None): -# serializer = ClassesSerializer(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 ClassesDetail(generics.RetrieveAPIView): +# queryset = Classes.objects.all() +# serializer_class = ClassesSerializer +# # permissions_classes = [permissions.IsAuthenticated, IsOwnerOrReadOnly] -# class ClassesDetail(APIView): -# """ -# Retrieve, update or delete a snippet instance. -# """ -# def get_object(self, pk): -# try: -# return Classes.objects.get(pk=pk) -# except Classes.DoesNotExist: -# raise Http404 +class ClassesDetail(mixins.RetrieveModelMixin, + mixins.UpdateModelMixin, + mixins.DestroyModelMixin, + generics.GenericAPIView): + queryset = Classes.objects.all() + serializer_class = ClassesSerializer -# def get(self, request, pk, format=None): -# snippet = self.get_object(pk) -# serializer = ClassesSerializer(snippet) -# return response.Response(serializer.data) + def get(self, request, *args, **kwargs): + return self.retrieve(request, *args, **kwargs) -# def put(self, request, pk, format=None): -# snippet = self.get_object(pk) -# serializer = ClassesSerializer(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 put(self, request, *args, **kwargs): + print(self.owner) + if(request.user == self.owner): + return self.update(request, *args, **kwargs) -# def delete(self, request, pk, format=None): -# snippet = self.get_object(pk) -# snippet.delete() -# return response.Response(status=status.HTTP_204_NO_CONTENT) \ No newline at end of file + def delete(self, request, *args, **kwargs): + return self.destroy(request, *args, **kwargs) + +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] diff --git a/Website/api/views.py b/Website/api/views.py index a8bdb83..3876c0a 100644 --- a/Website/api/views.py +++ b/Website/api/views.py @@ -4,10 +4,17 @@ from rest_framework import generics, viewsets, permissions, response, status from django.http import Http404 from rest_framework.views import APIView 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): queryset = User.objects.all() serializer_class = UserSerializer + permission_classes = [permissions.IsAuthenticated] class StudentViewSet(viewsets.ModelViewSet): @@ -16,8 +23,10 @@ class StudentViewSet(viewsets.ModelViewSet): """ queryset = Student.objects.all() 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): """ @@ -25,8 +34,10 @@ class TeacherViewSet(viewsets.ModelViewSet): """ queryset = Teacher.objects.all() 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): """ @@ -34,7 +45,14 @@ class ClassesViewSet(viewsets.ModelViewSet): """ queryset = Classes.objects.all() 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): @@ -43,7 +61,14 @@ class AssignmentViewSet(viewsets.ModelViewSet): """ queryset = Assignment.objects.all() 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): # """ diff --git a/Website/skoolos/urls.py b/Website/skoolos/urls.py index 00553b1..6a5d5ac 100644 --- a/Website/skoolos/urls.py +++ b/Website/skoolos/urls.py @@ -1,6 +1,7 @@ from django.urls import path from rest_framework import routers from api import views as api_views +from users import views as user_views from django.contrib import admin from django.conf.urls import include from django.contrib.auth import views as auth_views @@ -16,6 +17,7 @@ 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 = [ + # path('api/', include('api.urls')), path('api/', include(router.urls)), path('api-auth/', include('rest_framework.urls')), path('admin/', admin.site.urls), From 1e78bbf530d14cd993ea3e10aec12b4efd3e8f88 Mon Sep 17 00:00:00 2001 From: rushilwiz <rushilwiz@gmail.com> Date: Sun, 14 Jun 2020 02:22:28 -0400 Subject: [PATCH 3/4] added some messages --- Website/api/models.py | 5 +--- Website/config/__init__.py | 0 Website/{skoolos => config}/asgi.py | 2 +- Website/{skoolos => config}/settings.py | 7 +++-- Website/config/urls.py | 31 +++++++++++++++++++++ Website/{skoolos => config}/wsgi.py | 2 +- Website/manage.py | 2 +- Website/skoolos/admin.py | 3 ++ Website/skoolos/apps.py | 5 ++++ Website/skoolos/migrations/__init__.py | 0 Website/skoolos/models.py | 3 ++ Website/skoolos/static/skoolos/styles.css | 0 Website/skoolos/templates/skoolos/base.html | 26 +++++++++++++++++ Website/skoolos/templates/skoolos/home.html | 5 ++++ Website/skoolos/tests.py | 3 ++ Website/skoolos/urls.py | 26 ++--------------- Website/skoolos/views.py | 8 ++++++ Website/users/forms.py | 11 ++++---- Website/users/models.py | 2 +- Website/users/static/users/styles.css | 6 +++- Website/users/templates/users/base.html | 1 - Website/users/templates/users/login.html | 29 ++++++++++++++----- Website/users/templates/users/register.html | 7 +++++ Website/users/views.py | 23 ++++++++++----- 24 files changed, 151 insertions(+), 56 deletions(-) create mode 100644 Website/config/__init__.py rename Website/{skoolos => config}/asgi.py (82%) rename Website/{skoolos => config}/settings.py (96%) create mode 100644 Website/config/urls.py rename Website/{skoolos => config}/wsgi.py (82%) create mode 100644 Website/skoolos/admin.py create mode 100644 Website/skoolos/apps.py create mode 100644 Website/skoolos/migrations/__init__.py create mode 100644 Website/skoolos/models.py create mode 100644 Website/skoolos/static/skoolos/styles.css create mode 100644 Website/skoolos/templates/skoolos/base.html create mode 100644 Website/skoolos/templates/skoolos/home.html create mode 100644 Website/skoolos/tests.py create mode 100644 Website/skoolos/views.py diff --git a/Website/api/models.py b/Website/api/models.py index 1dfd59a..5659835 100644 --- a/Website/api/models.py +++ b/Website/api/models.py @@ -64,9 +64,6 @@ class Student(models.Model): classes=models.CharField(max_length=100, default="", blank=True) added_to=models.CharField(max_length=100, default="", blank=True) completed=models.TextField(default="", blank=True) - + def save(self, *args, **kwargs): return super(Student, self).save(*args, **kwargs) - - - diff --git a/Website/config/__init__.py b/Website/config/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Website/skoolos/asgi.py b/Website/config/asgi.py similarity index 82% rename from Website/skoolos/asgi.py rename to Website/config/asgi.py index 9577b84..561756d 100644 --- a/Website/skoolos/asgi.py +++ b/Website/config/asgi.py @@ -11,6 +11,6 @@ import os 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() diff --git a/Website/skoolos/settings.py b/Website/config/settings.py similarity index 96% rename from Website/skoolos/settings.py rename to Website/config/settings.py index 4912bfc..b636949 100644 --- a/Website/skoolos/settings.py +++ b/Website/config/settings.py @@ -31,6 +31,7 @@ ALLOWED_HOSTS = [] # Application definition INSTALLED_APPS = [ + 'skoolos.apps.SkoolosConfig', 'users.apps.UsersConfig', 'django.contrib.admin', 'django.contrib.auth', @@ -64,7 +65,7 @@ MIDDLEWARE = [ 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] -ROOT_URLCONF = 'skoolos.urls' +ROOT_URLCONF = 'config.urls' TEMPLATES = [ { @@ -82,7 +83,7 @@ TEMPLATES = [ }, ] -WSGI_APPLICATION = 'skoolos.wsgi.application' +WSGI_APPLICATION = 'config.wsgi.application' # Database @@ -137,3 +138,5 @@ STATIC_URL = '/static/' CRISPY_TEMPLATE_PACK = 'bootstrap4' LOGIN_REDIRECT_URL = '/' + +LOGIN_URL = '/login' diff --git a/Website/config/urls.py b/Website/config/urls.py new file mode 100644 index 0000000..420beb6 --- /dev/null +++ b/Website/config/urls.py @@ -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'), +] diff --git a/Website/skoolos/wsgi.py b/Website/config/wsgi.py similarity index 82% rename from Website/skoolos/wsgi.py rename to Website/config/wsgi.py index f17107f..6b29610 100644 --- a/Website/skoolos/wsgi.py +++ b/Website/config/wsgi.py @@ -11,6 +11,6 @@ import os 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() diff --git a/Website/manage.py b/Website/manage.py index f17dda4..58c5f10 100755 --- a/Website/manage.py +++ b/Website/manage.py @@ -5,7 +5,7 @@ import sys def main(): - os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'skoolos.settings') + os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings') try: from django.core.management import execute_from_command_line except ImportError as exc: diff --git a/Website/skoolos/admin.py b/Website/skoolos/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/Website/skoolos/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/Website/skoolos/apps.py b/Website/skoolos/apps.py new file mode 100644 index 0000000..6d65d67 --- /dev/null +++ b/Website/skoolos/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class SkoolosConfig(AppConfig): + name = 'skoolos' diff --git a/Website/skoolos/migrations/__init__.py b/Website/skoolos/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Website/skoolos/models.py b/Website/skoolos/models.py new file mode 100644 index 0000000..71a8362 --- /dev/null +++ b/Website/skoolos/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/Website/skoolos/static/skoolos/styles.css b/Website/skoolos/static/skoolos/styles.css new file mode 100644 index 0000000..e69de29 diff --git a/Website/skoolos/templates/skoolos/base.html b/Website/skoolos/templates/skoolos/base.html new file mode 100644 index 0000000..ac4bb53 --- /dev/null +++ b/Website/skoolos/templates/skoolos/base.html @@ -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> diff --git a/Website/skoolos/templates/skoolos/home.html b/Website/skoolos/templates/skoolos/home.html new file mode 100644 index 0000000..abfc593 --- /dev/null +++ b/Website/skoolos/templates/skoolos/home.html @@ -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 %} diff --git a/Website/skoolos/tests.py b/Website/skoolos/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/Website/skoolos/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/Website/skoolos/urls.py b/Website/skoolos/urls.py index dda5383..5f53e18 100644 --- a/Website/skoolos/urls.py +++ b/Website/skoolos/urls.py @@ -1,29 +1,7 @@ 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 +from . import 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('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('register/', user_views.register, name='register'), - path('create_account/', user_views.create_account, name='create_account'), - path('callback/', user_views.callback, name='callback'), + path('', views.home, name='home'), ] diff --git a/Website/skoolos/views.py b/Website/skoolos/views.py new file mode 100644 index 0000000..deb0eae --- /dev/null +++ b/Website/skoolos/views.py @@ -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") diff --git a/Website/users/forms.py b/Website/users/forms.py index ffcaa81..7bfae4c 100644 --- a/Website/users/forms.py +++ b/Website/users/forms.py @@ -1,7 +1,6 @@ from django import forms from django.contrib.auth.models import User from django.contrib.auth.forms import AuthenticationForm -from django.db.models import Q class LoginForm(AuthenticationForm): @@ -10,10 +9,10 @@ class LoginForm(AuthenticationForm): class UserCreationForm(forms.ModelForm): - username = forms.CharField() - email = forms.EmailField() - first_name = forms.CharField() - last_name = forms.CharField() + username = forms.CharField(disabled=True) + email = forms.EmailField(disabled=True) + first_name = forms.CharField(disabled=True) + last_name = forms.CharField(disabled=True) isStudent = forms.BooleanField(widget = forms.HiddenInput()) password = forms.CharField(widget=forms.PasswordInput(attrs={'placeholder': 'Password'})) confirm_password = forms.CharField(widget=forms.PasswordInput(attrs={'placeholder': 'Confirm Password'})) @@ -31,7 +30,7 @@ class UserCreationForm(forms.ModelForm): raise forms.ValidationError("Passwords do not match!") return cleaned_data - + class Meta: model = User fields = ('username', 'email', 'first_name', 'last_name', 'password') diff --git a/Website/users/models.py b/Website/users/models.py index 29b216c..bed1e0f 100644 --- a/Website/users/models.py +++ b/Website/users/models.py @@ -18,4 +18,4 @@ class Token(models.Model): return super(Token, self).save(*args, **kwargs) def __str__(self): - return self.token; + return f"{self.username}'s Token"; diff --git a/Website/users/static/users/styles.css b/Website/users/static/users/styles.css index 7aa3c45..f0b3e1c 100644 --- a/Website/users/static/users/styles.css +++ b/Website/users/static/users/styles.css @@ -99,6 +99,10 @@ body { -moz-osx-font-smoothing: grayscale; } +input:disabled { + background: #d9d9d9; +} + .errorlist { -} \ No newline at end of file +} diff --git a/Website/users/templates/users/base.html b/Website/users/templates/users/base.html index f4dd9e6..f621b1e 100644 --- a/Website/users/templates/users/base.html +++ b/Website/users/templates/users/base.html @@ -18,7 +18,6 @@ </head> <body> {% block content %}{% endblock %} -a <!-- 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> diff --git a/Website/users/templates/users/login.html b/Website/users/templates/users/login.html index efde965..185c43b 100644 --- a/Website/users/templates/users/login.html +++ b/Website/users/templates/users/login.html @@ -6,14 +6,29 @@ <div class="form"> <form class="login-form" method="POST"> {% csrf_token %} + {% 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 %} - <div class="fieldWrapper"> - {{ field.errors }} - {{ field }} - {% if field.help_text %} - <p class="help">{{ field.help_text|safe }}</p> - {% endif %} - </div> + {{ field }} {% endfor %} <button type="submit">login</button> <p class="message">Not registered? <a href="{% url 'register' %}">Create an account with Ion</a></p> diff --git a/Website/users/templates/users/register.html b/Website/users/templates/users/register.html index d7bac8d..2712f93 100644 --- a/Website/users/templates/users/register.html +++ b/Website/users/templates/users/register.html @@ -4,6 +4,13 @@ <div class="login-page"> <div class="form"> <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;"> <img src="https://ion.tjhsst.edu/static/img/favicon.png" style="filter: invert(1);"> Register with Ion diff --git a/Website/users/views.py b/Website/users/views.py index b14099f..3e01426 100644 --- a/Website/users/views.py +++ b/Website/users/views.py @@ -64,7 +64,7 @@ def callback (request): messages.warning(request, "Invalid Callback Response") - return redirect('/login/') + return redirect('/register/') def create_account (request): @@ -73,8 +73,8 @@ def create_account (request): form = UserCreationForm(request.POST) print(form.is_valid()) print(request.POST) - if form.is_valid(): - cleaned_data = form.cleaned_data + 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 @@ -91,16 +91,17 @@ def create_account (request): 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() - return redirect('/register/?error=password') + 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: print("GETGETGETGETGETGET") token = Token.objects.get(token=request.GET.get('token')) - tokenHash = request.GET.get('token') username = token.username email = token.email first_name = token.first_name @@ -112,9 +113,17 @@ def create_account (request): 'first_name': first_name, 'last_name': last_name, 'isStudent': isStudent, - 'token': token, + 'token': token.token, } form = UserCreationForm(initial=initial) return render(request, 'users/create_account.html', {'form': form}) - return redirect('/login/') + messages.warning(request, "Invalid token") + 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/") From 1935fb7d38bcfe702d8e6759b8772fd395a2e335 Mon Sep 17 00:00:00 2001 From: Raffu Khondaker <2022rkhondak@tjhsst.edu> Date: Sun, 14 Jun 2020 02:38:05 -0400 Subject: [PATCH 4/4] api urls --- .profile | 1 - CLI/.profile | 0 CLI/oauth/index.html | 2 +- CLI/skoolos.py | 2 +- Website/skoolos/urls.py | 2 +- 5 files changed, 3 insertions(+), 4 deletions(-) delete mode 100644 .profile delete mode 100644 CLI/.profile diff --git a/.profile b/.profile deleted file mode 100644 index df779be..0000000 --- a/.profile +++ /dev/null @@ -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': []} \ No newline at end of file diff --git a/CLI/.profile b/CLI/.profile deleted file mode 100644 index e69de29..0000000 diff --git a/CLI/oauth/index.html b/CLI/oauth/index.html index 62f3082..1c8f1f3 100644 --- a/CLI/oauth/index.html +++ b/CLI/oauth/index.html @@ -14,7 +14,7 @@ </head> <body> <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"> Sign in with Ion </a> diff --git a/CLI/skoolos.py b/CLI/skoolos.py index ccb30ef..e818d3a 100644 --- a/CLI/skoolos.py +++ b/CLI/skoolos.py @@ -52,7 +52,7 @@ def authenticate(): path = os.path.join(cdir, "chromedriver-mac") print(path) browser = webdriver.Chrome(path) - browser = webdriver.Safari() + #browser = webdriver.Safari() web_dir = os.path.join(os.path.dirname(__file__), 'oauth') os.chdir(web_dir) diff --git a/Website/skoolos/urls.py b/Website/skoolos/urls.py index 0d2bd2a..5b8da25 100644 --- a/Website/skoolos/urls.py +++ b/Website/skoolos/urls.py @@ -25,7 +25,7 @@ urlpatterns = [ 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('register/', user_views.register, name='register'), + path('', user_views.register, name='register'), path('create_account/', user_views.create_account, name='create_account'), path('callback/', user_views.callback, name='callback'), ]