Skip to content

Commit

Permalink
adding complete support for multi-client and subject-exercise and exe…
Browse files Browse the repository at this point in the history
…rcise-task relations
  • Loading branch information
ooemperor committed Dec 7, 2023
1 parent 8f1519a commit c7dd32e
Show file tree
Hide file tree
Showing 16 changed files with 197 additions and 47 deletions.
4 changes: 2 additions & 2 deletions codeGrader/backend/db/Exercise.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ class Exercise(Base):
order_by="[Task.name]",
# cascade="all",
passive_deletes=True,
lazy="joined",
backref=backref("TaskExercise", lazy="noload")
lazy="subquery",
backref=backref("TaskExercise", lazy="joined")
)

def get_profile(self):
Expand Down
4 changes: 4 additions & 0 deletions codeGrader/backend/db/Task.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,10 @@ def toJson(self, recursive: bool = True) -> dict:
out["id"] = self.id
out["name"] = self.name
out["tag"] = self.tag
if self.TaskExercise is None:
out["exercise"] = None
else:
out["exercise"] = self.TaskExercise.toJson(recursive=False)

if recursive:

Expand Down
6 changes: 3 additions & 3 deletions codeGrader/frontend/admin/handlers/AdminUser.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def get(self, id_: int) -> Union[str, Response]:
editable = self.admin.check_permission('w')
admin["editable"] = editable

if self.admin.check_permission('r', admin["profile"]["name"]): # when admin is allowed to view this admin
if self.admin.check_permission('r', admin["profile"]["id"]): # when admin is allowed to view this admin
return render_template("adminUser.html", **admin)

else: # admin is not allowed to view this user
Expand All @@ -80,7 +80,7 @@ def post(self, id_: int) -> Response:
assert self.request.form is not None

admin_before = self.api.get(f"/admin/{id_}") # get the admin data
if self.admin.check_permission('w', admin_before["profile"]["name"]):
if self.admin.check_permission('w', admin_before["profile"]["id"]):
admin_data = dict()

# getting the data from the form provided in the request
Expand Down Expand Up @@ -207,7 +207,7 @@ def post(self, id_: int) -> Response:
"""

admin = self.api.get(f"/admin/{id_}")
if self.admin.check_permission('w', admin["profile"]["name"]): # admin is allowed to delete the admin
if self.admin.check_permission('w', admin["profile"]["id"]): # admin is allowed to delete the admin
if self.get_value("action_button") == "Submit":
self.api.delete(f"/admin/{id_}")

Expand Down
14 changes: 7 additions & 7 deletions codeGrader/frontend/admin/handlers/Exercise.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,17 +50,17 @@ def get(self, id_: int) -> Union[str, Response]:
"""
exercise = self.api.get(f"/exercise/{id_}")

editable = self.admin.check_permission('w', exercise["profile"]["name"])
subjects = self.api.get("/subjects")
editable = self.admin.check_permission('w', exercise["profile"]["id"])
subjects = self.api.get("/subjects", profile=self.admin.get_filter_profile())

exercise["subjects"] = subjects["subject"]

exercise["editable"] = editable

if editable: # admin is allowed to see exercise
if self.admin.check_permission('r', exercise["profile"]["id"]): # when admin is allowed to view this user
return render_template("exercise.html", **exercise)

else: # admin is not allowed to see exercise
else: # admin is not allowed to see exercise
self.flash("You are not allowed to view this exercise. ")
return redirect(url_for("exercises"))

Expand All @@ -73,7 +73,7 @@ def post(self, id_: int) -> Response:
assert self.request.form is not None

exercise_before = self.api.get(f"/exercise/{id_}") # get the exercise data
if self.admin.check_permission('w', exercise_before["profile"]["name"]):
if self.admin.check_permission('w', exercise_before["profile"]["id"]):
exercise_data = dict()

exercise_data["name"] = self.get_value("name")
Expand Down Expand Up @@ -164,7 +164,7 @@ def get(self, id_: int) -> Union[str, Response]:
"""
exercise = self.api.get(f"/exercise/{id_}")

editable = self.admin.check_permission('w', exercise["profile"]["name"])
editable = self.admin.check_permission('w', exercise["profile"]["id"])

if editable:
return render_template("deleteExercise.html", **exercise)
Expand All @@ -182,7 +182,7 @@ def post(self, id_: int) -> Response:
@return: Redirection to the Exercise table
"""
exercise = self.api.get(f"/exercise/{id_}")
if self.admin.check_permission('w', exercise["profile"]["name"]): # admin is allowed to delete the exercise
if self.admin.check_permission('w', exercise["profile"]["id"]): # admin is allowed to delete the exercise
if self.get_value("action_button") == "Submit":

response = self.api.delete(f"/exercise/{id_}")
Expand Down
8 changes: 4 additions & 4 deletions codeGrader/frontend/admin/handlers/Profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@ def get(self, id_: int) -> Union[str, Response]:
@rtype: HTML
"""
profile = self.api.get(f"/profile/{id_}")
editable = self.admin.check_permission('w', profile["name"]) # checking if admin has write rights
editable = self.admin.check_permission('w', profile["id"]) # checking if admin has write rights
profile["editable"] = editable # adding the rights to the render params

if self.admin.check_permission('r', profile["name"]): # when admin is allowed to view this profile
if self.admin.check_permission('r', profile["id"]): # when admin is allowed to view this profile
return render_template("profile.html", **profile)

else: # admin is not allowed to view this profile
Expand All @@ -68,7 +68,7 @@ def post(self, id_: int) -> Response:
assert self.request.form is not None
profile_before = self.api.get(f"/profile/{id_}") # get the profile data

if self.admin.check_permission('w', profile_before["name"]): # admin is allowed to update
if self.admin.check_permission('w', profile_before["id"]): # admin is allowed to update
profile_data = dict()

profile_data["name"] = self.get_value("name")
Expand Down Expand Up @@ -152,7 +152,7 @@ def get(self, id_: int) -> str:
"""
profile = self.api.get(f"/profile/{id_}")

editable = self.admin.check_permission('w', profile["profile"]["name"])
editable = self.admin.check_permission('w', profile["profile"]["id"])

if editable:
return render_template("deleteProfile.html", **profile)
Expand Down
12 changes: 7 additions & 5 deletions codeGrader/frontend/admin/handlers/SessionAdmin.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,23 @@ def __init__(self, adminUser_id) -> None:
self.username = user_dict["username"]
self.profile = user_dict["profile"]
if self.profile is not None:
self.profile_id = self.profile["id"]
self.profile_name = self.profile["name"]
else:
self.profile_id = None
self.profile_name = None
self.type = user_dict["admin_type"]
self._admin_type_name = self.type["name"]

def check_permission(self, operation: str, profile_name: str = None, create_object: str = None) -> bool:
def check_permission(self, operation: str, profile_id: str = None, create_object: str = None) -> bool:
"""
Check the permission of the admin for a given Operation and profile
If the operation on the given profile is allowed we return true
else we return false
@param operation: r or w r == Read w == Write
@type operation: str
@param profile_name:
@type profile_name: str
@param profile_id:
@type profile_id: str
@param create_object: What type of object we want to create
@type create_object: str
@return: True if the operation is allowed else false
Expand All @@ -57,15 +59,15 @@ def check_permission(self, operation: str, profile_name: str = None, create_obje
# it is a full read admin, so it is allowed
return True

elif profile_name == self.profile_name:
elif profile_id == self.profile_id:
# checking if the profile is allowed
return True

else:
return False

elif operation == 'w':
if self._admin_type_name == config.admin_rw_partial and profile_name == self.profile_name:
if self._admin_type_name == config.admin_rw_partial and profile_id == self.profile_id:
return True

elif self._admin_type_name == config.admin_rw_partial and create_object not in [None, "profile", "admin"]:
Expand Down
10 changes: 5 additions & 5 deletions codeGrader/frontend/admin/handlers/Subject.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,10 @@ def get(self, id_: int) -> Union[str, Response]:

subject["profiles"] = profiles["profile"]

editable = self.admin.check_permission('w', subject["profile"]["name"])
editable = self.admin.check_permission('w', subject["profile"]["id"])
subject["editable"] = editable

if self.admin.check_permission('r', subject["profile"]["name"]): # when admin is allowed to view this user
if self.admin.check_permission('r', subject["profile"]["id"]): # when admin is allowed to view this user
return render_template("subject.html", **subject)

else: # admin is not allowed to view this subject
Expand All @@ -71,7 +71,7 @@ def post(self, id_: int) -> Response:
"""
assert self.request.form is not None
subject_before = self.api.get(f"/subject/{id_}") # get the subject data
if self.admin.check_permission('w', subject_before["profile"]["name"]):
if self.admin.check_permission('w', subject_before["profile"]["id"]):
subject_data = dict()

subject_data["name"] = self.get_value("name")
Expand Down Expand Up @@ -165,7 +165,7 @@ def get(self, id_: int) -> Union[str, Response]:
@return: Rendered Template
"""
subject = self.api.get(f"/subject/{id_}")
editable = self.admin.check_permission('w', subject["profile"]["name"])
editable = self.admin.check_permission('w', subject["profile"]["id"])

if editable:
return render_template("deleteSubject.html", **subject)
Expand All @@ -183,7 +183,7 @@ def post(self, id_: int) -> Response:
@return: Redirection to the Subject table
"""
subject = self.api.get(f"/subject/{id_}")
if self.admin.check_permission('w', subject["profile"]["name"]): # admin is allowed to delete the subject
if self.admin.check_permission('w', subject["profile"]["id"]): # admin is allowed to delete the subject
if self.get_value("action_button") == "Submit":
response = self.api.delete(f"/subject/{id_}")

Expand Down
21 changes: 14 additions & 7 deletions codeGrader/frontend/admin/handlers/Task.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,12 @@ def get(self, id_: int) -> Union[str, Response]:
"""
task = self.api.get(f"/task/{id_}")

editable = self.admin.check_permission('w', task["profile"]["name"])
editable = self.admin.check_permission('w', task["profile"]["id"])
exercises = self.api.get("/exercises", profile=self.admin.get_filter_profile())
task["exercises"] = exercises["exercise"]

task["editable"] = editable
if self.admin.check_permission('r', task["profile"]["name"]): # when admin is allowed to view this task
if self.admin.check_permission('r', task["profile"]["id"]): # when admin is allowed to view this task
return render_template("task.html", **task)

else: # admin is not allowed to view this task
Expand All @@ -69,11 +71,12 @@ def post(self, id_: int) -> Response:
assert self.request.form is not None

task_before = self.api.get(f"/task/{id_}") # get the task data
if self.admin.check_permission('w', task_before["profile"]["name"]):
if self.admin.check_permission('w', task_before["profile"]["id"]):
task_data = dict()

task_data["name"] = self.get_value("name")
task_data["tag"] = self.get_value("tag")
task_data["exercise_id"] = self.get_value("exercise")

# getting the data from the form provided in the request
self.api.put(f"/task/{id_}", body=task_data)
Expand Down Expand Up @@ -105,8 +108,11 @@ def get(self) -> Union[str, Response]:
"""

if self.admin.check_permission('w', 'task'):

return render_template("addTask.html")
task = dict()
exercises = self.api.get("/exercises", profile=self.admin.get_filter_profile())
task["exercises"] = exercises["exercise"]
print(task)
return render_template("addTask.html", **task)

else: # admin is not allowed to view this task
self.flash("You are not allowed to access this site! ")
Expand All @@ -123,6 +129,7 @@ def post(self) -> Response:

task_data["name"] = self.get_value("name")
task_data["tag"] = self.get_value("tag")
task_data["exercise_id"] = self.get_value("exercise")

self.api.post("/task/add", body=task_data)

Expand Down Expand Up @@ -154,7 +161,7 @@ def get(self, id_: int) -> Union[str, Response]:
"""
task = self.api.get(f"/task/{id_}")

editable = self.admin.check_permission('w', task["profile"]["name"])
editable = self.admin.check_permission('w', task["profile"]["id"])

if editable:
return render_template("deleteTask.html", **task)
Expand All @@ -172,7 +179,7 @@ def post(self, id_: int) -> Response:
@return: Redirection to the Task table
"""
task = self.api.get(f"/task/{id_}")
if self.admin.check_permission('w', task["profile"]["name"]): # admin is allowed to delete the task
if self.admin.check_permission('w', task["profile"]["id"]): # admin is allowed to delete the task

if self.get_value("action_button") == "Submit":
response = self.api.delete(f"/task/{id_}")
Expand Down
10 changes: 5 additions & 5 deletions codeGrader/frontend/admin/handlers/User.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,11 @@ def get(self, id_: int) -> Union[str, Response]:
user["profiles"] = profiles["profile"]

# checking if user will be able to edit the table
editable = self.admin.check_permission('w', user["profile"]["name"])
editable = self.admin.check_permission('w', user["profile"]["id"])

user["editable"] = editable

if self.admin.check_permission('r', user["profile"]["name"]): # when admin is allowed to view this user
if self.admin.check_permission('r', user["profile"]["id"]): # when admin is allowed to view this user
return render_template("user.html", **user)

else: # admin is not allowed to view this user
Expand All @@ -80,7 +80,7 @@ def post(self, id_: int) -> Response:
assert self.request.form is not None

user_before = self.api.get(f"/user/{id_}") # get the user data
if self.admin.check_permission('w', user_before["profile"]["name"]):
if self.admin.check_permission('w', user_before["profile"]["id"]):
user_data = dict()

# getting the data from the form provided in the request
Expand Down Expand Up @@ -185,7 +185,7 @@ def get(self, id_: int) -> Union[str, Response]:

user = self.api.get(f"/user/{id_}")

editable = self.admin.check_permission('w', user["profile"]["name"])
editable = self.admin.check_permission('w', user["profile"]["id"])

if editable:
return render_template("deleteUser.html", **user)
Expand All @@ -203,7 +203,7 @@ def post(self, id_: int) -> Response:
@return: Redirection to the users table
"""
user = self.api.get(f"/user/{id_}")
if self.admin.check_permission('w', user["profile"]["name"]): # admin is allowed to delete the user
if self.admin.check_permission('w', user["profile"]["id"]): # admin is allowed to delete the user

if self.get_value("action_button") == "Submit":
self.api.delete(f"/user/{id_}")
Expand Down
29 changes: 29 additions & 0 deletions codeGrader/frontend/admin/static/css/styling.css
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,35 @@ body {

/* Table Styling end*/

/*Collapsable Styling start*/
.collapsible_content {
padding: 0 18px;
max-height: 0;
overflow: hidden;
transition: max-height 0.2s ease-out;
}

.collapsible {
cursor: pointer;
border: none;
color: white;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 20px;
}

.collapsible:before {
content: "\25B6";
font-weight: bold;
float: left;
margin-left: 5px;
}

.active:before{
content: "\25BC";
}

.flash {
background-color: red;
padding: 10px;
Expand Down
21 changes: 16 additions & 5 deletions codeGrader/frontend/admin/templates/addTask.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,27 @@ <h1 class="header1 core_content">Task</h1>
<tr>
<td class="data">Name</td>
<td class="data">
<input class="input" type="text" id="input_name" name="name" placeholder="Task Name"">
<input class="input" type="text" id="input_name" name="name" placeholder="Task Name">
</td>
</tr>
<tr>
<td class=" data">Tag
</td>
</tr>
<tr>
<td class=" data">Tag</td>
<td class="data">
<input class="input" type="text" id="input_tag" name="tag" placeholder="Task Tag">
</td>
</tr>
<tr>
<td class="data">Exercise</td>
<td class="data">
<select id="sel_exercise" name="exercise">
{% for ex in exercises %}
<option value="{{ ex['id'] }}">
{{ ex['name'] }}
</option>
{% endfor %}
</select>
</td>
</tr>
</table>
</div>
<div id="control_buttons">
Expand Down
Loading

0 comments on commit c7dd32e

Please sign in to comment.