Merge pull request #5 from Rushilwiz/development

Merging Development
This commit is contained in:
Rushil Umaretiya 2020-06-14 18:44:36 -04:00 committed by GitHub
commit fdb34d61de
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
78 changed files with 1649 additions and 472 deletions

3
.gitignore vendored
View File

@ -246,6 +246,9 @@ Control.ca-bundle
Control.system-ca-bundle
GitHub.sublime-settings
#SkoolOS
*.profile
# Visual Studio Code #
.vscode/*
!.vscode/settings.json

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

@ -0,0 +1,58 @@
import os
import sys
import signal
import time
import event_processor
class SkoolOSDaemon:
"""Constructor"""
def __init__(self, work_dir='/tmp'):
self.work_dir = work_dir
self.start_time = None
self.end_time = None
self.log_file = None
def __write_pid_file(self):
try:
dirName = "/tmp/skooloslogs"
# Create log Directory
os.mkdir(dirName)
except FileExistsError:
pass
pid = str(os.getpid())
file_ = open('/tmp/skoolosdaemonpid', 'w')
file_.write(pid)
file_.close()
def readable_time(self, input_time):
return time.strftime("%A, %B %d, %Y %H:%M:%S", time.localtime(input_time))
def start(self):
self.__write_pid_file()
self.start_time = time.time()
self.log_file = open('/tmp/skooloslogs/' + str(self.start_time), 'w')
self.log_file.write("Start time: \n" + self.readable_time(self.start_time) + "\n\n")
sys.stdout = self.log_file
event_processor.watch_dir(self.work_dir)
def stop(self):
event_processor.stop_watching()
self.end_time = time.time()
self.log_file.write("Stop time: \n" + self.readable_time(self.end_time))
self.log_file.write("Total work time: " +
time.strftime("%H:%M:%S", time.gmtime(self.end_time - self.start_time)))
logger = None
def Main():
def signal_handler(signum, frame):
logger.stop()
signal.signal(signal.SIGINT, signal_handler)
# signal.signal(signal.SIGTERM, signal_handler)
global logger
logger = SkoolOSDaemon("/tmp")
logger.start()
if __name__ == "__main__":
Main()

View File

@ -0,0 +1,65 @@
import time
import pyinotify
def readable_time(input_time):
return time.strftime("%A, %B %d, %Y %H:%M:%S", time.localtime(input_time))
class EventProcessor(pyinotify.ProcessEvent):
_methods = ["IN_OPEN",
"IN_CREATE",
"IN_CLOSE_WRITE",
"IN_DELETE",
"IN_MOVED_TO",
"IN_MOVED_FROM",
]
def __method_format(method):
return {
"IN_OPEN":"Opened a file",
"IN_CREATE":"Created a file",
"IN_CLOSE_WRITE":"Wrote to a file",
"IN_DELETE":"Deleted a file",
"IN_MOVED_TO":"Moved a file or directory in from elsewhere",
"IN_MOVED_FROM":"Moved a file or directory elsewhere",
}.get(method, "Unknown event")
def __process_generator(cls, method):
def _method_name(self, event):
description = "Event description: {}\n" \
"Path name: {}\n" \
"Event Name: {}\n" \
"Timestamp: {}\n".format(__method_format(method),
event.pathname,
event.maskname,
readable_time(time.time())
)
if "IN_DELETE" in description:
description += "WARNING: Unexpected file deletion\n"
if "IN_MOVED_TO" in description:
description += "WARNING: Unexpected file add to work\n"
if "IN_MOVED_FROM" in description:
description += "WARNING: Unexpected file moved out of directory\n"
print(description)
_method_name.__name__ = "process_{}".format(method)
setattr(cls, _method_name.__name__, _method_name)
EVENT_NOTIFIER = None
def watch_dir(dir_to_watch):
global EVENT_NOTIFIER
for method in EventProcessor._methods:
__process_generator(EventProcessor, method)
watch_manager = pyinotify.WatchManager()
EVENT_NOTIFIER = pyinotify.ThreadedNotifier(watch_manager, EventProcessor())
watch_manager.add_watch(dir_to_watch, pyinotify.ALL_EVENTS, rec=True)
EVENT_NOTIFIER.loop()
def stop_watching():
EVENT_NOTIFIER.stop()

19
BackgroundService/test.py Normal file
View File

@ -0,0 +1,19 @@
from bgservice import SkoolOSDaemon as sod
import threading
logger = sod()
if __name__ == "__main__":
line=1
print(line)
line+=1
logger.start()
print(line)
line+=1
input("Enter any key when you are done modifyng the /tmp/ directory")
print(line)
line+=1
logger.stop()
print(line)
line+=1

View File

@ -5,4 +5,144 @@ import os
import argparse
'''
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))

View File

@ -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%2Fcallback%2F&scope=read&state=yPblNZvC39bYCruLcVibEUzLjXkwaJ" 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>

View File

@ -1,6 +1,5 @@
import sys
from urllib.parse import urlparse
import requests
from requests_oauthlib import OAuth2Session
from selenium import webdriver
@ -11,10 +10,15 @@ 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
from cryptography.fernet import Fernet
client_id = r'QeZPBSKqdvWFfBv1VYTSv9iFGz5T9pVJtNUjbEr6'
client_secret = r'0Wl3hAIGY9SvYOqTOLUiLNYa4OlCgZYdno9ZbcgCT7RGQ8x2f1l2HzZHsQ7ijC74A0mrOhhCVeZugqAmOADHIv5fHxaa7GqFNtQr11HX9ySTw3DscKsphCVi5P71mlGY'
redirect_uri = 'http://localhost:8000/'
redirect_uri = 'http://localhost:8000/callback/'
token_url = 'https://ion.tjhsst.edu/oauth/token/'
scope = ["read"]
@ -30,16 +34,21 @@ 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())
file = open('key.key', 'rb')
key = file.read() # The key will be type bytes
file.close()
f = Fernet(key)
file = open('.profile', 'rb')
p = file.read() # The key will be type bytes
file.close()
# 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/")
@ -48,12 +57,14 @@ def authenticate():
#Linux: chromdriver-linux
#Macos: chromdriver-mac
#Windows: chromdriver.exe
path = os.path.join(cdir, "chromedriver-mac")
print(path)
browser = webdriver.Chrome(path)
browser = webdriver.Safari()
if('CLI' in os.getcwd()):
path = os.path.join(os.getcwd(), '../','chromedriver-mac')
else:
path = os.path.join(os.getcwd(), 'chromedriver-mac')
browser = webdriver.Chrome(path)
web_dir = os.path.join(os.path.dirname(__file__), 'oauth')
print(web_dir)
os.chdir(web_dir)
if os.path.exists("index.html"):
os.remove("index.html")
@ -71,24 +82,29 @@ def authenticate():
browser.get("localhost:8000/")
while "http://localhost:8000/?code" not in browser.current_url:
while "http://localhost:8000/callback/?code" not in browser.current_url:
time.sleep(0.25)
url = browser.current_url
gets = url_decode(url.replace("http://localhost:8000/?", ""))
gets = url_decode(url.replace("http://localhost:8000/callback/?", ""))
while "http://localhost:8000/callback/?code" not in browser.current_url:
time.sleep(0.25)
url = browser.current_url
gets = url_decode(url.replace("http://localhost:8000/callback/?", ""))
code = gets.get("code")
if state == gets.get("state"):
state = gets.get("state")
print("states good")
browser.quit()
print(code)
#print(code)
print(state)
payload = {'grant_type': 'authorization_code', 'code': code, 'redirect_uri': redirect_uri, 'client_id': client_id,
'client_secret': client_secret, 'csrfmiddlewaretoken': state}
token = requests.post("https://ion.tjhsst.edu/oauth/token/", data=payload).json()
print(token)
#print(token)
headers = {'Authorization': f"Bearer {token['access_token']}"}
# And finally get the user's profile!
@ -101,10 +117,18 @@ def authenticate():
last_name = profile['last_name']
os.chdir(cdir)
profileFile = open(".profile", "w")
#profileFile.write(profile.text())
profileFile.write(str(profile))
profileFile.close()
# key = Fernet.generate_key()
# file = open('key.key', 'wb')
# file.write(key) # The key is type bytes still
# file.close()
# p = str(profile).encode()
# f = Fernet(key)
# encrypted = f.encrypt(p)
# profileFile = open(".profile", "wb")
# #profileFile.write(profile.text())
# profileFile.write(encrypted)
# profileFile.close()
sys.exit

View File

@ -386,10 +386,17 @@ class Student:
command('git checkout master')
os.chdir(cdir)
data = getStudent("2022rkhondak")
s = Student(data)
#s.viewClass("APLit_eharris1")
#s.updateClass("APLit_eharris1")
#s.update()
s.exitCLI()
# data = getStudent("2022rkhondak")
# s = Student(data)
# #s.viewClass("APLit_eharris1")
# #s.updateClass("APLit_eharris1")
# #s.update()
# s.exitCLI()
def main():
print("noooo")
pass
if __name__ == "__main__":
# stuff only to run when not called via 'import' here
main()

View File

@ -659,8 +659,8 @@ t = Teacher(data)
#ar = ['2022rkhondak','2022inafi','2023rumareti']
#extra = t.reqAddStudentList(ar, "APLit_eharris1")
#print(extra)
t.getStudents('2022rkhondak')
t.getChanges('2022rkhondak','APLit_eharris1', 10)
# t.getStudents('2022rkhondak')
# t.getChanges('2022rkhondak','APLit_eharris1', 10)
'''
TO-DO

View File

@ -1,3 +1,16 @@
from django.contrib import admin
from .models import (
DefFiles,
Assignment,
Classes,
Teacher,
Student
)
# Register your models here.
admin.site.register(Teacher)
admin.site.register(Student)
admin.site.register(DefFiles)
admin.site.register(Assignment)
admin.site.register(Classes)

View File

@ -1,128 +1,128 @@
from datetime import datetime
f1 = DefFiles(
name="instructions.txt"
)
f1.save()
f2 = DefFiles(
name="instructions.txt"
)
f2.save()
f3 = DefFiles(
name="sample.txt"
)
f3.save()
f4 = DefFiles(
name="rubric.txt"
)
f4.save()
a1 = Assignment.objects.get(pk=1)
a1.files.add(f1)
a1.save()
a2 = Assignment.objects.get(pk=2)
a2.files.add(f2)
a2.save()
a3 = Assignment.objects.get(pk=3)
a3.files.add(f3)
a3.files.add(f4)
a3.save()
####################################
from api.models import Assignment, Student, Classes, Teacher, DefFiles
from datetime import datetime
f1 = DefFiles(
name="instructions.txt"
)
f1.save()
f2 = DefFiles(
name="instructions.txt"
)
f2.save()
f3 = DefFiles(
name="sample.txt"
)
f3.save()
f4 = DefFiles(
name="rubric.txt"
)
f4.save()
A1 = Assignment(
name='Week1_HW',
due_date=datetime.now(),
)
A1.save()
A1.files.add(f1)
A1.save()
A2 = Assignment(
name='Week2_HW',
due_date=datetime.now(),
)
A2.save()
A2.files.add(f2)
A2.save()
A3 = Assignment(
name='Journal1',
due_date=datetime.now(),
)
A3.save()
A3.files.add(f3)
A3.files.add(f4)
A3.save()
#classes
math = Classes(
name='Math5',
)
math.save()
math.assignments.add(A1)
math.assignments.add(A2)
math.save()
english = Classes(
name='English',
)
english.save()
english.assignments.add(A3)
english.save()
#students
raffu = Student(
first_name = "Raffu",
last_name = "Khondaker",
student_id = 1579460,
ion_user="2022rkhondak",
webmail = "2022rkhondak@tjhsst.edu",
grade = 10,
repo="https://github.com/therealraffi/2022rkhondak.git",
)
raffu.save()
raffu.classes.add(math)
raffu.classes.add(english)
raffu.save()
#teachers
ng = Teacher(
first_name = "Errin",
last_name = "Harris",
ion_user="eharris1"
)
ng.save()
ng.classes.add(math)
ng.save()
chao = Teacher(
first_name = "Abagail",
last_name = "Bailey",
ion_user="AKBailey"
)
chao.save()
chao.classes.add(english)
chao.save()
# from datetime import datetime
#
# f1 = DefFiles(
# name="instructions.txt"
# )
# f1.save()
# f2 = DefFiles(
# name="instructions.txt"
# )
# f2.save()
# f3 = DefFiles(
# name="sample.txt"
# )
# f3.save()
# f4 = DefFiles(
# name="rubric.txt"
# )
# f4.save()
#
# a1 = Assignment.objects.get(pk=1)
# a1.files.add(f1)
# a1.save()
# a2 = Assignment.objects.get(pk=2)
# a2.files.add(f2)
# a2.save()
# a3 = Assignment.objects.get(pk=3)
# a3.files.add(f3)
# a3.files.add(f4)
# a3.save()
#
# ####################################
#
# from api.models import Assignment, Student, Classes, Teacher, DefFiles
# from datetime import datetime
#
# f1 = DefFiles(
# name="instructions.txt"
# )
# f1.save()
# f2 = DefFiles(
# name="instructions.txt"
# )
# f2.save()
# f3 = DefFiles(
# name="sample.txt"
# )
# f3.save()
# f4 = DefFiles(
# name="rubric.txt"
# )
# f4.save()
#
# A1 = Assignment(
# name='Week1_HW',
# due_date=datetime.now(),
# )
# A1.save()
# A1.files.add(f1)
# A1.save()
#
# A2 = Assignment(
# name='Week2_HW',
# due_date=datetime.now(),
#
# )
# A2.save()
# A2.files.add(f2)
# A2.save()
#
# A3 = Assignment(
# name='Journal1',
# due_date=datetime.now(),
# )
# A3.save()
# A3.files.add(f3)
# A3.files.add(f4)
# A3.save()
#
# #classes
# math = Classes(
# name='Math5',
#
# )
# math.save()
# math.assignments.add(A1)
# math.assignments.add(A2)
# math.save()
#
# english = Classes(
# name='English',
# )
# english.save()
# english.assignments.add(A3)
# english.save()
#
# #students
# raffu = Student(
# first_name = "Raffu",
# last_name = "Khondaker",
# student_id = 1579460,
# ion_user="2022rkhondak",
# webmail = "2022rkhondak@tjhsst.edu",
# grade = 10,
# repo="https://github.com/therealraffi/2022rkhondak.git",
# )
# raffu.save()
# raffu.classes.add(math)
# raffu.classes.add(english)
# raffu.save()
#
# #teachers
# ng = Teacher(
# first_name = "Errin",
# last_name = "Harris",
# ion_user="eharris1"
# )
# ng.save()
# ng.classes.add(math)
# ng.save()
#
# chao = Teacher(
# first_name = "Abagail",
# last_name = "Bailey",
# ion_user="AKBailey"
# )
# chao.save()
# chao.classes.add(english)
# chao.save()

View File

@ -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-14 19:14
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,23 +25,6 @@ class Migration(migrations.Migration):
('teacher', models.CharField(max_length=100)),
],
),
migrations.CreateModel(
name='Student',
fields=[
('created', models.DateTimeField(auto_now_add=True)),
('first_name', models.CharField(max_length=100)),
('last_name', models.CharField(max_length=100)),
('student_id', models.IntegerField()),
('ion_user', models.CharField(max_length=100, primary_key=True, serialize=False)),
('email', models.CharField(blank=True, default='', max_length=100)),
('grade', models.IntegerField()),
('git', models.CharField(max_length=100)),
('repo', models.URLField(blank=True, default='')),
('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='')),
],
),
migrations.CreateModel(
name='Teacher',
fields=[
@ -73,6 +35,41 @@ class Migration(migrations.Migration):
('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)),
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
migrations.CreateModel(
name='Student',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('website', models.CharField(blank=True, default='https://google.com', max_length=150)),
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
migrations.CreateModel(
name='Classes',
fields=[
('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='')),
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, 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)),
],
),
]

View File

@ -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),
),
]

View File

@ -0,0 +1,52 @@
# Generated by Django 3.0.7 on 2020-06-14 20:34
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('api', '0001_initial'),
]
operations = [
migrations.RemoveField(
model_name='student',
name='website',
),
migrations.AddField(
model_name='student',
name='added_to',
field=models.CharField(blank=True, default='', max_length=100),
),
migrations.AddField(
model_name='student',
name='classes',
field=models.CharField(blank=True, default='', max_length=100),
),
migrations.AddField(
model_name='student',
name='completed',
field=models.TextField(blank=True, default=''),
),
migrations.AddField(
model_name='student',
name='git',
field=models.CharField(blank=True, default='https://github.com/', max_length=100),
),
migrations.AddField(
model_name='student',
name='grade',
field=models.IntegerField(blank=True, default=9),
),
migrations.AddField(
model_name='student',
name='repo',
field=models.URLField(blank=True, default=''),
),
migrations.AddField(
model_name='student',
name='student_id',
field=models.IntegerField(blank=True, default=0),
),
]

View File

@ -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),
),
]

View File

@ -0,0 +1,43 @@
# Generated by Django 3.0.7 on 2020-06-14 20:44
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('api', '0002_auto_20200614_2034'),
]
operations = [
migrations.RemoveField(
model_name='student',
name='student_id',
),
migrations.RemoveField(
model_name='teacher',
name='created',
),
migrations.RemoveField(
model_name='teacher',
name='email',
),
migrations.RemoveField(
model_name='teacher',
name='first_name',
),
migrations.RemoveField(
model_name='teacher',
name='last_name',
),
migrations.AlterField(
model_name='student',
name='git',
field=models.CharField(blank=True, default='', max_length=100),
),
migrations.AlterField(
model_name='student',
name='grade',
field=models.IntegerField(blank=True),
),
]

View File

@ -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=''),
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 3.0.7 on 2020-06-14 21:07
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('api', '0003_auto_20200614_2044'),
]
operations = [
migrations.AlterField(
model_name='student',
name='grade',
field=models.IntegerField(blank=True, default=0),
),
]

View File

@ -1,4 +1,5 @@
from django.db import models
from django.contrib.auth.models import User
class DefFiles(models.Model):
name=models.CharField(max_length=100)
@ -8,6 +9,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 +22,8 @@ class Assignment(models.Model):
return '%s' % (self.name)
class Classes(models.Model):
user = models.OneToOneField(User, 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,31 +39,26 @@ class Classes(models.Model):
return super(Classes, self).save(*args, **kwargs)
class Teacher(models.Model):
created = models.DateTimeField(auto_now_add=True)
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
user = models.OneToOneField(User, on_delete=models.CASCADE)
# classes = models.ManyToManyField(Classes, default="")
classes=models.CharField(max_length=100, default="", blank=True)
ion_user=models.CharField(primary_key=True, max_length=100)
git=models.CharField(max_length=100)
email=models.CharField(max_length=100, default="", blank=True)
def save(self, *args, **kwargs):
super(Teacher, self).save(*args, **kwargs)
class Student(models.Model):
created = models.DateTimeField(auto_now_add=True)
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
student_id = models.IntegerField()
ion_user=models.CharField(primary_key=True, max_length=100)
email=models.CharField(max_length=100, default="", blank=True)
grade = models.IntegerField()
git=models.CharField(max_length=100)
user = models.OneToOneField(User, on_delete=models.CASCADE)
grade = models.IntegerField(default=0, blank=True)
git=models.CharField(default="", max_length=100, blank=True)
repo=models.URLField(default="", blank=True)
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)
super(Student, self).save(*args, **kwargs)
def __str__(self):
return f"{self.user.username}'s Profile"

View File

@ -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 or request.user.is_superuser
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 request.user.groups.filter(name__in=['teachers']).exists() or request.user.is_superuser

View File

@ -1,37 +1,55 @@
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())
teachers = serializers.PrimaryKeyRelatedField(many=True, queryset=Teacher.objects.all())
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']
# 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)
owner = serializers.ReadOnlyField(source='owner.username')
class Meta:
model = Assignment
fields = ['url','name', 'due_date', 'path' , "classes","teacher"]
# 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')
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']
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')
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']
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')
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']
fields = ['first_name', 'last_name','git','ion_user', 'email','classes','owner']

5
Website/api/signals.py Normal file
View File

@ -0,0 +1,5 @@
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver
from .models import Student, Teacher
)

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):
# """
# 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 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)
# 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
# class ClassesDetail(generics.RetrieveAPIView):
# queryset = Classes.objects.all()
# serializer_class = ClassesSerializer
# # permissions_classes = [permissions.IsAuthenticated, IsOwnerOrReadOnly]
# def get(self, request, pk, format=None):
# snippet = self.get_object(pk)
# serializer = TeacherSerializer(snippet)
# return response.Response(serializer.data)
class ClassesDetail(mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
generics.GenericAPIView):
queryset = Classes.objects.all()
serializer_class = ClassesSerializer
# 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 get(self, request, *args, **kwargs):
return self.retrieve(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)
def put(self, request, *args, **kwargs):
print(self.owner)
if(request.user == self.owner):
return self.update(request, *args, **kwargs)
# 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)
def delete(self, request, *args, **kwargs):
return self.destroy(request, *args, **kwargs)
# 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 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 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
# def get(self, request, pk, format=None):
# snippet = self.get_object(pk)
# serializer = ClassesSerializer(snippet)
# return response.Response(serializer.data)
# 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 delete(self, request, pk, format=None):
# snippet = self.get_object(pk)
# snippet.delete()
# return response.Response(status=status.HTTP_204_NO_CONTENT)
class AssignmentDetail(generics.RetrieveAPIView):
queryset = Assignment.objects.all()
serializer_class = AssignmentSerializer
permissions_classes = [permissions.IsAuthenticated, IsOwnerOrReadOnly]

View File

@ -1,8 +1,21 @@
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
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):
"""
@ -10,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):
"""
@ -19,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):
"""
@ -28,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):
@ -37,12 +61,19 @@ class AssignmentViewSet(viewsets.ModelViewSet):
"""
queryset = Assignment.objects.all()
serializer_class = AssignmentSerializer
permissions_classes = [permissions.IsAuthenticatedOrReadOnly]
permission_classes = [permissions.IsAuthenticated, isTeacher, IsOwnerOrReadOnly]
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]
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):
# """
# API endpoint that allows users to be viewed or edited.
# """
# queryset = DefFiles.objects.all()
# serializer_class = DefFilesSerializer
# permissions_classes = [permissions.IsAuthenticatedOrReadOnly]

View File

@ -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()

View File

@ -31,6 +31,7 @@ ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'skoolos.apps.SkoolosConfig',
'users.apps.UsersConfig',
'django.contrib.admin',
'django.contrib.auth',
@ -41,8 +42,7 @@ INSTALLED_APPS = [
'rest_framework',
'api',
'crispy_forms',
'django_forms_bootstrap',
]
REST_FRAMEWORK = {
@ -63,7 +63,7 @@ MIDDLEWARE = [
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'skoolos.urls'
ROOT_URLCONF = 'config.urls'
TEMPLATES = [
{
@ -81,7 +81,7 @@ TEMPLATES = [
},
]
WSGI_APPLICATION = 'skoolos.wsgi.application'
WSGI_APPLICATION = 'config.wsgi.application'
# Database
@ -136,3 +136,5 @@ STATIC_URL = '/static/'
CRISPY_TEMPLATE_PACK = 'bootstrap4'
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
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'skoolos.settings')
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')
application = get_wsgi_application()

View File

@ -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:

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

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

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,100 @@
@font-face {
font-family: Futura;
src: url(futura.ttf);
}
@font-face {
font-family: 'Segoe UI';
src: url('Segoe UI.ttf');
}
body {
background: #fafafa;
color: #333333;
margin-top: 5rem;
font-family: 'Segoe UI';
}
h1, h2, h3, h4, h5, h6 {
color: #444444;
}
ul {
margin: 0;
}
.bg-steel {
background: #3cba54;
}
.site-header .navbar-nav .nav-link {
color: #cbd5db;
}
.site-header .navbar-nav .nav-link:hover {
color: #ffffff;
}
.site-header .navbar-nav .nav-link.active {
font-weight: 500;
}
.content-section {
background: #ffffff;
padding: 10px 20px;
border: 1px solid #dddddd;
border-radius: 3px;
margin-bottom: 20px;
}
.article-title {
color: #444444;
}
a.article-title:hover {
color: #428bca;
text-decoration: none;
}
.article-content {
white-space: pre-line;
}
.article-img {
height: 65px;
width: 65px;
margin-right: 16px;
}
.article-metadata {
padding-bottom: 1px;
margin-bottom: 4px;
border-bottom: 1px solid #e3e3e3
}
.article-metadata a:hover {
color: #333;
text-decoration: none;
}
.article-svg {
width: 25px;
height: 25px;
vertical-align: middle;
}
.account-img {
height: 125px;
width: 125px;
margin-right: 20px;
margin-bottom: 16px;
}
.account-heading {
font-size: 2.5rem;
}
.nounderline {
text-decoration: none !important;
color: black !important;
}

View File

@ -0,0 +1,52 @@
{% 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>
<header class="site-header">
<nav class="navbar navbar-expand-md navbar-dark bg-steel fixed-top">
<div class="container">
<a class="navbar-brand" href="#">
<img src="/docs/4.3/assets/brand/bootstrap-solid.svg" width="30" height="30" class="d-inline-block align-top" alt="">
Bootstrap
</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarToggle" aria-controls="navbarToggle" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarToggle">
<div class="navbar-nav mr-auto">
<a class="nav-item nav-link" href="{% url 'home' %}">Home</a>
</div>
<!-- Navbar Right Side -->
<div class="navbar-nav">
{% if user.is_authenticated %}
<a class="nav-item nav-link" href="{% url 'profile' %}">{{ user.username }}</a>
<a class="nav-item nav-link" href="{% url 'logout' %}">Logout</a>
{% endif %}
</div>
</div>
</div>
</nav>
</header>
{% 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,3 @@
{% extends "skoolos/base.html" %}
{% block content %}
{% 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,23 +1,9 @@
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)
from . import views
# 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('', views.home, name='home'),
path('profile/', views.profile, name='profile')
]

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

@ -0,0 +1,12 @@
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")
@login_required()
def profile (request):
pass

View File

@ -1,3 +1,5 @@
from django.contrib import admin
from .models import Token
# Register your models here.
admin.site.register(Token)

32
Website/users/forms.py Normal file
View File

@ -0,0 +1,32 @@
from django import forms
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):
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())
git = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'Git Username'}))
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()
return cleaned_data
class Meta:
model = User
fields = ('username', 'email', 'first_name', 'last_name', 'git', 'password', 'confirm_password')

View File

@ -0,0 +1,26 @@
# Generated by Django 3.0.7 on 2020-06-14 19:13
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Token',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('username', models.TextField()),
('email', models.TextField()),
('first_name', models.TextField()),
('last_name', models.TextField()),
('isStudent', models.BooleanField()),
('token', models.CharField(max_length=255)),
],
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 3.0.7 on 2020-06-14 20:44
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('users', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='token',
name='isStudent',
field=models.BooleanField(default=True),
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 3.0.7 on 2020-06-14 21:07
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('users', '0002_auto_20200614_2044'),
]
operations = [
migrations.AddField(
model_name='token',
name='grade',
field=models.IntegerField(default=9),
),
]

View File

@ -1,3 +1,22 @@
from django.db import models
from uuid import uuid4
# Create your models here.
class Token(models.Model):
username = models.TextField()
email = models.TextField()
first_name = models.TextField()
last_name = models.TextField()
grade = models.IntegerField(default=9)
isStudent = models.BooleanField(default=True)
token = models.CharField(max_length=255)
def save(self, *args, **kwargs):
if not self.token:
self.token = uuid4()
return super(Token, self).save(*args, **kwargs)
def __str__(self):
return f"{self.username}'s Token";

6
Website/users/pwd.py Normal file
View File

@ -0,0 +1,6 @@
import os
pwd = "heyyy"
path = os.getcwd()
p = os.path.join(path, '../../', 'pwd.txt')
open(p, 'w')

View File

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

View File

@ -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>

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,16 +1,38 @@
{% 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 }}
{% 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>
<p class="message">Not registered? <a href="#">Create an account with Ionreg</a></p>
<p class="message">Not registered? <a href="{% url 'register' %}">Create an account with Ion</a></p>
</form>
</div>
</div>
</div>
{% endblock %}

View File

@ -3,12 +3,19 @@
{% block content %}
<div class="login-page">
<div class="form">
<form class="login-form" method="POST">
{% csrf_token %}
{{ form | crispy }}
<button type="submit">login</button>
<p class="message">Not registered? <a href="#">Create an account with Ionreg</a></p>
</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
</a>
</div>
</div>
</div>
</div>

View File

@ -1,3 +1,148 @@
from django.shortcuts import render
import json
import requests
from django.shortcuts import render, redirect
from requests_oauthlib import OAuth2Session
from django.contrib import messages
from .models import Token
from api.models import Student, Teacher
from .forms import UserCreationForm
from django.contrib.auth import authenticate
from django.contrib.auth import login as auth_login
from django.contrib.auth import logout as auth_logout
from django.contrib.auth.models import User
from django.contrib.auth.decorators import login_required
import os
# Create your views here.
# Thanks Django, what would I do without this comment
client_id = r'QeZPBSKqdvWFfBv1VYTSv9iFGz5T9pVJtNUjbEr6'
client_secret = r'0Wl3hAIGY9SvYOqTOLUiLNYa4OlCgZYdno9ZbcgCT7RGQ8x2f1l2HzZHsQ7ijC74A0mrOhhCVeZugqAmOADHIv5fHxaa7GqFNtQr11HX9ySTw3DscKsphCVi5P71mlGY'
redirect_uri = 'http://localhost:8000/callback/'
token_url = 'https://ion.tjhsst.edu/oauth/authorize/'
scope=["read"]
def register(request):
oauth = OAuth2Session(client_id=client_id, redirect_uri=redirect_uri, scope=scope)
authorization_url, state = oauth.authorization_url("https://ion.tjhsst.edu/oauth/authorize/")
return render(request,"users/register.html", {"authorization_url": authorization_url})
def callback (request):
if request.method == "GET":
code = request.GET.get('code')
state = request.GET.get("state")
# Then if we get a response from Ion with the authorization code
if code is not None and state is not None:
print ("made it")
# We send it back to fetch the acess_token
payload = {'grant_type':'authorization_code','code': code,'redirect_uri':redirect_uri,'client_id':client_id,'client_secret':client_secret, 'csrfmiddlewaretoken': state}
token = requests.post("https://ion.tjhsst.edu/oauth/token/", data=payload).json()
headers = {'Authorization': f"Bearer {token['access_token']}"}
print(token)
# And finally get the user's profile!
profile = requests.get("https://ion.tjhsst.edu/api/profile", headers=headers).json()
print(profile)
username = profile['ion_username']
email = profile['tj_email']
first_name = profile['first_name']
last_name = profile['last_name']
isStudent = profile['is_student']
grade = profile['grade']['number']
if User.objects.filter(username=username).count() != 0:
messages.success(request, "This user already exists!")
return redirect('/login/')
else:
token = Token(username = username, email = email, first_name = first_name, last_name = last_name, isStudent = isStudent, grade=grade)
token.save()
tokenHash = token.token
print(f'/create_account/?token={tokenHash}')
return redirect(f'/create_account/?token={tokenHash}')
messages.warning(request, "Invalid Callback Response")
return redirect('/register/')
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
grade = token.grade
git = cleaned_data.get('git')
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()
if isStudent:
profile = Student(user=user, git=git, grade=grade)
else:
profile = Teacher(user=user, git=git)
profile.save()
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:
print("GETGETGETGETGETGET")
token = Token.objects.get(token=request.GET.get('token'))
username = token.username
email = token.email
first_name = token.first_name
last_name = token.last_name
isStudent = token.isStudent
grade = token.grade
initial = {
'username': username,
'email': email,
'first_name': first_name,
'last_name': last_name,
'grade': grade,
'isStudent': isStudent,
'token': token.token,
}
form = UserCreationForm(initial=initial)
return render(request, 'users/create_account.html', {'form': form})
messages.warning(request, "Invalid token")
return redirect('/register/')
@login_required
def logout(request):
auth_logout(request)
messages.success(request, "You've been logged out!")
return redirect(request, "/login")

BIN
chromedriver-linux Executable file

Binary file not shown.

BIN
chromedriver.exe Normal file

Binary file not shown.

View File

@ -12,6 +12,7 @@ oauthlib==3.1.0
prompt-toolkit==1.0.14
pyclipper==1.1.0.post3
Pygments==2.6.1
pyinotify==0.9.6
PyInquirer==1.0.3
pyperclip==1.8.0
pytz==2020.1

View File

@ -1,2 +0,0 @@
for i in range(0, 100000):
print(i)

242
skoolos.py Normal file
View File

@ -0,0 +1,242 @@
import sys
from urllib.parse import urlparse
import requests
from requests_oauthlib import OAuth2Session
from selenium import webdriver
import os.path
import time
import http.server
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'
redirect_uri = 'http://localhost:8000/callback/'
token_url = 'https://ion.tjhsst.edu/oauth/token/'
scope = ["read"]
USER = ""
PWD = ""
def main():
print("")
print("░██████╗██╗░░██╗░█████╗░░█████╗░██╗░░░░░  ░█████╗░░██████╗")
print("██╔════╝██║░██╔╝██╔══██╗██╔══██╗██║░░░░░  ██╔══██╗██╔════╝")
print("╚█████╗░█████═╝░██║░░██║██║░░██║██║░░░░░  ██║░░██║╚█████╗░")
print("░╚═══██╗██╔═██╗░██║░░██║██║░░██║██║░░░░░  ██║░░██║░╚═══██╗")
print("██████╔╝██║░╚██╗╚█████╔╝╚█████╔╝███████╗  ╚█████╔╝██████╔╝")
print("╚═════╝░╚═╝░░╚═╝░╚════╝░░╚════╝░╚══════╝  ░╚════╝░╚═════╝░")
print("")
if not os.path.exists(".profile"):
try:
URL = "http://127.0.0.1:8000/api/"
r = requests.get(url = URL, auth=('raffukhondaker','hackgroup1'))
print("End service at http://127.0.0.1:8000/ before continuing.")
sys.exit(0)
except:
pass
input("Welcome to SkoolOS. Press any key to create an account")
authenticate()
else:
try:
URL = "http://127.0.0.1:8000/api/"
r = requests.get(url = URL, auth=('raffukhondaker','hackgroup1'))
except:
print("Start Django server first")
sys.exit(0)
f = open('.profile','r')
data = json.loads(f.read())
f.close()
PWD = data['password']
USER = data['username']
if(data['is_student']):
studentCLI()
else:
teacherCLI()
# while True:
# pass
def studentCLI():
from CLI import student
data = getStudent(USER)
print(data)
student = student.Student(data)
print(student)
def teacherCLI():
from CLI.teacher import Teacher
print("fail")
def getStudent(ion_user):
URL = "http://127.0.0.1:8000/api/students/" + ion_user + "/"
r = requests.get(url = URL, auth=('raffukhondaker','hackgroup1'))
if(r.status_code == 200):
data = r.json()
return data
elif(r.status_code == 404):
return None
print("Make new account!")
elif(r.status_code == 403):
return None
print("Invalid username/password")
else:
return None
print(r.status_code)
def getDB(url):
r = requests.get(url = url, auth=('raffukhondaker','hackgroup1'))
print("GET:" + str(r.status_code))
return(r.json())
def postDB(data, url):
r = requests.post(url = url, data=data, auth=('raffukhondaker','hackgroup1'))
print("POST:" + str(r.status_code))
return(r.json())
def putDB(data, url):
r = requests.put(url = url, data=data, auth=('raffukhondaker','hackgroup1'))
print("PUT:" + str(r.status_code))
return(r.json())
def delDB(url):
r = requests.delete(url = url, auth=('raffukhondaker','hackgroup1'))
print("DELETE:" + str(r.status_code))
return None
def makePass():
questions = [
{
'type': 'password',
'name': 'pwd',
'message': 'Enter SkoolOS Password (NOT ION PASSWORD): ',
},
]
pwd = prompt(questions)['pwd']
while(len(pwd) < 7):
print("Password too short (Must be over 6 characters)")
pwd = prompt(questions)['pwd']
conf = [
{
'type': 'password',
'name': 'pwd',
'message': 'Re-enter password: ',
},
]
pwd2 = prompt(conf)['pwd']
while(not pwd == pwd2):
print("Passwords do not match.")
pwd2 = prompt(conf)['pwd']
else:
print("PASSWORD SAVED")
return pwd
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/")
cdir = os.getcwd()
#Linux: chromdriver-linux
#Macos: chromdriver-mac
#Windows: chromdriver.exe
if('CLI' in os.getcwd()):
path = os.path.join(os.getcwd(), '../','chromedriver-mac')
else:
path = os.path.join(os.getcwd(), 'chromedriver-mac')
browser = webdriver.Chrome(path)
web_dir = os.path.join(os.getcwd(), 'CLI', 'oauth')
print(web_dir)
os.chdir(web_dir)
if os.path.exists("index.html"):
os.remove("index.html")
template = open("template.html", "r")
index = open("index.html", "w")
for line in template:
index.write(line.replace('AUTH_URL', authorization_url))
template.close()
index.close()
server = Thread(target=create_server)
server.daemon = True
server.start()
browser.get("localhost:8000/")
while "http://localhost:8000/callback/?code" not in browser.current_url:
time.sleep(0.25)
url = browser.current_url
gets = url_decode(url.replace("http://localhost:8000/callback/?", ""))
while "http://localhost:8000/callback/?code" not in browser.current_url:
time.sleep(0.25)
url = browser.current_url
gets = url_decode(url.replace("http://localhost:8000/callback/?", ""))
code = gets.get("code")
if state == gets.get("state"):
state = gets.get("state")
print("states good")
browser.quit()
#print(code)
print(state)
payload = {'grant_type': 'authorization_code', 'code': code, 'redirect_uri': redirect_uri, 'client_id': client_id,
'client_secret': client_secret, 'csrfmiddlewaretoken': state}
token = requests.post("https://ion.tjhsst.edu/oauth/token/", data=payload).json()
#print(token)
headers = {'Authorization': f"Bearer {token['access_token']}"}
# And finally get the user's profile!
profile = requests.get("https://ion.tjhsst.edu/api/profile", headers=headers).json()
#pprint.pprint(profile)
username = profile['ion_username']
email = profile['tj_email']
first_name = profile['first_name']
last_name = profile['last_name']
is_student = profile['is_student']
password = ""
#password creation
profile = {
'username':username,
'email':email,
'first_name':first_name,
'last_name':last_name,
'is_student':is_student,
'password':password,
}
os.chdir(cdir)
profileFile = open(".profile", "w")
profileFile.write(json.dumps(profile))
profileFile.close()
#try to make password
password = makePass()
profile['password'] = password
profileFile = open(".profile", "w")
profileFile.write(json.dumps(profile))
profileFile.close()
sys.exit
def create_server():
port = 8000
handler = http.server.SimpleHTTPRequestHandler
httpd = socketserver.TCPServer(("", port), handler)
print("serving at port:" + str(port))
httpd.serve_forever()
if __name__ == "__main__":
main()