diff --git a/CLI/commands.py b/CLI/commands.py index ed1c1f3..39ed5f7 100644 --- a/CLI/commands.py +++ b/CLI/commands.py @@ -5,4 +5,144 @@ import os import argparse - \ No newline at end of file +''' +my_parser = argparse.ArgumentParser(prog='skool', description='Let SkoolOS control your system', epilog="Try again") +my_parser.add_argument('--init', action="store_true") #returns true if run argument +args = my_parser.parse_args() + +update() +outputs = vars(args) +if(outputs['init']): + start() +''' + +#already ccrerrated account through website, has to login +def update(): + #get data from database + return + +def yesorno(question): + questions = [ + { + 'type': 'input', + 'name': 'response', + 'message': question, + }, + ] + answers = prompt(questions) + if(answers["response"] == "y"): + return True + return False + +def login(): + #enter username + #enter password + questions = [ + { + 'type': 'input', + 'name': 'webmail', + 'message': 'What\'s TJ Webmail', + }, + { + 'type': 'password', + 'name': 'password', + 'message': 'Password?', + }, + ] + user = prompt(questions) + #reading from json of users (replace w GET to database) to check if user is registered + with open('users.json', 'r') as json_file: + data = json.load(json_file) + for i in range(len(data)): + if user["webmail"] == data[i]["webmail"]: + if(user["password"] == data[i]["password"]): + print("Logged in!") + return data[i] + else: + print("Password incorrect. Try again.") + return None + print("User not found. Please Try again") + return None + +#did not create account through website, has to signup/login +def signup(): + questions = [ + { + 'type': 'input', + 'name': 'first-name', + 'message': 'What\'s your first name', + }, + { + 'type': 'input', + 'name': 'last-name', + 'message': 'What\'s your last name?', + }, + { + 'type': 'list', + 'name': 'grade', + 'message': 'Grade?', + 'choices':["9","10","11","12"] + }, + { + 'type': 'input', + 'name': 'webmail', + 'message': 'What\'s your TJ Webmail?', + }, + { + 'type': 'password', + 'name': 'password', + 'message': 'Password?', + }, + ] + user = prompt(questions) + for i in user: + if user[i] == "": + print("Some forms were left blank. Try again.\n") + return None + if len(user["password"]) < 6: + print("Password is too short. Try again.") + return None + if (("@tjhsst.edu" in user['webmail']) == False): + print("Webmail entered was not a @tjhhsst.edu. Try again.") + return None + + user["classes"] = [] + with open('users.json', 'r') as json_file: + data = json.load(json_file) + data.append(user) + open("users.json", "w").write(str(json.dumps(data))) + return user + +def relogin(): + questions = [ + { + 'type': 'list', + 'name': 'choice', + 'message': '', + 'choices':["Continue as current user","Login into new user","Sign up into new account"] + }, + ] + answer = prompt(questions) + + +def setup(user): + #Read classes/assignenments and setup directory: + #SkoolOS/Math/Week1 + for c in user["classes"]: + os.makedirs(c) + for a in user["classes"][c]: + os.makedirs(c + "/" + a) + +def start(): + if(os.path.exists(".login.txt") == False): + b = yesorno("Do you have a SkoolOS account?(y/N)") + if(b): + user = login() + if(user != None): + setup(user) + open(".login.txt", "w").write(str(user)) + else: + user = signup() + if(user != None): + open(".login.txt").write(str(user)) + diff --git a/CLI/skoolos.py b/CLI/skoolos.py index 57f3ae3..ccb30ef 100644 --- a/CLI/skoolos.py +++ b/CLI/skoolos.py @@ -1,6 +1,5 @@ import sys from urllib.parse import urlparse - import requests from requests_oauthlib import OAuth2Session from selenium import webdriver @@ -11,6 +10,10 @@ import socketserver from threading import Thread from werkzeug.urls import url_decode import pprint +from PyInquirer import prompt, print_json +import json +import os +import argparse client_id = r'QeZPBSKqdvWFfBv1VYTSv9iFGz5T9pVJtNUjbEr6' client_secret = r'0Wl3hAIGY9SvYOqTOLUiLNYa4OlCgZYdno9ZbcgCT7RGQ8x2f1l2HzZHsQ7ijC74A0mrOhhCVeZugqAmOADHIv5fHxaa7GqFNtQr11HX9ySTw3DscKsphCVi5P71mlGY' @@ -30,16 +33,14 @@ def main(): print("") if not os.path.exists(".profile"): - print(76546789876545678765) + input("Welcome to SkoolOS. Press any key to create an account") authenticate() - print(open(".profile", "r").read()) else: print(open(".profile", "r").read()) # while True: # pass - def authenticate(): oauth = OAuth2Session(client_id=client_id, redirect_uri=redirect_uri, scope=scope) authorization_url, state = oauth.authorization_url("https://ion.tjhsst.edu/oauth/authorize/") diff --git a/Website/api/migrations/0001_initial.py b/Website/api/migrations/0001_initial.py index 056367b..4d13567 100644 --- a/Website/api/migrations/0001_initial.py +++ b/Website/api/migrations/0001_initial.py @@ -1,6 +1,8 @@ -# Generated by Django 3.0.7 on 2020-06-12 01:34 +# Generated by Django 3.0.7 on 2020-06-12 23:18 +from django.conf import settings from django.db import migrations, models +import django.db.models.deletion class Migration(migrations.Migration): @@ -8,33 +10,10 @@ class Migration(migrations.Migration): initial = True dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ - migrations.CreateModel( - name='Assignment', - fields=[ - ('name', models.CharField(max_length=100, primary_key=True, serialize=False)), - ('due_date', models.DateTimeField()), - ('files', models.CharField(blank=True, default='', max_length=100)), - ('path', models.CharField(max_length=100)), - ('classes', models.CharField(max_length=100)), - ('teacher', models.CharField(max_length=100)), - ], - ), - migrations.CreateModel( - name='Classes', - fields=[ - ('name', models.CharField(max_length=100, primary_key=True, serialize=False)), - ('repo', models.URLField(default='')), - ('path', models.CharField(default='', max_length=100)), - ('teacher', models.CharField(default='', max_length=100)), - ('assignments', models.CharField(default='', max_length=100)), - ('default_file', models.CharField(default='', max_length=100)), - ('confirmed', models.TextField(blank=True, default='')), - ('unconfirmed', models.TextField(blank=True, default='')), - ], - ), migrations.CreateModel( name='DefFiles', fields=[ @@ -46,6 +25,19 @@ class Migration(migrations.Migration): ('teacher', models.CharField(max_length=100)), ], ), + migrations.CreateModel( + name='Teacher', + fields=[ + ('created', models.DateTimeField(auto_now_add=True)), + ('first_name', models.CharField(max_length=100)), + ('last_name', models.CharField(max_length=100)), + ('classes', models.CharField(blank=True, default='', max_length=100)), + ('ion_user', models.CharField(max_length=100, primary_key=True, serialize=False)), + ('git', models.CharField(max_length=100)), + ('email', models.CharField(blank=True, default='', max_length=100)), + ('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='teachers', to=settings.AUTH_USER_MODEL)), + ], + ), migrations.CreateModel( name='Student', fields=[ @@ -61,18 +53,33 @@ class Migration(migrations.Migration): ('classes', models.CharField(blank=True, default='', max_length=100)), ('added_to', models.CharField(blank=True, default='', max_length=100)), ('completed', models.TextField(blank=True, default='')), + ('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='students', to=settings.AUTH_USER_MODEL)), ], ), migrations.CreateModel( - name='Teacher', + name='Classes', fields=[ - ('created', models.DateTimeField(auto_now_add=True)), - ('first_name', models.CharField(max_length=100)), - ('last_name', models.CharField(max_length=100)), - ('classes', models.CharField(blank=True, default='', max_length=100)), - ('ion_user', models.CharField(max_length=100, primary_key=True, serialize=False)), - ('git', models.CharField(max_length=100)), - ('email', models.CharField(blank=True, default='', max_length=100)), + ('name', models.CharField(max_length=100, primary_key=True, serialize=False)), + ('repo', models.URLField(blank=True, default='')), + ('path', models.CharField(default='', max_length=100)), + ('teacher', models.CharField(default='', max_length=100)), + ('assignments', models.TextField(blank=True, default='')), + ('default_file', models.CharField(blank=True, default='', max_length=100)), + ('confirmed', models.TextField(blank=True, default='')), + ('unconfirmed', models.TextField(blank=True, default='')), + ('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='classes', to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.CreateModel( + name='Assignment', + fields=[ + ('name', models.CharField(max_length=100, primary_key=True, serialize=False)), + ('due_date', models.DateTimeField()), + ('files', models.CharField(blank=True, default='', max_length=100)), + ('path', models.CharField(max_length=100)), + ('classes', models.CharField(max_length=100)), + ('teacher', models.CharField(max_length=100)), + ('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='assignments', to=settings.AUTH_USER_MODEL)), ], ), ] diff --git a/Website/api/migrations/0002_auto_20200612_0135.py b/Website/api/migrations/0002_auto_20200612_0135.py deleted file mode 100644 index 652eea2..0000000 --- a/Website/api/migrations/0002_auto_20200612_0135.py +++ /dev/null @@ -1,23 +0,0 @@ -# Generated by Django 3.0.7 on 2020-06-12 01:35 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('api', '0001_initial'), - ] - - operations = [ - migrations.AlterField( - model_name='assignment', - name='name', - field=models.CharField(max_length=100), - ), - migrations.AlterField( - model_name='assignment', - name='path', - field=models.CharField(max_length=100, primary_key=True, serialize=False), - ), - ] diff --git a/Website/api/migrations/0003_auto_20200612_0135.py b/Website/api/migrations/0003_auto_20200612_0135.py deleted file mode 100644 index 5b95bdd..0000000 --- a/Website/api/migrations/0003_auto_20200612_0135.py +++ /dev/null @@ -1,23 +0,0 @@ -# Generated by Django 3.0.7 on 2020-06-12 01:35 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('api', '0002_auto_20200612_0135'), - ] - - operations = [ - migrations.AlterField( - model_name='assignment', - name='name', - field=models.CharField(max_length=100, primary_key=True, serialize=False), - ), - migrations.AlterField( - model_name='assignment', - name='path', - field=models.CharField(max_length=100), - ), - ] diff --git a/Website/api/migrations/0004_auto_20200612_0813.py b/Website/api/migrations/0004_auto_20200612_0813.py deleted file mode 100644 index c713dcc..0000000 --- a/Website/api/migrations/0004_auto_20200612_0813.py +++ /dev/null @@ -1,28 +0,0 @@ -# Generated by Django 3.0.7 on 2020-06-12 08:13 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('api', '0003_auto_20200612_0135'), - ] - - operations = [ - migrations.AlterField( - model_name='classes', - name='assignments', - field=models.TextField(blank=True, default=''), - ), - migrations.AlterField( - model_name='classes', - name='default_file', - field=models.CharField(blank=True, default='', max_length=100), - ), - migrations.AlterField( - model_name='classes', - name='repo', - field=models.URLField(blank=True, default=''), - ), - ] diff --git a/Website/api/models.py b/Website/api/models.py index 6c8cb7d..1dfd59a 100644 --- a/Website/api/models.py +++ b/Website/api/models.py @@ -8,6 +8,8 @@ class DefFiles(models.Model): teacher=models.CharField(max_length=100) class Assignment(models.Model): + owner = models.ForeignKey('auth.User', related_name='assignments', on_delete=models.CASCADE) + name=models.CharField(max_length=100, primary_key=True) due_date=models.DateTimeField() # files = models.ManyToManyField(DefFiles) @@ -19,6 +21,8 @@ class Assignment(models.Model): return '%s' % (self.name) class Classes(models.Model): + owner = models.ForeignKey('auth.User', related_name='classes', on_delete=models.CASCADE) + name = models.CharField(primary_key=True, max_length=100) repo=models.URLField(default="", blank=True) path=models.CharField(max_length=100, default="") @@ -34,6 +38,8 @@ class Classes(models.Model): return super(Classes, self).save(*args, **kwargs) class Teacher(models.Model): + owner = models.ForeignKey('auth.User', related_name='teachers', on_delete=models.CASCADE) + created = models.DateTimeField(auto_now_add=True) first_name = models.CharField(max_length=100) last_name = models.CharField(max_length=100) @@ -44,6 +50,8 @@ class Teacher(models.Model): email=models.CharField(max_length=100, default="", blank=True) class Student(models.Model): + owner = models.ForeignKey('auth.User', related_name='students', on_delete=models.CASCADE) + created = models.DateTimeField(auto_now_add=True) first_name = models.CharField(max_length=100) last_name = models.CharField(max_length=100) diff --git a/Website/api/permissions.py b/Website/api/permissions.py new file mode 100644 index 0000000..6aab8bf --- /dev/null +++ b/Website/api/permissions.py @@ -0,0 +1,25 @@ +from rest_framework import permissions + + +class IsOwnerOrReadOnly(permissions.BasePermission): + """ + Custom permission to only allow owners of an object to edit it. + """ + + def has_object_permission(self, request, view, obj): + # Read permissions are allowed to any request, + # so we'll always allow GET, HEAD or OPTIONS requests. + if request.method in permissions.SAFE_METHODS: + return True + + # Write permissions are only allowed to the owner of the snippet. + return obj.owner == request.user + +class isTeacher(permissions.BasePermission): + #only teachers can make classes and assignmenst + def has_object_permission(self, request, view, obj): + if request.method in permissions.SAFE_METHODS: + return True + + # Write permissions are only allowed to the owner of the snippet. + return obj.user.groups.filter(name__in=['teachers']).exists() diff --git a/Website/api/serializers.py b/Website/api/serializers.py index 0ff5ae6..97a9383 100644 --- a/Website/api/serializers.py +++ b/Website/api/serializers.py @@ -1,37 +1,56 @@ 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 + +class UserSerializer(serializers.HyperlinkedModelSerializer): + students = serializers.PrimaryKeyRelatedField(many=True, queryset=Student.objects.all()) + owner = serializers.ReadOnlyField(source='owner.username') + permission_classes = [permissions.IsAuthenticatedOrReadOnly] -class DefFilesSerializer(serializers.HyperlinkedModelSerializer): - permissions_classes = [permissions.IsAuthenticatedOrReadOnly] class Meta: - model = DefFiles - fields = ['name', 'path','assignment','classes', "teacher",'url', 'id'] + model = User + fields = ['id', 'username', 'students'] + +# class DefFilesSerializer(serializers.HyperlinkedModelSerializer): +# class Meta: +# model = DefFiles +# fields = ['name', 'path','assignment','classes', "teacher",'url', 'id'] 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"] + fields = ['url','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'] + fields = ['url', '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'] + fields = ['url', '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'] + fields = ['url', 'first_name', 'last_name','git','ion_user', 'email','classes','owner'] diff --git a/Website/api/views.py b/Website/api/views.py index 439c30b..a8bdb83 100644 --- a/Website/api/views.py +++ b/Website/api/views.py @@ -1,8 +1,14 @@ from .models import Student, Teacher, Classes, Assignment, DefFiles -from .serializers import StudentSerializer, TeacherSerializer, ClassesSerializer, AssignmentSerializer, DefFilesSerializer +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 + +class UserViewSet(viewsets.ModelViewSet): + queryset = User.objects.all() + serializer_class = UserSerializer + class StudentViewSet(viewsets.ModelViewSet): """ @@ -39,10 +45,10 @@ class AssignmentViewSet(viewsets.ModelViewSet): serializer_class = AssignmentSerializer permissions_classes = [permissions.IsAuthenticatedOrReadOnly] -class DefFilesViewSet(viewsets.ModelViewSet): - """ - API endpoint that allows users to be viewed or edited. - """ - queryset = DefFiles.objects.all() - serializer_class = DefFilesSerializer - permissions_classes = [permissions.IsAuthenticatedOrReadOnly] +# class DefFilesViewSet(viewsets.ModelViewSet): +# """ +# API endpoint that allows users to be viewed or edited. +# """ +# queryset = DefFiles.objects.all() +# serializer_class = DefFilesSerializer +# permissions_classes = [permissions.IsAuthenticatedOrReadOnly] diff --git a/Website/skoolos/urls.py b/Website/skoolos/urls.py index a1e34a3..1ffab10 100644 --- a/Website/skoolos/urls.py +++ b/Website/skoolos/urls.py @@ -10,8 +10,8 @@ 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'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. diff --git a/chromedriver-linux b/chromedriver-linux new file mode 100755 index 0000000..7d7041d Binary files /dev/null and b/chromedriver-linux differ diff --git a/chromedriver.exe b/chromedriver.exe new file mode 100644 index 0000000..4850c8d Binary files /dev/null and b/chromedriver.exe differ diff --git a/eharris1/APLit_eharris1/BookReport_APLit/guidelines.txt b/eharris1/APLit_eharris1/BookReport_APLit/guidelines.txt deleted file mode 100644 index e69de29..0000000 diff --git a/eharris1/APLit_eharris1/Cuisine_APLit/instruct.txt b/eharris1/APLit_eharris1/Cuisine_APLit/instruct.txt deleted file mode 100644 index e69de29..0000000 diff --git a/eharris1/APLit_eharris1/Cuisine_APLit/rubric.txt b/eharris1/APLit_eharris1/Cuisine_APLit/rubric.txt deleted file mode 100644 index e69de29..0000000 diff --git a/eharris1/APLit_eharris1/Essay1_APLit/practice_essay.txt b/eharris1/APLit_eharris1/Essay1_APLit/practice_essay.txt deleted file mode 100644 index e69de29..0000000 diff --git a/eharris1/APLit_eharris1/Essay2_APLit/rubric.txt b/eharris1/APLit_eharris1/Essay2_APLit/rubric.txt deleted file mode 100644 index e69de29..0000000 diff --git a/eharris1/APLit_eharris1/Lab3_APLit_eharris1/lab3.txt b/eharris1/APLit_eharris1/Lab3_APLit_eharris1/lab3.txt deleted file mode 100644 index e69de29..0000000 diff --git a/eharris1/APLit_eharris1/README.md b/eharris1/APLit_eharris1/README.md deleted file mode 100644 index e69de29..0000000 diff --git a/eharris1/APLit_eharris1/Test1_APLit/instruct.txt b/eharris1/APLit_eharris1/Test1_APLit/instruct.txt deleted file mode 100644 index e69de29..0000000 diff --git a/eharris1/English11_eharris1/Entry1_English11/rubric.txt b/eharris1/English11_eharris1/Entry1_English11/rubric.txt deleted file mode 100644 index e69de29..0000000 diff --git a/eharris1/English11_eharris1/Entry1_English11/sample_entry.txt b/eharris1/English11_eharris1/Entry1_English11/sample_entry.txt deleted file mode 100644 index e69de29..0000000 diff --git a/eharris1/English11_eharris1/Entry2_English11/instruct.txt b/eharris1/English11_eharris1/Entry2_English11/instruct.txt deleted file mode 100644 index e69de29..0000000 diff --git a/eharris1/English11_eharris1/Journal1_English11/entry.txt b/eharris1/English11_eharris1/Journal1_English11/entry.txt deleted file mode 100644 index 8b13789..0000000 --- a/eharris1/English11_eharris1/Journal1_English11/entry.txt +++ /dev/null @@ -1 +0,0 @@ - diff --git a/eharris1/English11_eharris1/README.md b/eharris1/English11_eharris1/README.md deleted file mode 100644 index e69de29..0000000 diff --git a/runtest.py b/runtest.py deleted file mode 100644 index 837cd82..0000000 --- a/runtest.py +++ /dev/null @@ -1,2 +0,0 @@ -for i in range(0, 100000): - print(i) \ No newline at end of file