mirror of
https://github.com/Rushilwiz/SkoolOS.git
synced 2025-04-16 02:10:19 -04:00
commit
fdb34d61de
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -246,6 +246,9 @@ Control.ca-bundle
|
||||||
Control.system-ca-bundle
|
Control.system-ca-bundle
|
||||||
GitHub.sublime-settings
|
GitHub.sublime-settings
|
||||||
|
|
||||||
|
#SkoolOS
|
||||||
|
*.profile
|
||||||
|
|
||||||
# Visual Studio Code #
|
# Visual Studio Code #
|
||||||
.vscode/*
|
.vscode/*
|
||||||
!.vscode/settings.json
|
!.vscode/settings.json
|
||||||
|
|
1
.profile
1
.profile
|
@ -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': []}
|
|
58
BackgroundService/bgservice.py
Normal file
58
BackgroundService/bgservice.py
Normal 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()
|
65
BackgroundService/event_processor.py
Normal file
65
BackgroundService/event_processor.py
Normal 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
19
BackgroundService/test.py
Normal 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
|
142
CLI/commands.py
142
CLI/commands.py
|
@ -5,4 +5,144 @@ import os
|
||||||
import argparse
|
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))
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="d-flex align-items-center justify-content-center" style="height: 100vh">
|
<div class="d-flex align-items-center justify-content-center" style="height: 100vh">
|
||||||
<a href="https://ion.tjhsst.edu/oauth/authorize/?response_type=code&client_id=QeZPBSKqdvWFfBv1VYTSv9iFGz5T9pVJtNUjbEr6&redirect_uri=http%3A%2F%2Flocalhost%3A8000%2F&scope=read&state=81xYFv6S9CLi7laXQ64gJWskDJUMMb" title="Ion" class="border border-dark p-3 btn btn-lg mx-auto" style="box-shadow: 5px 10px;">
|
<a href="https://ion.tjhsst.edu/oauth/authorize/?response_type=code&client_id=QeZPBSKqdvWFfBv1VYTSv9iFGz5T9pVJtNUjbEr6&redirect_uri=http%3A%2F%2Flocalhost%3A8000%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">
|
<img src="https://ion.tjhsst.edu/static/img/favicon.png">
|
||||||
Sign in with Ion
|
Sign in with Ion
|
||||||
</a>
|
</a>
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import sys
|
import sys
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
from requests_oauthlib import OAuth2Session
|
from requests_oauthlib import OAuth2Session
|
||||||
from selenium import webdriver
|
from selenium import webdriver
|
||||||
|
@ -11,10 +10,15 @@ import socketserver
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
from werkzeug.urls import url_decode
|
from werkzeug.urls import url_decode
|
||||||
import pprint
|
import pprint
|
||||||
|
from PyInquirer import prompt, print_json
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import argparse
|
||||||
|
from cryptography.fernet import Fernet
|
||||||
|
|
||||||
client_id = r'QeZPBSKqdvWFfBv1VYTSv9iFGz5T9pVJtNUjbEr6'
|
client_id = r'QeZPBSKqdvWFfBv1VYTSv9iFGz5T9pVJtNUjbEr6'
|
||||||
client_secret = r'0Wl3hAIGY9SvYOqTOLUiLNYa4OlCgZYdno9ZbcgCT7RGQ8x2f1l2HzZHsQ7ijC74A0mrOhhCVeZugqAmOADHIv5fHxaa7GqFNtQr11HX9ySTw3DscKsphCVi5P71mlGY'
|
client_secret = r'0Wl3hAIGY9SvYOqTOLUiLNYa4OlCgZYdno9ZbcgCT7RGQ8x2f1l2HzZHsQ7ijC74A0mrOhhCVeZugqAmOADHIv5fHxaa7GqFNtQr11HX9ySTw3DscKsphCVi5P71mlGY'
|
||||||
redirect_uri = 'http://localhost:8000/'
|
redirect_uri = 'http://localhost:8000/callback/'
|
||||||
token_url = 'https://ion.tjhsst.edu/oauth/token/'
|
token_url = 'https://ion.tjhsst.edu/oauth/token/'
|
||||||
scope = ["read"]
|
scope = ["read"]
|
||||||
|
|
||||||
|
@ -30,16 +34,21 @@ def main():
|
||||||
print("")
|
print("")
|
||||||
|
|
||||||
if not os.path.exists(".profile"):
|
if not os.path.exists(".profile"):
|
||||||
print(76546789876545678765)
|
input("Welcome to SkoolOS. Press any key to create an account")
|
||||||
authenticate()
|
authenticate()
|
||||||
print(open(".profile", "r").read())
|
|
||||||
else:
|
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:
|
# while True:
|
||||||
# pass
|
# pass
|
||||||
|
|
||||||
|
|
||||||
def authenticate():
|
def authenticate():
|
||||||
oauth = OAuth2Session(client_id=client_id, redirect_uri=redirect_uri, scope=scope)
|
oauth = OAuth2Session(client_id=client_id, redirect_uri=redirect_uri, scope=scope)
|
||||||
authorization_url, state = oauth.authorization_url("https://ion.tjhsst.edu/oauth/authorize/")
|
authorization_url, state = oauth.authorization_url("https://ion.tjhsst.edu/oauth/authorize/")
|
||||||
|
@ -48,12 +57,14 @@ def authenticate():
|
||||||
#Linux: chromdriver-linux
|
#Linux: chromdriver-linux
|
||||||
#Macos: chromdriver-mac
|
#Macos: chromdriver-mac
|
||||||
#Windows: chromdriver.exe
|
#Windows: chromdriver.exe
|
||||||
path = os.path.join(cdir, "chromedriver-mac")
|
if('CLI' in os.getcwd()):
|
||||||
print(path)
|
path = os.path.join(os.getcwd(), '../','chromedriver-mac')
|
||||||
browser = webdriver.Chrome(path)
|
else:
|
||||||
browser = webdriver.Safari()
|
path = os.path.join(os.getcwd(), 'chromedriver-mac')
|
||||||
|
|
||||||
|
browser = webdriver.Chrome(path)
|
||||||
web_dir = os.path.join(os.path.dirname(__file__), 'oauth')
|
web_dir = os.path.join(os.path.dirname(__file__), 'oauth')
|
||||||
|
print(web_dir)
|
||||||
os.chdir(web_dir)
|
os.chdir(web_dir)
|
||||||
if os.path.exists("index.html"):
|
if os.path.exists("index.html"):
|
||||||
os.remove("index.html")
|
os.remove("index.html")
|
||||||
|
@ -71,24 +82,29 @@ def authenticate():
|
||||||
|
|
||||||
browser.get("localhost:8000/")
|
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)
|
time.sleep(0.25)
|
||||||
|
|
||||||
url = browser.current_url
|
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")
|
code = gets.get("code")
|
||||||
if state == gets.get("state"):
|
if state == gets.get("state"):
|
||||||
state = gets.get("state")
|
state = gets.get("state")
|
||||||
print("states good")
|
print("states good")
|
||||||
browser.quit()
|
browser.quit()
|
||||||
|
|
||||||
print(code)
|
#print(code)
|
||||||
print(state)
|
print(state)
|
||||||
|
|
||||||
payload = {'grant_type': 'authorization_code', 'code': code, 'redirect_uri': redirect_uri, 'client_id': client_id,
|
payload = {'grant_type': 'authorization_code', 'code': code, 'redirect_uri': redirect_uri, 'client_id': client_id,
|
||||||
'client_secret': client_secret, 'csrfmiddlewaretoken': state}
|
'client_secret': client_secret, 'csrfmiddlewaretoken': state}
|
||||||
token = requests.post("https://ion.tjhsst.edu/oauth/token/", data=payload).json()
|
token = requests.post("https://ion.tjhsst.edu/oauth/token/", data=payload).json()
|
||||||
print(token)
|
#print(token)
|
||||||
headers = {'Authorization': f"Bearer {token['access_token']}"}
|
headers = {'Authorization': f"Bearer {token['access_token']}"}
|
||||||
|
|
||||||
# And finally get the user's profile!
|
# And finally get the user's profile!
|
||||||
|
@ -101,10 +117,18 @@ def authenticate():
|
||||||
last_name = profile['last_name']
|
last_name = profile['last_name']
|
||||||
|
|
||||||
os.chdir(cdir)
|
os.chdir(cdir)
|
||||||
profileFile = open(".profile", "w")
|
# key = Fernet.generate_key()
|
||||||
#profileFile.write(profile.text())
|
# file = open('key.key', 'wb')
|
||||||
profileFile.write(str(profile))
|
# file.write(key) # The key is type bytes still
|
||||||
profileFile.close()
|
# 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
|
sys.exit
|
||||||
|
|
||||||
|
|
|
@ -386,10 +386,17 @@ class Student:
|
||||||
command('git checkout master')
|
command('git checkout master')
|
||||||
os.chdir(cdir)
|
os.chdir(cdir)
|
||||||
|
|
||||||
data = getStudent("2022rkhondak")
|
# data = getStudent("2022rkhondak")
|
||||||
s = Student(data)
|
# s = Student(data)
|
||||||
#s.viewClass("APLit_eharris1")
|
# #s.viewClass("APLit_eharris1")
|
||||||
#s.updateClass("APLit_eharris1")
|
# #s.updateClass("APLit_eharris1")
|
||||||
#s.update()
|
# #s.update()
|
||||||
s.exitCLI()
|
# s.exitCLI()
|
||||||
|
|
||||||
|
def main():
|
||||||
|
print("noooo")
|
||||||
|
pass
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
# stuff only to run when not called via 'import' here
|
||||||
|
main()
|
|
@ -659,8 +659,8 @@ t = Teacher(data)
|
||||||
#ar = ['2022rkhondak','2022inafi','2023rumareti']
|
#ar = ['2022rkhondak','2022inafi','2023rumareti']
|
||||||
#extra = t.reqAddStudentList(ar, "APLit_eharris1")
|
#extra = t.reqAddStudentList(ar, "APLit_eharris1")
|
||||||
#print(extra)
|
#print(extra)
|
||||||
t.getStudents('2022rkhondak')
|
# t.getStudents('2022rkhondak')
|
||||||
t.getChanges('2022rkhondak','APLit_eharris1', 10)
|
# t.getChanges('2022rkhondak','APLit_eharris1', 10)
|
||||||
|
|
||||||
'''
|
'''
|
||||||
TO-DO
|
TO-DO
|
|
@ -1,3 +1,16 @@
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
from .models import (
|
||||||
|
DefFiles,
|
||||||
|
Assignment,
|
||||||
|
Classes,
|
||||||
|
Teacher,
|
||||||
|
Student
|
||||||
|
)
|
||||||
|
|
||||||
# Register your models here.
|
# Register your models here.
|
||||||
|
|
||||||
|
admin.site.register(Teacher)
|
||||||
|
admin.site.register(Student)
|
||||||
|
admin.site.register(DefFiles)
|
||||||
|
admin.site.register(Assignment)
|
||||||
|
admin.site.register(Classes)
|
||||||
|
|
|
@ -1,128 +1,128 @@
|
||||||
from datetime import datetime
|
# from datetime import datetime
|
||||||
|
#
|
||||||
f1 = DefFiles(
|
# f1 = DefFiles(
|
||||||
name="instructions.txt"
|
# name="instructions.txt"
|
||||||
)
|
# )
|
||||||
f1.save()
|
# f1.save()
|
||||||
f2 = DefFiles(
|
# f2 = DefFiles(
|
||||||
name="instructions.txt"
|
# name="instructions.txt"
|
||||||
)
|
# )
|
||||||
f2.save()
|
# f2.save()
|
||||||
f3 = DefFiles(
|
# f3 = DefFiles(
|
||||||
name="sample.txt"
|
# name="sample.txt"
|
||||||
)
|
# )
|
||||||
f3.save()
|
# f3.save()
|
||||||
f4 = DefFiles(
|
# f4 = DefFiles(
|
||||||
name="rubric.txt"
|
# name="rubric.txt"
|
||||||
)
|
# )
|
||||||
f4.save()
|
# f4.save()
|
||||||
|
#
|
||||||
a1 = Assignment.objects.get(pk=1)
|
# a1 = Assignment.objects.get(pk=1)
|
||||||
a1.files.add(f1)
|
# a1.files.add(f1)
|
||||||
a1.save()
|
# a1.save()
|
||||||
a2 = Assignment.objects.get(pk=2)
|
# a2 = Assignment.objects.get(pk=2)
|
||||||
a2.files.add(f2)
|
# a2.files.add(f2)
|
||||||
a2.save()
|
# a2.save()
|
||||||
a3 = Assignment.objects.get(pk=3)
|
# a3 = Assignment.objects.get(pk=3)
|
||||||
a3.files.add(f3)
|
# a3.files.add(f3)
|
||||||
a3.files.add(f4)
|
# a3.files.add(f4)
|
||||||
a3.save()
|
# a3.save()
|
||||||
|
#
|
||||||
####################################
|
# ####################################
|
||||||
|
#
|
||||||
from api.models import Assignment, Student, Classes, Teacher, DefFiles
|
# from api.models import Assignment, Student, Classes, Teacher, DefFiles
|
||||||
from datetime import datetime
|
# from datetime import datetime
|
||||||
|
#
|
||||||
f1 = DefFiles(
|
# f1 = DefFiles(
|
||||||
name="instructions.txt"
|
# name="instructions.txt"
|
||||||
)
|
# )
|
||||||
f1.save()
|
# f1.save()
|
||||||
f2 = DefFiles(
|
# f2 = DefFiles(
|
||||||
name="instructions.txt"
|
# name="instructions.txt"
|
||||||
)
|
# )
|
||||||
f2.save()
|
# f2.save()
|
||||||
f3 = DefFiles(
|
# f3 = DefFiles(
|
||||||
name="sample.txt"
|
# name="sample.txt"
|
||||||
)
|
# )
|
||||||
f3.save()
|
# f3.save()
|
||||||
f4 = DefFiles(
|
# f4 = DefFiles(
|
||||||
name="rubric.txt"
|
# name="rubric.txt"
|
||||||
)
|
# )
|
||||||
f4.save()
|
# f4.save()
|
||||||
|
#
|
||||||
A1 = Assignment(
|
# A1 = Assignment(
|
||||||
name='Week1_HW',
|
# name='Week1_HW',
|
||||||
due_date=datetime.now(),
|
# due_date=datetime.now(),
|
||||||
)
|
# )
|
||||||
A1.save()
|
# A1.save()
|
||||||
A1.files.add(f1)
|
# A1.files.add(f1)
|
||||||
A1.save()
|
# A1.save()
|
||||||
|
#
|
||||||
A2 = Assignment(
|
# A2 = Assignment(
|
||||||
name='Week2_HW',
|
# name='Week2_HW',
|
||||||
due_date=datetime.now(),
|
# due_date=datetime.now(),
|
||||||
|
#
|
||||||
)
|
# )
|
||||||
A2.save()
|
# A2.save()
|
||||||
A2.files.add(f2)
|
# A2.files.add(f2)
|
||||||
A2.save()
|
# A2.save()
|
||||||
|
#
|
||||||
A3 = Assignment(
|
# A3 = Assignment(
|
||||||
name='Journal1',
|
# name='Journal1',
|
||||||
due_date=datetime.now(),
|
# due_date=datetime.now(),
|
||||||
)
|
# )
|
||||||
A3.save()
|
# A3.save()
|
||||||
A3.files.add(f3)
|
# A3.files.add(f3)
|
||||||
A3.files.add(f4)
|
# A3.files.add(f4)
|
||||||
A3.save()
|
# A3.save()
|
||||||
|
#
|
||||||
#classes
|
# #classes
|
||||||
math = Classes(
|
# math = Classes(
|
||||||
name='Math5',
|
# name='Math5',
|
||||||
|
#
|
||||||
)
|
# )
|
||||||
math.save()
|
# math.save()
|
||||||
math.assignments.add(A1)
|
# math.assignments.add(A1)
|
||||||
math.assignments.add(A2)
|
# math.assignments.add(A2)
|
||||||
math.save()
|
# math.save()
|
||||||
|
#
|
||||||
english = Classes(
|
# english = Classes(
|
||||||
name='English',
|
# name='English',
|
||||||
)
|
# )
|
||||||
english.save()
|
# english.save()
|
||||||
english.assignments.add(A3)
|
# english.assignments.add(A3)
|
||||||
english.save()
|
# english.save()
|
||||||
|
#
|
||||||
#students
|
# #students
|
||||||
raffu = Student(
|
# raffu = Student(
|
||||||
first_name = "Raffu",
|
# first_name = "Raffu",
|
||||||
last_name = "Khondaker",
|
# last_name = "Khondaker",
|
||||||
student_id = 1579460,
|
# student_id = 1579460,
|
||||||
ion_user="2022rkhondak",
|
# ion_user="2022rkhondak",
|
||||||
webmail = "2022rkhondak@tjhsst.edu",
|
# webmail = "2022rkhondak@tjhsst.edu",
|
||||||
grade = 10,
|
# grade = 10,
|
||||||
repo="https://github.com/therealraffi/2022rkhondak.git",
|
# repo="https://github.com/therealraffi/2022rkhondak.git",
|
||||||
)
|
# )
|
||||||
raffu.save()
|
# raffu.save()
|
||||||
raffu.classes.add(math)
|
# raffu.classes.add(math)
|
||||||
raffu.classes.add(english)
|
# raffu.classes.add(english)
|
||||||
raffu.save()
|
# raffu.save()
|
||||||
|
#
|
||||||
#teachers
|
# #teachers
|
||||||
ng = Teacher(
|
# ng = Teacher(
|
||||||
first_name = "Errin",
|
# first_name = "Errin",
|
||||||
last_name = "Harris",
|
# last_name = "Harris",
|
||||||
ion_user="eharris1"
|
# ion_user="eharris1"
|
||||||
)
|
# )
|
||||||
ng.save()
|
# ng.save()
|
||||||
ng.classes.add(math)
|
# ng.classes.add(math)
|
||||||
ng.save()
|
# ng.save()
|
||||||
|
#
|
||||||
chao = Teacher(
|
# chao = Teacher(
|
||||||
first_name = "Abagail",
|
# first_name = "Abagail",
|
||||||
last_name = "Bailey",
|
# last_name = "Bailey",
|
||||||
ion_user="AKBailey"
|
# ion_user="AKBailey"
|
||||||
)
|
# )
|
||||||
chao.save()
|
# chao.save()
|
||||||
chao.classes.add(english)
|
# chao.classes.add(english)
|
||||||
chao.save()
|
# chao.save()
|
||||||
|
|
|
@ -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
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
@ -8,33 +10,10 @@ class Migration(migrations.Migration):
|
||||||
initial = True
|
initial = True
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
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(
|
migrations.CreateModel(
|
||||||
name='DefFiles',
|
name='DefFiles',
|
||||||
fields=[
|
fields=[
|
||||||
|
@ -46,23 +25,6 @@ class Migration(migrations.Migration):
|
||||||
('teacher', models.CharField(max_length=100)),
|
('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(
|
migrations.CreateModel(
|
||||||
name='Teacher',
|
name='Teacher',
|
||||||
fields=[
|
fields=[
|
||||||
|
@ -73,6 +35,41 @@ class Migration(migrations.Migration):
|
||||||
('ion_user', models.CharField(max_length=100, primary_key=True, serialize=False)),
|
('ion_user', models.CharField(max_length=100, primary_key=True, serialize=False)),
|
||||||
('git', models.CharField(max_length=100)),
|
('git', models.CharField(max_length=100)),
|
||||||
('email', models.CharField(blank=True, default='', 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)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -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),
|
|
||||||
),
|
|
||||||
]
|
|
52
Website/api/migrations/0002_auto_20200614_2034.py
Normal file
52
Website/api/migrations/0002_auto_20200614_2034.py
Normal 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),
|
||||||
|
),
|
||||||
|
]
|
|
@ -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),
|
|
||||||
),
|
|
||||||
]
|
|
43
Website/api/migrations/0003_auto_20200614_2044.py
Normal file
43
Website/api/migrations/0003_auto_20200614_2044.py
Normal 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),
|
||||||
|
),
|
||||||
|
]
|
|
@ -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=''),
|
|
||||||
),
|
|
||||||
]
|
|
18
Website/api/migrations/0004_auto_20200614_2107.py
Normal file
18
Website/api/migrations/0004_auto_20200614_2107.py
Normal 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),
|
||||||
|
),
|
||||||
|
]
|
|
@ -1,4 +1,5 @@
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
from django.contrib.auth.models import User
|
||||||
|
|
||||||
class DefFiles(models.Model):
|
class DefFiles(models.Model):
|
||||||
name=models.CharField(max_length=100)
|
name=models.CharField(max_length=100)
|
||||||
|
@ -8,6 +9,8 @@ class DefFiles(models.Model):
|
||||||
teacher=models.CharField(max_length=100)
|
teacher=models.CharField(max_length=100)
|
||||||
|
|
||||||
class Assignment(models.Model):
|
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)
|
name=models.CharField(max_length=100, primary_key=True)
|
||||||
due_date=models.DateTimeField()
|
due_date=models.DateTimeField()
|
||||||
# files = models.ManyToManyField(DefFiles)
|
# files = models.ManyToManyField(DefFiles)
|
||||||
|
@ -19,6 +22,8 @@ class Assignment(models.Model):
|
||||||
return '%s' % (self.name)
|
return '%s' % (self.name)
|
||||||
|
|
||||||
class Classes(models.Model):
|
class Classes(models.Model):
|
||||||
|
user = models.OneToOneField(User, on_delete=models.CASCADE)
|
||||||
|
|
||||||
name = models.CharField(primary_key=True, max_length=100)
|
name = models.CharField(primary_key=True, max_length=100)
|
||||||
repo=models.URLField(default="", blank=True)
|
repo=models.URLField(default="", blank=True)
|
||||||
path=models.CharField(max_length=100, default="")
|
path=models.CharField(max_length=100, default="")
|
||||||
|
@ -34,31 +39,26 @@ class Classes(models.Model):
|
||||||
return super(Classes, self).save(*args, **kwargs)
|
return super(Classes, self).save(*args, **kwargs)
|
||||||
|
|
||||||
class Teacher(models.Model):
|
class Teacher(models.Model):
|
||||||
created = models.DateTimeField(auto_now_add=True)
|
user = models.OneToOneField(User, on_delete=models.CASCADE)
|
||||||
first_name = models.CharField(max_length=100)
|
|
||||||
last_name = models.CharField(max_length=100)
|
|
||||||
# classes = models.ManyToManyField(Classes, default="")
|
# classes = models.ManyToManyField(Classes, default="")
|
||||||
classes=models.CharField(max_length=100, default="", blank=True)
|
classes=models.CharField(max_length=100, default="", blank=True)
|
||||||
ion_user=models.CharField(primary_key=True, max_length=100)
|
ion_user=models.CharField(primary_key=True, max_length=100)
|
||||||
git=models.CharField(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):
|
class Student(models.Model):
|
||||||
created = models.DateTimeField(auto_now_add=True)
|
user = models.OneToOneField(User, on_delete=models.CASCADE)
|
||||||
first_name = models.CharField(max_length=100)
|
grade = models.IntegerField(default=0, blank=True)
|
||||||
last_name = models.CharField(max_length=100)
|
git=models.CharField(default="", max_length=100, blank=True)
|
||||||
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)
|
|
||||||
repo=models.URLField(default="", blank=True)
|
repo=models.URLField(default="", blank=True)
|
||||||
classes=models.CharField(max_length=100, default="", blank=True)
|
classes=models.CharField(max_length=100, default="", blank=True)
|
||||||
added_to=models.CharField(max_length=100, default="", blank=True)
|
added_to=models.CharField(max_length=100, default="", blank=True)
|
||||||
completed=models.TextField(default="", blank=True)
|
completed=models.TextField(default="", blank=True)
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
return super(Student, self).save(*args, **kwargs)
|
super(Student, self).save(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"{self.user.username}'s Profile"
|
||||||
|
|
25
Website/api/permissions.py
Normal file
25
Website/api/permissions.py
Normal 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
|
|
@ -1,37 +1,55 @@
|
||||||
from django.contrib.auth.models import User, Group
|
from django.contrib.auth.models import User, Group
|
||||||
from .models import Student, Teacher, Classes, Assignment, DefFiles
|
from .models import Student, Teacher, Classes, Assignment, DefFiles
|
||||||
from rest_framework import serializers, permissions
|
from rest_framework import serializers, permissions
|
||||||
|
from django.contrib.auth.models import User
|
||||||
|
from .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:
|
class Meta:
|
||||||
model = DefFiles
|
model = User
|
||||||
fields = ['name', 'path','assignment','classes', "teacher",'url', 'id']
|
fields = ['id', 'username']
|
||||||
|
|
||||||
|
# class DefFilesSerializer(serializers.HyperlinkedModelSerializer):
|
||||||
|
# class Meta:
|
||||||
|
# model = DefFiles
|
||||||
|
# fields = ['name', 'path','assignment','classes', "teacher",'url', 'id']
|
||||||
|
|
||||||
class AssignmentSerializer(serializers.HyperlinkedModelSerializer):
|
class AssignmentSerializer(serializers.HyperlinkedModelSerializer):
|
||||||
#permissions_classes = [permissions.IsAuthenticatedOrReadOnly]
|
#permissions_classes = [permissions.IsAuthenticatedOrReadOnly]
|
||||||
# files = DefFilesSerializer(many=True, read_only=True,allow_null=True)
|
# files = DefFilesSerializer(many=True, read_only=True,allow_null=True)
|
||||||
|
owner = serializers.ReadOnlyField(source='owner.username')
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Assignment
|
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):
|
class ClassesSerializer(serializers.HyperlinkedModelSerializer):
|
||||||
# assignments = AssignmentSerializer(many=True, read_only=True,allow_null=True)
|
# assignments = AssignmentSerializer(many=True, read_only=True,allow_null=True)
|
||||||
# default_file=DefFilesSerializer(many=True, read_only=True,allow_null=True)
|
# default_file=DefFilesSerializer(many=True, read_only=True,allow_null=True)
|
||||||
|
owner = serializers.ReadOnlyField(source='owner.username')
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Classes
|
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):
|
class StudentSerializer(serializers.HyperlinkedModelSerializer):
|
||||||
# classes = ClassesSerializer(many=True, read_only=True,allow_null=True)
|
# classes = ClassesSerializer(many=True, read_only=True,allow_null=True)
|
||||||
|
owner = serializers.ReadOnlyField(source='owner.username')
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Student
|
model = Student
|
||||||
fields = ['url', 'first_name', 'last_name', 'grade','email','student_id', 'git','ion_user','classes','added_to','completed', 'repo']
|
# fields = ['url','first_name', 'last_name', 'grade','email','student_id', 'git','ion_user','classes','added_to','completed', 'repo','owner']
|
||||||
|
fields = ['first_name', 'last_name', 'grade','email','student_id', 'git','ion_user','classes','added_to','completed', 'repo','owner']
|
||||||
|
|
||||||
class TeacherSerializer(serializers.ModelSerializer):
|
class TeacherSerializer(serializers.ModelSerializer):
|
||||||
# classes = ClassesSerializer(many=True, read_only=True,allow_null=True)
|
# classes = ClassesSerializer(many=True, read_only=True,allow_null=True)
|
||||||
|
owner = serializers.ReadOnlyField(source='owner.username')
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Teacher
|
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
5
Website/api/signals.py
Normal 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
|
||||||
|
)
|
|
@ -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)
|
|
@ -1,131 +1,89 @@
|
||||||
# class StudentList(APIView):
|
from .models import Student, Teacher, Classes, Assignment, DefFiles
|
||||||
# """
|
from .serializers import StudentSerializer, TeacherSerializer, ClassesSerializer, AssignmentSerializer, UserSerializer
|
||||||
# List all snippets, or create a new snippet.
|
from rest_framework import generics, viewsets, permissions, response, status
|
||||||
# """
|
from django.http import Http404
|
||||||
# def get(self, request, format=None):
|
from rest_framework.views import APIView
|
||||||
# snippets = Student.objects.all()
|
from django.contrib.auth.models import User
|
||||||
# serializer = StudentSerializer(snippets, many=True)
|
from .permissions import isTeacher, IsOwnerOrReadOnly
|
||||||
# return response.Response(serializer.data)
|
from django.shortcuts import render, redirect
|
||||||
|
from rest_framework.parsers import JSONParser
|
||||||
|
from django.http.response import JsonResponse
|
||||||
|
from rest_framework.response import Response
|
||||||
|
from rest_framework import mixins
|
||||||
|
|
||||||
# def post(self, request, format=None):
|
|
||||||
# serializer = StudentSerializer(data=request.data)
|
|
||||||
# if serializer.is_valid():
|
|
||||||
# serializer.save()
|
|
||||||
# return response.Response(serializer.data, status=status.HTTP_201_CREATED)
|
|
||||||
# return response.Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
|
||||||
|
|
||||||
# class StudentDetail(APIView):
|
class StudentList(generics.ListCreateAPIView):
|
||||||
# """
|
queryset = Student.objects.all()
|
||||||
# Retrieve, update or delete a snippet instance.
|
serializer_class = StudentSerializer
|
||||||
# """
|
def perform_create(self, serializer):
|
||||||
# def get_object(self, pk):
|
serializer.save(owner=self.request.user)
|
||||||
# try:
|
|
||||||
# return Student.objects.get(pk=pk)
|
|
||||||
# except Student.DoesNotExist:
|
|
||||||
# raise Http404
|
|
||||||
|
|
||||||
# def get(self, request, pk, format=None):
|
class StudentDetail(generics.RetrieveAPIView):
|
||||||
# snippet = self.get_object(pk)
|
queryset = Student.objects.all()
|
||||||
# serializer = StudentSerializer(snippet)
|
serializer_class = StudentSerializer
|
||||||
# return response.Response(serializer.data)
|
permissions_classes = [permissions.IsAuthenticated, IsOwnerOrReadOnly]
|
||||||
|
|
||||||
# def put(self, request, pk, format=None):
|
class TeacherList(generics.ListCreateAPIView):
|
||||||
# snippet = self.get_object(pk)
|
queryset = Teacher.objects.all()
|
||||||
# serializer = StudentSerializer(snippet, data=request.data)
|
serializer_class = TeacherSerializer
|
||||||
# if serializer.is_valid():
|
def perform_create(self, serializer):
|
||||||
# serializer.save()
|
if(self.request.user.groups.filter(name__in=['teachers']).exists() or self.request.user.is_superuser):
|
||||||
# return response.Response(serializer.data)
|
serializer.save(owner=self.request.user)
|
||||||
# return response.Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
else:
|
||||||
|
print("UNAUTHORIZED POST")
|
||||||
|
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
# def delete(self, request, pk, format=None):
|
class TeacherDetail(generics.RetrieveAPIView):
|
||||||
# snippet = self.get_object(pk)
|
queryset = Teacher.objects.all()
|
||||||
# snippet.delete()
|
serializer_class = TeacherSerializer
|
||||||
# return response.Response(status=status.HTTP_204_NO_CONTENT)
|
permissions_classes = [permissions.IsAuthenticated, IsOwnerOrReadOnly]
|
||||||
|
|
||||||
# class TeacherList(APIView):
|
|
||||||
# """
|
|
||||||
# List all snippets, or create a new snippet.
|
|
||||||
# """
|
|
||||||
# def get(self, request, format=None):
|
|
||||||
# snippets = Teacher.objects.all()
|
|
||||||
# serializer = TeacherSerializer(snippets, many=True)
|
|
||||||
# return response.Response(serializer.data)
|
|
||||||
|
|
||||||
# def post(self, request, format=None):
|
|
||||||
# serializer = TeacherSerializer(data=request.data)
|
|
||||||
# if serializer.is_valid():
|
|
||||||
# serializer.save()
|
|
||||||
# return response.Response(serializer.data, status=status.HTTP_201_CREATED)
|
|
||||||
# return response.Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
|
||||||
|
|
||||||
# class TeacherDetail(APIView):
|
|
||||||
# """
|
|
||||||
# Retrieve, update or delete a snippet instance.
|
|
||||||
# """
|
|
||||||
# def get_object(self, pk):
|
|
||||||
# try:
|
|
||||||
# return Teacher.objects.get(pk=pk)
|
|
||||||
# except Teacher.DoesNotExist:
|
|
||||||
# raise Http404
|
|
||||||
|
|
||||||
# def get(self, request, pk, format=None):
|
|
||||||
# snippet = self.get_object(pk)
|
|
||||||
# serializer = TeacherSerializer(snippet)
|
|
||||||
# return response.Response(serializer.data)
|
|
||||||
|
|
||||||
# def put(self, request, pk, format=None):
|
|
||||||
# snippet = self.get_object(pk)
|
|
||||||
# serializer = TeacherSerializer(snippet, data=request.data)
|
|
||||||
# if serializer.is_valid():
|
|
||||||
# serializer.save()
|
|
||||||
# return response.Response(serializer.data)
|
|
||||||
# return response.Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
|
||||||
|
|
||||||
# def delete(self, request, pk, format=None):
|
|
||||||
# snippet = self.get_object(pk)
|
|
||||||
# snippet.delete()
|
|
||||||
# return response.Response(status=status.HTTP_204_NO_CONTENT)
|
|
||||||
|
|
||||||
# class ClassesList(APIView):
|
class ClassesList(generics.ListCreateAPIView):
|
||||||
# """
|
queryset = Classes.objects.all()
|
||||||
# List all snippets, or create a new snippet.
|
serializer_class = ClassesSerializer
|
||||||
# """
|
#permissions_classes = [isTeacher]
|
||||||
# def get(self, request, format=None):
|
def perform_create(self, serializer):
|
||||||
# snippets = Classes.objects.all()
|
if(self.request.user.groups.filter(name__in=['teachers']).exists() or self.request.user.is_superuser):
|
||||||
# serializer = ClassesSerializer(snippets, many=True)
|
serializer.save(owner=self.request.user)
|
||||||
# return response.Response(serializer.data)
|
else:
|
||||||
|
print("UNAUTHORIZED POST")
|
||||||
|
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
# def post(self, request, format=None):
|
# class ClassesDetail(generics.RetrieveAPIView):
|
||||||
# serializer = ClassesSerializer(data=request.data)
|
# queryset = Classes.objects.all()
|
||||||
# if serializer.is_valid():
|
# serializer_class = ClassesSerializer
|
||||||
# serializer.save()
|
# # permissions_classes = [permissions.IsAuthenticated, IsOwnerOrReadOnly]
|
||||||
# return response.Response(serializer.data, status=status.HTTP_201_CREATED)
|
|
||||||
# return response.Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
|
||||||
|
|
||||||
# class ClassesDetail(APIView):
|
class ClassesDetail(mixins.RetrieveModelMixin,
|
||||||
# """
|
mixins.UpdateModelMixin,
|
||||||
# Retrieve, update or delete a snippet instance.
|
mixins.DestroyModelMixin,
|
||||||
# """
|
generics.GenericAPIView):
|
||||||
# def get_object(self, pk):
|
queryset = Classes.objects.all()
|
||||||
# try:
|
serializer_class = ClassesSerializer
|
||||||
# return Classes.objects.get(pk=pk)
|
|
||||||
# except Classes.DoesNotExist:
|
|
||||||
# raise Http404
|
|
||||||
|
|
||||||
# def get(self, request, pk, format=None):
|
def get(self, request, *args, **kwargs):
|
||||||
# snippet = self.get_object(pk)
|
return self.retrieve(request, *args, **kwargs)
|
||||||
# serializer = ClassesSerializer(snippet)
|
|
||||||
# return response.Response(serializer.data)
|
|
||||||
|
|
||||||
# def put(self, request, pk, format=None):
|
def put(self, request, *args, **kwargs):
|
||||||
# snippet = self.get_object(pk)
|
print(self.owner)
|
||||||
# serializer = ClassesSerializer(snippet, data=request.data)
|
if(request.user == self.owner):
|
||||||
# if serializer.is_valid():
|
return self.update(request, *args, **kwargs)
|
||||||
# serializer.save()
|
|
||||||
# return response.Response(serializer.data)
|
|
||||||
# return response.Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
|
||||||
|
|
||||||
# def delete(self, request, pk, format=None):
|
def delete(self, request, *args, **kwargs):
|
||||||
# snippet = self.get_object(pk)
|
return self.destroy(request, *args, **kwargs)
|
||||||
# snippet.delete()
|
|
||||||
# return response.Response(status=status.HTTP_204_NO_CONTENT)
|
class AssignmentList(generics.ListCreateAPIView):
|
||||||
|
queryset = Assignment.objects.all()
|
||||||
|
serializer_class = AssignmentSerializer
|
||||||
|
def perform_create(self, serializer):
|
||||||
|
if(self.request.user.groups.filter(name__in=['teachers']).exists() or self.request.user.is_superuser):
|
||||||
|
serializer.save(owner=self.request.user)
|
||||||
|
else:
|
||||||
|
print("UNAUTHORIZED POST")
|
||||||
|
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
|
class AssignmentDetail(generics.RetrieveAPIView):
|
||||||
|
queryset = Assignment.objects.all()
|
||||||
|
serializer_class = AssignmentSerializer
|
||||||
|
permissions_classes = [permissions.IsAuthenticated, IsOwnerOrReadOnly]
|
||||||
|
|
|
@ -1,8 +1,21 @@
|
||||||
from .models import Student, Teacher, Classes, Assignment, DefFiles
|
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 rest_framework import generics, viewsets, permissions, response, status
|
||||||
from django.http import Http404
|
from django.http import Http404
|
||||||
from rest_framework.views import APIView
|
from rest_framework.views import APIView
|
||||||
|
from django.contrib.auth.models import User
|
||||||
|
from .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):
|
class StudentViewSet(viewsets.ModelViewSet):
|
||||||
"""
|
"""
|
||||||
|
@ -10,8 +23,10 @@ class StudentViewSet(viewsets.ModelViewSet):
|
||||||
"""
|
"""
|
||||||
queryset = Student.objects.all()
|
queryset = Student.objects.all()
|
||||||
serializer_class = StudentSerializer
|
serializer_class = StudentSerializer
|
||||||
permissions_classes = [permissions.IsAuthenticatedOrReadOnly]
|
permission_classes = [permissions.IsAuthenticated, IsOwnerOrReadOnly]
|
||||||
|
|
||||||
|
def perform_create(self, serializer):
|
||||||
|
serializer.save(owner=self.request.user)
|
||||||
|
|
||||||
class TeacherViewSet(viewsets.ModelViewSet):
|
class TeacherViewSet(viewsets.ModelViewSet):
|
||||||
"""
|
"""
|
||||||
|
@ -19,8 +34,10 @@ class TeacherViewSet(viewsets.ModelViewSet):
|
||||||
"""
|
"""
|
||||||
queryset = Teacher.objects.all()
|
queryset = Teacher.objects.all()
|
||||||
serializer_class = TeacherSerializer
|
serializer_class = TeacherSerializer
|
||||||
permissions_classes = [permissions.IsAuthenticatedOrReadOnly]
|
permission_classes = [permissions.IsAuthenticated, IsOwnerOrReadOnly]
|
||||||
|
|
||||||
|
def perform_create(self, serializer):
|
||||||
|
serializer.save(owner=self.request.user)
|
||||||
|
|
||||||
class ClassesViewSet(viewsets.ModelViewSet):
|
class ClassesViewSet(viewsets.ModelViewSet):
|
||||||
"""
|
"""
|
||||||
|
@ -28,7 +45,14 @@ class ClassesViewSet(viewsets.ModelViewSet):
|
||||||
"""
|
"""
|
||||||
queryset = Classes.objects.all()
|
queryset = Classes.objects.all()
|
||||||
serializer_class = ClassesSerializer
|
serializer_class = ClassesSerializer
|
||||||
permissions_classes = [permissions.IsAuthenticatedOrReadOnly]
|
permission_classes = [permissions.IsAuthenticated, IsOwnerOrReadOnly]
|
||||||
|
|
||||||
|
def perform_create(self, serializer):
|
||||||
|
if(self.request.user.groups.filter(name__in=['teachers']).exists() or self.request.user.is_superuser):
|
||||||
|
serializer.save(owner=self.request.user)
|
||||||
|
else:
|
||||||
|
print("UNAUTHORIZED POST")
|
||||||
|
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
|
|
||||||
class AssignmentViewSet(viewsets.ModelViewSet):
|
class AssignmentViewSet(viewsets.ModelViewSet):
|
||||||
|
@ -37,12 +61,19 @@ class AssignmentViewSet(viewsets.ModelViewSet):
|
||||||
"""
|
"""
|
||||||
queryset = Assignment.objects.all()
|
queryset = Assignment.objects.all()
|
||||||
serializer_class = AssignmentSerializer
|
serializer_class = AssignmentSerializer
|
||||||
permissions_classes = [permissions.IsAuthenticatedOrReadOnly]
|
permission_classes = [permissions.IsAuthenticated, isTeacher, IsOwnerOrReadOnly]
|
||||||
|
|
||||||
class DefFilesViewSet(viewsets.ModelViewSet):
|
def perform_create(self, serializer):
|
||||||
"""
|
if(self.request.user.groups.filter(name__in=['teachers']).exists() or self.request.user.is_superuser):
|
||||||
API endpoint that allows users to be viewed or edited.
|
serializer.save(owner=self.request.user)
|
||||||
"""
|
else:
|
||||||
queryset = DefFiles.objects.all()
|
print("UNAUTHORIZED POST")
|
||||||
serializer_class = DefFilesSerializer
|
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||||
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]
|
||||||
|
|
|
@ -11,6 +11,6 @@ import os
|
||||||
|
|
||||||
from django.core.asgi import get_asgi_application
|
from django.core.asgi import get_asgi_application
|
||||||
|
|
||||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'skoolos.settings')
|
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')
|
||||||
|
|
||||||
application = get_asgi_application()
|
application = get_asgi_application()
|
|
@ -31,6 +31,7 @@ ALLOWED_HOSTS = []
|
||||||
# Application definition
|
# Application definition
|
||||||
|
|
||||||
INSTALLED_APPS = [
|
INSTALLED_APPS = [
|
||||||
|
'skoolos.apps.SkoolosConfig',
|
||||||
'users.apps.UsersConfig',
|
'users.apps.UsersConfig',
|
||||||
'django.contrib.admin',
|
'django.contrib.admin',
|
||||||
'django.contrib.auth',
|
'django.contrib.auth',
|
||||||
|
@ -41,8 +42,7 @@ INSTALLED_APPS = [
|
||||||
'rest_framework',
|
'rest_framework',
|
||||||
'api',
|
'api',
|
||||||
'crispy_forms',
|
'crispy_forms',
|
||||||
|
'django_forms_bootstrap',
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
||||||
REST_FRAMEWORK = {
|
REST_FRAMEWORK = {
|
||||||
|
@ -63,7 +63,7 @@ MIDDLEWARE = [
|
||||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||||
]
|
]
|
||||||
|
|
||||||
ROOT_URLCONF = 'skoolos.urls'
|
ROOT_URLCONF = 'config.urls'
|
||||||
|
|
||||||
TEMPLATES = [
|
TEMPLATES = [
|
||||||
{
|
{
|
||||||
|
@ -81,7 +81,7 @@ TEMPLATES = [
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
WSGI_APPLICATION = 'skoolos.wsgi.application'
|
WSGI_APPLICATION = 'config.wsgi.application'
|
||||||
|
|
||||||
|
|
||||||
# Database
|
# Database
|
||||||
|
@ -135,4 +135,6 @@ STATIC_URL = '/static/'
|
||||||
|
|
||||||
CRISPY_TEMPLATE_PACK = 'bootstrap4'
|
CRISPY_TEMPLATE_PACK = 'bootstrap4'
|
||||||
|
|
||||||
LOGIN_REDIRECT_URL = '/'
|
LOGIN_REDIRECT_URL = '/'
|
||||||
|
|
||||||
|
LOGIN_URL = '/login'
|
31
Website/config/urls.py
Normal file
31
Website/config/urls.py
Normal 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'),
|
||||||
|
]
|
|
@ -11,6 +11,6 @@ import os
|
||||||
|
|
||||||
from django.core.wsgi import get_wsgi_application
|
from django.core.wsgi import get_wsgi_application
|
||||||
|
|
||||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'skoolos.settings')
|
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')
|
||||||
|
|
||||||
application = get_wsgi_application()
|
application = get_wsgi_application()
|
|
@ -5,7 +5,7 @@ import sys
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'skoolos.settings')
|
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')
|
||||||
try:
|
try:
|
||||||
from django.core.management import execute_from_command_line
|
from django.core.management import execute_from_command_line
|
||||||
except ImportError as exc:
|
except ImportError as exc:
|
||||||
|
|
3
Website/skoolos/admin.py
Normal file
3
Website/skoolos/admin.py
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
from django.contrib import admin
|
||||||
|
|
||||||
|
# Register your models here.
|
5
Website/skoolos/apps.py
Normal file
5
Website/skoolos/apps.py
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
|
class SkoolosConfig(AppConfig):
|
||||||
|
name = 'skoolos'
|
3
Website/skoolos/models.py
Normal file
3
Website/skoolos/models.py
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
from django.db import models
|
||||||
|
|
||||||
|
# Create your models here.
|
BIN
Website/skoolos/static/skoolos/Segoe UI Bold Italic.ttf
Normal file
BIN
Website/skoolos/static/skoolos/Segoe UI Bold Italic.ttf
Normal file
Binary file not shown.
BIN
Website/skoolos/static/skoolos/Segoe UI Bold.ttf
Normal file
BIN
Website/skoolos/static/skoolos/Segoe UI Bold.ttf
Normal file
Binary file not shown.
BIN
Website/skoolos/static/skoolos/Segoe UI Italic.ttf
Normal file
BIN
Website/skoolos/static/skoolos/Segoe UI Italic.ttf
Normal file
Binary file not shown.
BIN
Website/skoolos/static/skoolos/Segoe UI.ttf
Normal file
BIN
Website/skoolos/static/skoolos/Segoe UI.ttf
Normal file
Binary file not shown.
BIN
Website/skoolos/static/skoolos/futura.ttf
Normal file
BIN
Website/skoolos/static/skoolos/futura.ttf
Normal file
Binary file not shown.
100
Website/skoolos/static/skoolos/styles.css
Normal file
100
Website/skoolos/static/skoolos/styles.css
Normal 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;
|
||||||
|
}
|
52
Website/skoolos/templates/skoolos/base.html
Normal file
52
Website/skoolos/templates/skoolos/base.html
Normal 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>
|
3
Website/skoolos/templates/skoolos/home.html
Normal file
3
Website/skoolos/templates/skoolos/home.html
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
{% extends "skoolos/base.html" %}
|
||||||
|
{% block content %}
|
||||||
|
{% endblock content %}
|
3
Website/skoolos/tests.py
Normal file
3
Website/skoolos/tests.py
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
# Create your tests here.
|
|
@ -1,23 +1,9 @@
|
||||||
from django.urls import path
|
from django.urls import path
|
||||||
from rest_framework import routers
|
|
||||||
from api import views as api_views
|
|
||||||
from django.contrib import admin
|
|
||||||
from django.conf.urls import include
|
|
||||||
from django.contrib.auth import views as auth_views
|
|
||||||
|
|
||||||
router = routers.DefaultRouter()
|
from . import views
|
||||||
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)
|
|
||||||
|
|
||||||
|
|
||||||
# Wire up our API using automatic URL routing.
|
|
||||||
# Additionally, we include login URLs for the browsable API.
|
# Additionally, we include login URLs for the browsable API.
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('api/', include(router.urls)),
|
path('', views.home, name='home'),
|
||||||
path('api-auth/', include('rest_framework.urls')),
|
path('profile/', views.profile, name='profile')
|
||||||
path('admin/', admin.site.urls),
|
]
|
||||||
path('login/', auth_views.LoginView.as_view(template_name="users/login.html"), name='login')
|
|
||||||
]
|
|
||||||
|
|
12
Website/skoolos/views.py
Normal file
12
Website/skoolos/views.py
Normal 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
|
|
@ -1,3 +1,5 @@
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
from .models import Token
|
||||||
|
|
||||||
# Register your models here.
|
# Register your models here.
|
||||||
|
admin.site.register(Token)
|
||||||
|
|
32
Website/users/forms.py
Normal file
32
Website/users/forms.py
Normal 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')
|
26
Website/users/migrations/0001_initial.py
Normal file
26
Website/users/migrations/0001_initial.py
Normal 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)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
18
Website/users/migrations/0002_auto_20200614_2044.py
Normal file
18
Website/users/migrations/0002_auto_20200614_2044.py
Normal 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),
|
||||||
|
),
|
||||||
|
]
|
18
Website/users/migrations/0003_token_grade.py
Normal file
18
Website/users/migrations/0003_token_grade.py
Normal 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),
|
||||||
|
),
|
||||||
|
]
|
|
@ -1,3 +1,22 @@
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
from uuid import uuid4
|
||||||
|
|
||||||
|
|
||||||
# Create your models here.
|
# 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
6
Website/users/pwd.py
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
import os
|
||||||
|
|
||||||
|
pwd = "heyyy"
|
||||||
|
path = os.getcwd()
|
||||||
|
p = os.path.join(path, '../../', 'pwd.txt')
|
||||||
|
open(p, 'w')
|
|
@ -99,6 +99,10 @@ body {
|
||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input:disabled {
|
||||||
|
background: #d9d9d9;
|
||||||
|
}
|
||||||
|
|
||||||
.errorlist {
|
.errorlist {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
{% block content %}{% endblock %}
|
{% block content %}{% endblock %}
|
||||||
a
|
|
||||||
<!-- Bootstrap JS -->
|
<!-- Bootstrap JS -->
|
||||||
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
|
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
|
||||||
|
|
22
Website/users/templates/users/create_account.html
Normal file
22
Website/users/templates/users/create_account.html
Normal 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 %}
|
|
@ -1,16 +1,38 @@
|
||||||
{% extends "users/base.html" %}
|
{% extends "users/base.html" %}
|
||||||
{% load crispy_forms_tags %}
|
{% load bootstrap_tags %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="login-page">
|
<div class="login-page">
|
||||||
<div class="form">
|
<div class="form">
|
||||||
<form class="login-form" method="POST">
|
<form class="login-form" method="POST">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{{ form | crispy }}
|
{% if messages %}
|
||||||
|
{% for message in messages %}
|
||||||
|
<div class="alert alert-{{ message.tags }} alert-dismissible fade show">
|
||||||
|
{{ message }}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% if form.errors %}
|
||||||
|
{% for field in form %}
|
||||||
|
{% for error in field.errors %}
|
||||||
|
<div class="alert alert-danger">
|
||||||
|
<strong>{{ error|escape }}</strong>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
{% endfor %}
|
||||||
|
{% for error in form.non_field_errors %}
|
||||||
|
<div class="alert alert-danger">
|
||||||
|
<strong>{{ error|escape }}</strong>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% for field in form %}
|
||||||
|
{{ field }}
|
||||||
|
{% endfor %}
|
||||||
<button type="submit">login</button>
|
<button type="submit">login</button>
|
||||||
<p class="message">Not registered? <a href="#">Create an account with Ionreg</a></p>
|
<p class="message">Not registered? <a href="{% url 'register' %}">Create an account with Ion</a></p>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{% endblock %}
|
||||||
{% endblock %}
|
|
||||||
|
|
|
@ -3,13 +3,20 @@
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="login-page">
|
<div class="login-page">
|
||||||
<div class="form">
|
<div class="form">
|
||||||
<form class="login-form" method="POST">
|
<div class="content-section">
|
||||||
{% csrf_token %}
|
{% if messages %}
|
||||||
{{ form | crispy }}
|
{% for message in messages %}
|
||||||
<button type="submit">login</button>
|
<div class="alert alert-{{ message.tags }} alert-dismissible fade show">
|
||||||
<p class="message">Not registered? <a href="#">Create an account with Ionreg</a></p>
|
{{ message }}
|
||||||
</form>
|
</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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -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.
|
# 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
BIN
chromedriver-linux
Executable file
Binary file not shown.
BIN
chromedriver.exe
Normal file
BIN
chromedriver.exe
Normal file
Binary file not shown.
|
@ -12,6 +12,7 @@ oauthlib==3.1.0
|
||||||
prompt-toolkit==1.0.14
|
prompt-toolkit==1.0.14
|
||||||
pyclipper==1.1.0.post3
|
pyclipper==1.1.0.post3
|
||||||
Pygments==2.6.1
|
Pygments==2.6.1
|
||||||
|
pyinotify==0.9.6
|
||||||
PyInquirer==1.0.3
|
PyInquirer==1.0.3
|
||||||
pyperclip==1.8.0
|
pyperclip==1.8.0
|
||||||
pytz==2020.1
|
pytz==2020.1
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
for i in range(0, 100000):
|
|
||||||
print(i)
|
|
242
skoolos.py
Normal file
242
skoolos.py
Normal 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()
|
Loading…
Reference in New Issue
Block a user