Repository: hedyorg/hedy

Issue:
[UI idea] Reset password for kid by teacher
**Idea**

Some kids forget their password, but they can't access their email address (f.e. because they can't receive links or can't receive email outside of school) If would be great if teachers can set a password reset for this kid so that they can log in again. Once logged in, they can change their password again.


Discussion:
I think this might be quite complex to implement when thinking about it. Do we want to give any teacher these privileges? What is students are in multiple classes? Then we might want to add some checkbox when joining a class:

"When joining this class you accept that your teacher can reset your password".

Or do we want a bigger re-structure? Enabling children to create accounts without a mail address? Because they also need a mail account for sign up and verifying their account. If this is a recurring issue at schools we might want to re-think the way we create accounts. We can say: a teacher mail account can contain multiple accounts. But then we run into a lot issues in the back-end as we in general assume a mail / username is unique. 

This isn't necessary related to this issue as we can always implement the "Teacher can change passwords" functionality. But I think it would be nice to define our long-term direction on the classes as it might become more and more complex to change this structure later on as the class functionality is rapidly growing.
> I think this might be quite complex to implement when thinking about it. 
> Do we want to give any teacher these privileges? 

Yeah I see there is some sort of trade off here between ease of use for teacher and privacy of students, but I think we need to go this way because kids will forget their passwords and that will be unworkable for kids.

>What if students are in multiple classes? 

I don't think this is a scenario we will run into often, but I guess it is ok to have both (or all) teachers get this power.

> Then we might want to add 
> some checkbox when joining a class:
> "When joining this class you accept that your teacher can reset your password".

That seems fair (although I doubt that all kids will understand this fully)

> Or do we want a bigger re-structure? Enabling children to create accounts without a mail address? Because they also need a mail account for sign up and verifying their account. 

It is good that you are thinking about future maintainability!! We do not require kids to verify their email addresses and that is for exactly this reason, that they might not have access to their email addresses.

> If this is a recurring issue at schools we might want to re-think the way we create accounts. We can say: a teacher mail account can contain multiple accounts. But then we run into a lot issues in the back-end as we in general assume a mail / username is unique.

I think it would be great if a teacher could create accounts, we already have an issue open for something similar (to upload a csv file with accounts #1386) that will also alleviate a few of these issues (f.e. kids mistyping their addresses). With that I think we want to keep the constraints on accounts having a unique username and password.

I think it would be best to wait until #1764 is merged until I start working on this. Otherwise, as they are very related we will run into a lot of merge issues later on.
Will work on this today! I have this implementation in mind:

- Add a "reset password" column to the class-overview table
- Teacher get a modal.prompt and then a modal confirm
- Within the modal.prompt they can set a new password
- User logs in -> should reset password

Things to consider:

- Do we want to keep track of a "reset" account (boolean on user)? 
  -> We can navigate the user directly to change password on login
- Makes the implementation more complex but maybe more user-friendly
- Do we want to add a disclaimer to the "join class" page -> "You give the teacher access to blabla...."

Resolving patch:
diff --git a/website/auth.py b/website/auth.py
--- a/website/auth.py
+++ b/website/auth.py
@@ -345,6 +345,32 @@ def destroy_public(user):
         DATABASE.forget_public_profile(user['username'])
         return '', 200
 
+    @app.route('/auth/change_student_password', methods=['POST'])
+    @requires_login
+    def change_student_password(user):
+        body = request.json
+        print(body)
+        if not isinstance(body, dict):
+            return g.auth_texts.get('ajax_error'), 400
+        if not isinstance(body.get('username'), str):
+            return g.auth_texts.get('username_invalid'), 400
+        if not isinstance(body.get('password'), str):
+            return g.auth_texts.get('password_invalid'), 400
+        if len(body['password']) < 6:
+            return g.auth_texts.get('password_six'), 400
+
+        if not is_teacher(user):
+            return g.auth_texts.get("password_change_not_allowed"), 400
+        students = DATABASE.get_teacher_students(user['username'])
+        if body['username'] not in students:
+            return g.auth_texts.get("password_change_not_allowed"), 400
+
+        user = DATABASE.user_by_username(body['username'])
+        hashed = hash(body['password'], make_salt())
+        DATABASE.update_user(body['username'], {'password': hashed})
+
+        return {'success': g.auth_texts.get("password_change_success")}, 200
+
     @app.route('/auth/change_password', methods=['POST'])
     @requires_login
     def change_password(user):


Test patch: