Fix Bug48: Implememt Password Recovery Using Security Questions
							parent
							
								
									21918cf883
								
							
						
					
					
						commit
						8876825ef9
					
				|  | @ -1,2 +1,3 @@ | |||
| .vscode | ||||
| .DS_Store | ||||
| venv/ | ||||
| __pycache__/ | ||||
| *.pyc | ||||
|  |  | |||
|  | @ -0,0 +1,87 @@ | |||
| <?php | ||||
| include 'NoDirectPhpAcess.php'; | ||||
| include 'Header.php'; | ||||
| include "get_mysql_credentials.php"; // Database credentials
 | ||||
| error_reporting(E_ALL); | ||||
| ini_set('display_errors', 1); | ||||
| 
 | ||||
| // Connect to the database
 | ||||
| $con = mysqli_connect("localhost", $mysql_username, $mysql_password, "lrr"); | ||||
| 
 | ||||
| if (mysqli_connect_errno()) { | ||||
|     die("Connection failed: " . mysqli_connect_error()); | ||||
| } | ||||
| 
 | ||||
| // Check if user is logged in
 | ||||
| if (isset($_SESSION['email'])) { | ||||
|     $email = $_SESSION['email']; | ||||
| 
 | ||||
|     // Check if form is submitted
 | ||||
|     if ($_SERVER['REQUEST_METHOD'] == 'POST') { | ||||
|         // Get the submitted answers
 | ||||
|         $answer1 = strtolower(trim($_POST['answer1'])); | ||||
|         $answer2 = strtolower(trim($_POST['answer2'])); | ||||
| 
 | ||||
|         // Fetch correct answers from the database
 | ||||
|         $sql = "SELECT user_id, answer1, answer2 FROM password_recovery_security_questions WHERE email = '$email'"; | ||||
|         $result = mysqli_query($con, $sql); | ||||
| 
 | ||||
|         if ($row = mysqli_fetch_assoc($result)) { | ||||
|             // Compare submitted answers with stored answers
 | ||||
|             if (hash_equals($row['answer1'], $answer1) && hash_equals($row['answer2'], $answer2)) { | ||||
|                 $_SESSION['user_id'] = $row['user_id']; | ||||
|                 header("Location: ResetPassword.php"); // Redirect to password reset page
 | ||||
|                 exit; | ||||
|             } else { | ||||
|                 $error_message = "Incorrect answers. Please try again."; | ||||
|             } | ||||
|         } else { | ||||
|             echo '<div class="container mt-5"><div class="alert alert-warning" role="alert">No security questions found for this user.</div></div>'; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     // Fetch security questions from the database for display
 | ||||
|     $sql = "SELECT question1, question2 FROM password_recovery_security_questions WHERE email = '$email'"; | ||||
|     $result = mysqli_query($con, $sql); | ||||
| 
 | ||||
|     if ($row = mysqli_fetch_assoc($result)) { | ||||
|         // Display the questions in a form
 | ||||
|         echo'<br/><br/><br/>'; | ||||
|         echo '<div class="container">'; | ||||
|         echo '<div class="row">'; | ||||
|         echo '<div class="col-md-5"></div>'; | ||||
|         echo '<div class="col-md-5">'; | ||||
|          if (isset($error_message)) { | ||||
|             echo '<div id="alertbad" class="alert alert-danger" role="alert">' . $error_message . '</div>'; // Display error message
 | ||||
|         } | ||||
| 
 | ||||
|         //echo '<center>';
 | ||||
|         echo '<form action="" method="POST" class="">'; | ||||
|         echo '<legend>Answer Your Security Questions.</legend>'; | ||||
| 
 | ||||
|         // Question 1
 | ||||
|         echo '<div class="mb-3">'; | ||||
|         echo '<label class="form-label">' . htmlspecialchars($row['question1']) . '</label>'; | ||||
|         echo '<input type="text" class="form-control" name="answer1" required>'; | ||||
|         echo '</div>'; | ||||
|         echo'<br/>'; | ||||
| 
 | ||||
|         // Question 2
 | ||||
|         echo '<div class="mb-3">'; | ||||
|         echo '<label class="form-label">' . htmlspecialchars($row['question2']) . '</label>'; | ||||
|         echo '<input type="text" class="form-control" name="answer2" required>'; | ||||
|         echo '</div>'; | ||||
| 
 | ||||
|         echo '<button id="sub" type="submit" class="btn btn-primary">Submit Answers</button>'; | ||||
|         echo '</form>'; | ||||
|         echo '</div></div></div>'; // Close container
 | ||||
|     } else { | ||||
|         echo '<div class="container mt-5"><div class="alert alert-warning" role="alert">No security questions found for this user.</div></div>'; | ||||
|     } | ||||
| } else { | ||||
|     header("Location: RecoverPassword.php"); // Redirect if session data is missing
 | ||||
|     exit; | ||||
| } | ||||
| 
 | ||||
| mysqli_close($con); | ||||
| ?>
 | ||||
|  | @ -1,3 +1,8 @@ | |||
| <?php | ||||
| error_reporting(E_ALL); | ||||
| ini_set('display_errors', 1); | ||||
| ?>
 | ||||
| 
 | ||||
| <?php | ||||
| session_start(); | ||||
| error_reporting(0); | ||||
|  | @ -157,7 +162,7 @@ if (mysqli_connect_errno()) { | |||
| 
 | ||||
| 			<?php | ||||
| 			if (isset($_SESSION["user_fullname"])) { | ||||
|                 if ($_SESSION['user_type'] == "Student" || $_SESSION['user_type'] == 'Lecturer') { | ||||
|                 if ($_SESSION['user_type'] == "Student" || $_SESSION['user_type'] == 'Lecturer' || $_SESSION['user_type'] == 'TA') { | ||||
|                     echo "<a class='nav-link' href='~\..\Courses.php'><i class='fa fa-book'></i> My courses </a>"; | ||||
|                 } | ||||
| 			?>
 | ||||
|  |  | |||
|  | @ -15,11 +15,9 @@ include 'Header.php'; | |||
| 	    <form method="post" action="Script.php"> | ||||
| 		<legend>Recover password</legend> | ||||
| 		<input type="hidden" name="form_recover_password" value="true"/> | ||||
| 		Student number | ||||
| 		<input type="text" name="sno" placeholder="Enter your student number" class="form-control" required="required" value="<?php echo htmlspecialchars($_SESSION['student_number']); ?>"> <br/> | ||||
| 		Email | ||||
| 		<input type="text" name="email" placeholder="Enter your email address" class="form-control" required="required" value="<?php echo htmlspecialchars($_SESSION['user_email']); ?>"> <br/> | ||||
| 		<button type="submit" class="btn btn-primary">Recover</button> | ||||
| 		<button id="rec"  type="submit" class="btn btn-primary">Recover</button> | ||||
| 	    </form> | ||||
| 	</div> | ||||
|     </div> | ||||
|  | @ -0,0 +1,78 @@ | |||
| <?php | ||||
| require_once 'Header.php'; | ||||
| require_once 'NoDirectPhpAcess.php'; | ||||
| require_once "get_mysql_credentials.php"; | ||||
| 
 | ||||
| ini_set('display_errors', 0); | ||||
| error_reporting(E_ALL); | ||||
| 
 | ||||
| $con = mysqli_connect("localhost", $mysql_username, $mysql_password, "lrr"); | ||||
| 
 | ||||
| if (mysqli_connect_errno()) { | ||||
|     error_log("Database connection failed: " . mysqli_connect_error()); | ||||
|     die("An error occurred. Please try again later."); | ||||
| } | ||||
| 
 | ||||
| // Check if user_id is set in the session
 | ||||
| if (!isset($_SESSION['email'])) { | ||||
|     die("Session expired. Please log in again."); | ||||
| } | ||||
| 
 | ||||
| $email = $_SESSION['email']; | ||||
| 
 | ||||
| if ($_SERVER['REQUEST_METHOD'] == 'POST') { | ||||
|     // Handle password reset
 | ||||
|     if (isset($_POST['new_password']) && isset($_POST['confirm_password'])) { | ||||
|         $new_password = $_POST['new_password']; | ||||
|         $confirm_password = $_POST['confirm_password']; | ||||
| 
 | ||||
|         if (!preg_match('/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^\w\d\s]).{8,}$/', $new_password)) { | ||||
|             echo '<div class="alert alert-danger">Password must be at least 8 characters long and include uppercase and lowercase letters, numbers, and special characters.</div>'; | ||||
|         } elseif ($new_password !== $confirm_password) { | ||||
|             echo '<div class="alert alert-danger">Passwords do not match. Please try again.</div>'; | ||||
|         } else { | ||||
|             $hashed_password = password_hash($new_password, PASSWORD_ARGON2ID); | ||||
|             $user_id = $_SESSION['user_id']; | ||||
| 
 | ||||
|             $stmt = $con->prepare("UPDATE users_table SET Password = ? WHERE email = ? AND user_id = ?"); | ||||
|             $stmt->bind_param("sss", $hashed_password, $email, $user_id); | ||||
| 
 | ||||
|             if ($stmt->execute()) { | ||||
|                 echo '<div class="alert alert-success">Password reset successfully. You can now log in with your new password.</div>'; | ||||
|                 unset($_SESSION['user_id']); // Clear user_id after successful password reset
 | ||||
|                 header("Location: index.php"); | ||||
|             } else { | ||||
|                 error_log("Error updating password for user ID: $user_id"); | ||||
|                 echo '<div class="alert alert-danger">An error occurred. Please try again later.</div>'; | ||||
|             } | ||||
|             $stmt->close(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| // Display the reset password form
 | ||||
| echo ' | ||||
| <br/><br/><br/> | ||||
| <div class="container"> | ||||
| <div class="row"> | ||||
| <div class="col-md-5"></div> | ||||
| <div class="col-md-5"> | ||||
| <form action="" method="POST" class=""> | ||||
|     <legend>Reset Your Password</legend><br/> | ||||
|        New Password <label class="form-text">Must include uppercase and lowercase letters, digits and special characters.</label>   | ||||
|        <input type="password" name="new_password"  placeholder=" Enter New Password" class="form-control" required> | ||||
|        <br/> | ||||
|       Confirm New Password | ||||
|         <input type="password" name="confirm_password" placeholder="Confirm New Password" class="form-control" required> | ||||
|      <br/> | ||||
|     <button id="butt" type="submit" class="btn btn-primary">Reset Password</button> | ||||
| </form> | ||||
| </div></div></div> | ||||
| <style> | ||||
| .guideline { display: none;} | ||||
| #newPassword:focus + .guideline {display: block;}
 | ||||
| '; | ||||
| 
 | ||||
| 
 | ||||
| mysqli_close($con); | ||||
| ?>
 | ||||
							
								
								
									
										114
									
								
								Script.php
								
								
								
								
							
							
						
						
									
										114
									
								
								Script.php
								
								
								
								
							|  | @ -224,20 +224,50 @@ if (!empty($_POST["form_login"])) { | |||
|                 $_SESSION['user_type'] = $row['UserType']; | ||||
|                 $_SESSION['user_fullname'] = $row['Full_Name']; | ||||
| 
 | ||||
|  // Check if the user is a student and has not set up their password recovery yet
 | ||||
| 
 | ||||
|                 if ($_SESSION['user_type'] == "Student") { | ||||
|                     header("Location: Courses.php"); | ||||
|                     // Query to check if the student has completed the password recovery setup
 | ||||
|                     $recovery_result = mysqli_query($con, "SELECT * FROM password_recovery_security_questions WHERE Student_ID = '" . $row['Student_ID'] . "'"); | ||||
|                     if (mysqli_num_rows($recovery_result) == 0) { | ||||
|                         // If the student has not set up password recovery, redirect to the setup page
 | ||||
|                         header("Location: SecurityQuestions.php"); | ||||
|                         exit(); | ||||
|                     } else { | ||||
|                         // If the student has set up password recovery, redirect to the Courses page
 | ||||
|                         header("Location: Courses.php"); | ||||
|                     } | ||||
|                 } | ||||
| 
 | ||||
|                // Redirect other user types to their respective pages
 | ||||
| 
 | ||||
|                 if ($_SESSION['user_type'] == "Lecturer") { | ||||
|                     header("Location: Courses.php"); | ||||
|                     $recovery_result = mysqli_query($con, "SELECT * FROM password_recovery_security_questions WHERE user_id = '" . $row['User_ID'] . "' AND user_type = 'Lecturer'"); | ||||
|                     if (mysqli_num_rows($recovery_result) == 0) { | ||||
|                      header("Location: SecurityQuestions.php"); | ||||
|                      exit(); | ||||
|                    } else { | ||||
|                      header("Location: Courses.php"); } | ||||
|                 } | ||||
| 
 | ||||
|                 if ($_SESSION['user_type'] == "TA") { | ||||
|                     header("Location: Courses.php"); | ||||
|                     $recovery_result = mysqli_query($con, "SELECT * FROM password_recovery_security_questions WHERE user_id = '" . $row['User_ID'] . "' AND user_type = 'TA'"); | ||||
|                     if (mysqli_num_rows($recovery_result) == 0) { | ||||
|                      header("Location: SecurityQuestions.php"); | ||||
|                      exit(); | ||||
|                    } else {  | ||||
|                      header("Location: Courses.php"); } | ||||
| 
 | ||||
|                 } | ||||
| 
 | ||||
|                 if ($_SESSION['user_type'] == "Admin") { | ||||
|                     header("Location: Admin.php"); | ||||
|                     $recovery_result = mysqli_query($con, "SELECT * FROM password_recovery_security_questions WHERE user_id = '" . $row['User_ID'] . "' AND user_type = 'Admin'"); | ||||
|                     if (mysqli_num_rows($recovery_result) == 0) { | ||||
|                      header("Location: SecurityQuestions.php"); | ||||
|                      exit(); | ||||
|                    } else {  | ||||
|                      header("Location: Admin.php"); } | ||||
| 
 | ||||
|                 } | ||||
|                 //  report wrong pass if not correct
 | ||||
|                 return; | ||||
|  | @ -250,43 +280,79 @@ if (!empty($_POST["form_login"])) { | |||
|                 header("Location: index.php"); | ||||
|                 exit();  // Add this line to prevent further execution after redirect
 | ||||
|             } | ||||
|             // Add the following line to reset the session variable when needed
 | ||||
|             // Reset the session variable when needed
 | ||||
|             unset($_SESSION["failed_login_user"]); | ||||
| 
 | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| // ################################ Recover Password  #####################################
 | ||||
| 
 | ||||
| if (!empty($_POST["form_recover_password"])) { | ||||
| 
 | ||||
|     $student_id = mysqli_real_escape_string($con, $_POST["sno"]); | ||||
|     $email = mysqli_real_escape_string($con, $_POST["email"]); | ||||
| 
 | ||||
|     // validate student number
 | ||||
|     if (strlen($student_id) != 12  || is_numeric($student_id) == FALSE) { | ||||
|         $_SESSION["info_recover_password"] = "Invalid student number."; | ||||
|         header("Location: recover_password.php"); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     // validate email
 | ||||
|     // Validate email
 | ||||
|     if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { | ||||
|         $_SESSION["info_recover_password"] = "Invalid email address."; | ||||
|         // echo "Invalid email address.";
 | ||||
|         header("Location: recover_password.php"); | ||||
|         header("Location: RecoverPassword.php"); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     $result = mysqli_query($con, "SELECT * FROM users_table WHERE Email='$email' and Student_ID='$student_id'"); | ||||
|     // Check if user exists in the database
 | ||||
| $result = mysqli_query($con, "SELECT * FROM users_table WHERE Email='$email'"); | ||||
| if (mysqli_num_rows($result) == 0) { | ||||
|     $_SESSION["info_recover_password"] = "Email address is not recognized."; | ||||
|     header("Location: RecoverPassword.php"); | ||||
| } else { | ||||
|     // Store the student ID and email in the session
 | ||||
|     $_SESSION['email'] = $email; | ||||
|     header("Location: AnswerSecurityQuestions.php"); | ||||
| } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| // ################################ RESET Password  #####################################
 | ||||
| 
 | ||||
| if (!empty($_POST["form_reset_password"])) { | ||||
|     $password = mysqli_real_escape_string($con, $_POST["password"]); | ||||
|     $token = mysqli_real_escape_string($con, $_POST["token"]); | ||||
|     $email = mysqli_real_escape_string($con, $_POST["email"]); | ||||
|     $result = mysqli_query( | ||||
|         $con, | ||||
|         "SELECT * FROM Users_Table WHERE email='$email'" | ||||
|     ); | ||||
|     if (mysqli_num_rows($result) == 0) { | ||||
|         $_SESSION["info_recover_password"] = "Email address is not recognised."; | ||||
|         $_SESSION["info_recover_password"] = "Identity not recognized.  Try again or send an inquiry email message to lanhui at zjnu.edu.cn."; | ||||
|         header("Location: recover_password.php"); | ||||
| 
 | ||||
|         echo "invalid email"; | ||||
|         return; | ||||
|     } else { | ||||
|         $result = mysqli_query($con, "DELETE FROM users_table WHERE Email='$email' and Student_ID='$student_id'"); | ||||
|         header("Location: signup.php"); | ||||
|         while ($row = mysqli_fetch_assoc($result)) { | ||||
| 
 | ||||
|             $userid = $row['User_ID']; | ||||
| 
 | ||||
|             $email = $row['Email']; | ||||
|             $id = $row['Student_ID']; | ||||
| 
 | ||||
|             $user_token = $userid * $userid * $userid + $userid * 0.00343; | ||||
|             if ($user_token == $token) { | ||||
|                 // Password Update
 | ||||
| 
 | ||||
|                 // Password Update
 | ||||
|                 $hashed_password = hash('sha512', $password); | ||||
|                 $sql = "UPDATE users_table set HashPassword='$hashed_password' where User_ID='$userid';"; | ||||
|                 if ($con->query($sql) === TRUE) { | ||||
| 
 | ||||
|                     error_reporting(0); | ||||
| 
 | ||||
|                     $_SESSION["info_login"] = " Password changed successfully , you can login now with your new password "; | ||||
|                     header("Location: index.php"); | ||||
|                 } else { | ||||
|                     echo "Error: " . $sql . "<br>" . $con->error; | ||||
|                 } | ||||
|             } else { | ||||
|                 echo "Invalid Token "; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -0,0 +1,139 @@ | |||
| <?php | ||||
| session_start(); | ||||
| error_reporting(0); | ||||
| date_default_timezone_set('Asia/Shanghai'); | ||||
| 
 | ||||
| include 'NoDirectPhpAcess.php'; | ||||
| include "get_mysql_credentials.php"; // Database credentials
 | ||||
| error_reporting(E_ALL); | ||||
| ini_set('display_errors', 1); | ||||
| 
 | ||||
| $con = mysqli_connect("localhost", $mysql_username, $mysql_password, "lrr"); | ||||
| 
 | ||||
| if (mysqli_connect_errno()) { | ||||
|     die("Connection failed: " . mysqli_connect_error()); | ||||
| } | ||||
| 
 | ||||
| // Check if user_id is set in the session
 | ||||
| if (!isset($_SESSION['user_id'])) { | ||||
|     echo '<div class="alert alert-danger" role="alert">Session expired. Please log in again.</div>'; | ||||
|     exit(); // Stop script execution if user_id is not set
 | ||||
| } | ||||
| 
 | ||||
| if ($_SERVER['REQUEST_METHOD'] == 'POST') { | ||||
|     // Get the security questions and answers from the form
 | ||||
|     $question1 = mysqli_real_escape_string($con, $_POST['security_question1']); | ||||
|     $answer1 = strtolower(mysqli_real_escape_string($con, $_POST['security_answer1'])); | ||||
|     $question2 = mysqli_real_escape_string($con, $_POST['security_question2']); | ||||
|     $answer2 = strtolower(mysqli_real_escape_string($con, $_POST['security_answer2'])); | ||||
| 
 | ||||
|     // Get the user ID and user type from the session
 | ||||
|     $user_id = $_SESSION['user_id']; // Use user_id from session
 | ||||
|     $user_type = $_SESSION['user_type']; //Get user type from session
 | ||||
|     $email = $_SESSION['user_email']; | ||||
|     $student_id = isset($_SESSION['user_student_id']) ? $_SESSION['user_student_id'] : NULL; //Handle student_id for students
 | ||||
| 
 | ||||
|     // Prepare SQL statement
 | ||||
|     if($user_type == 'Student') {  | ||||
|     $sql = "INSERT INTO password_recovery_security_questions (user_id,user_type,  student_id, email, question1, answer1, question2, answer2)    
 | ||||
|             VALUES ('$user_id', '$user_type', '$student_id', '$email', '$question1', '$answer1', '$question2', '$answer2')  | ||||
|             ON DUPLICATE KEY UPDATE  | ||||
|                 question1='$question1',  | ||||
|                 answer1='$answer1',  | ||||
|                 question2='$question2',  | ||||
|                 answer2='$answer2'";
 | ||||
|     } else { | ||||
|     // For non-students (Lecturer, TA, etc.), exclude student_id
 | ||||
|         $sql = "INSERT INTO password_recovery_security_questions (user_id, user_type, email, question1, answer1, question2, answer2)    
 | ||||
|                 VALUES ('$user_id', '$user_type', '$email', '$question1', '$answer1', '$question2', '$answer2')  | ||||
|                 ON DUPLICATE KEY UPDATE  | ||||
|                     question1='$question1',  | ||||
|                     answer1='$answer1',  | ||||
|                     question2='$question2',  | ||||
|                     answer2='$answer2'";
 | ||||
|     } | ||||
| 
 | ||||
|     // Execute the query and check for success
 | ||||
|     if (mysqli_query($con, $sql)) { | ||||
|         echo '<div id="alertgood" class="alert alert-success" role="alert">Password recovery details set successfully. Please remember your answers! Redirecting to Courses page...</div>'; | ||||
| 	echo '<script>'; | ||||
| 	echo ' setTimeout(function() {'; | ||||
| 	echo ' 	var userType = "'. $_SESSION['user_type'] . '";'; | ||||
| 	echo ' 	if (userType === "Admin") {'; | ||||
| 	echo ' 	   window.location.href = "Admin.php";'; | ||||
| 	echo '  } else {'; | ||||
| 	echo ' 	   window.location.href = "Courses.php";'; | ||||
| 	echo ' 	}'; | ||||
| 	echo ' }, 2000);';  | ||||
| 	echo '</script>'; | ||||
|     } else { | ||||
|         echo '<div class="alert alert-danger" role="alert">Error: ' . mysqli_error($con) . '</div>'; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| mysqli_close($con); | ||||
| ?>
 | ||||
| 
 | ||||
| <!DOCTYPE html> | ||||
| <html lang="en"> | ||||
| <head> | ||||
|     <meta charset="UTF-8"> | ||||
|     <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||||
|     <title>Security Questions</title> | ||||
|     <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/css/bootstrap.min.css" rel="stylesheet"> | ||||
| </head> | ||||
| <body> | ||||
| <nav class="navbar navbar-expand-lg bg-body-tertiary" style="padding-left:180px;padding-right:150px;margin:auto;"> | ||||
| 	    <div class="container-fluid"> | ||||
| 
 | ||||
| 		<a class="navbar-brand" href="#"> <img src="logo.png" style="width:30px;height:30px;" alt="LRR Logo"> LRR </a> | ||||
| </nav> | ||||
| <br/><br/><br/> | ||||
| <div class="container"> | ||||
|  <div class="col-md-5"></div> | ||||
|      <form action="SecurityQuestions.php" method="POST"> | ||||
|        <label> Set Password Recovery (Make sure you remember your answers) </label>  | ||||
|         <div class="mb-3"> | ||||
| 		<br/> | ||||
|             <label for="security_question1" class="form-label">Select Security Question 1</label> | ||||
|             <select class="form-select" id="security_question1" name="security_question1" required> | ||||
|                 <option value="">-- Select a question --</option> | ||||
|                 <option value="What is the name of your first pet?">What is the name of your first pet?</option> | ||||
|                 <option value="What is your mother's maiden name?">What is your mother's maiden name?</option> | ||||
|                 <option value="What is the name of the town where you were born?">What is the name of the town where you were born?</option> | ||||
|                 <option value="What was the name of your first best friend?">What was the name of your first best friend?</option> | ||||
|                 <option value="What is your favorite book?">What is your favorite book?</option> | ||||
|                 <option value="What was the make and model of your first car?">What was the make and model of your first car?</option> | ||||
|                 <!-- Add more options if needed --> | ||||
|             </select> | ||||
|         </div> | ||||
|         <div class="mb-3"> | ||||
|             <label for="security_answer1" class="form-label">Answer 1</label> | ||||
|             <input type="text" class="form-control" id="security_answer1" name="security_answer1" required> | ||||
|         </div> | ||||
| 		<br/> | ||||
|         <div class="mb-3"> | ||||
|             <label for="security_question2" class="form-label">Select Security Question 2</label> | ||||
|             <select class="form-select" id="security_question2" name="security_question2" required> | ||||
|                 <option value="">-- Select a question --</option> | ||||
|                 <option value="What was the name of your first school?">What was the name of your first school?</option> | ||||
|                 <option value="What is your favorite movie?">What is your favorite movie?</option> | ||||
|                 <option value="What was your childhood nickname?">What was your childhood nickname?</option> | ||||
|                 <option value="What is the name of your favorite teacher?">What is the name of your favorite teacher?</option> | ||||
|                 <option value="What street did you grow up on?">What street did you grow up on?</option> | ||||
|                 <option value="What is your favorite food?">What is your favorite food?</option> | ||||
|                 <!-- Add more options if needed --> | ||||
|             </select> | ||||
|         </div> | ||||
|         <div class="mb-3"> | ||||
|             <label for="security_answer2" class="form-label">Answer 2</label> | ||||
|             <input type="text" class="form-control" id="security_answer2" name="security_answer2" required> | ||||
|         </div> | ||||
| 
 | ||||
| 		<br/> | ||||
|         <button id="submit_recovery" type="submit" class="btn btn-primary">Save Answers</button> | ||||
|     </form> | ||||
| </div> | ||||
| 
 | ||||
| </body> | ||||
| </html> | ||||
|  | @ -41,7 +41,7 @@ if (isset($_SESSION["user_fullname"])) { | |||
| 		<label class="form-text">Don't have an account yet?</label> <a href="signup.php" id="signup_link">Sign up</a> | ||||
| 
 | ||||
| 		<br> | ||||
| 		<label class="form-text">Forget your password?</label> <a href="recover_password.php">Recover</a> | ||||
| 		<label class="form-text">Forget your password?</label> <a id="goRecover" href="RecoverPassword.php">Recover</a> | ||||
| 
 | ||||
| 
 | ||||
| 		<?php | ||||
|  |  | |||
|  | @ -259,7 +259,10 @@ INSERT INTO `students_data` (`ID`, `Student_ID`, `Passport_Number`) VALUES | |||
| (1, '201825800054', 'LJ7951632'), | ||||
| (2, '201825800050', 'P00581929'), | ||||
| (3, '201632120150', 'FN524516'), | ||||
| (4, '202400000001', 'NA'); | ||||
| (4, '202400000001', 'NA'), | ||||
| (5,'201932130101',''), | ||||
| (6,'201920781742',''); | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| -- -------------------------------------------------------- | ||||
|  | @ -269,7 +272,7 @@ INSERT INTO `students_data` (`ID`, `Student_ID`, `Passport_Number`) VALUES | |||
| -- | ||||
| 
 | ||||
| CREATE TABLE `users_table` ( | ||||
|   `User_ID` int(11) NOT NULL, | ||||
|   `User_ID` int(11) NOT NULL AUTO_INCREMENT, | ||||
|   `Email` varchar(50) COLLATE utf8mb4_bin DEFAULT NULL, | ||||
|   `Password` varchar(250) CHARACTER SET utf8 DEFAULT NULL, | ||||
|   `HashPassword` varchar(250) COLLATE utf8mb4_bin NOT NULL, | ||||
|  | @ -277,7 +280,8 @@ CREATE TABLE `users_table` ( | |||
|   `UserType` varchar(50) COLLATE utf8mb4_bin DEFAULT NULL, | ||||
|   `Student_ID` varchar(500) COLLATE utf8mb4_bin DEFAULT NULL, | ||||
|   `Passport_Number` varchar(50) COLLATE utf8mb4_bin DEFAULT NULL, | ||||
|   `Status` varchar(30) COLLATE utf8mb4_bin NOT NULL DEFAULT 'Active' | ||||
|   `Status` varchar(30) COLLATE utf8mb4_bin NOT NULL DEFAULT 'Active', | ||||
|    PRIMARY KEY (`User_ID`) | ||||
| ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin; | ||||
| 
 | ||||
| -- | ||||
|  | @ -294,8 +298,28 @@ INSERT INTO `users_table` (`User_ID`, `Email`, `Password`, `HashPassword`, `Full | |||
| (12, 'mehdi@qq.com', '123', '', 'El-mehdi Houzi', 'Student', '201825800054', 'LJ7951632', 'Active'), | ||||
| (17, 'teecloudy@qq.com', '$2y$10$8WqSK7QI.3YCb2yoclqutOxyGxojncUvzhqLcE8zjlSvjBdcIQ18O', '', 'Ashly Tafadzwa Dhani', 'Student', '201632120150', NULL, 'Active'), | ||||
| (18, 'ashly@qq.com', 'Testing2', '', 'Ashly 2 Testing', 'Student', '2016321201502', NULL, 'Active'), | ||||
| (19, '11@11.11', 'dfdf', '760a8f4f392f1f6bc3ecb118365c6cd039b59fdce96122897d5157970d9c9c129bd73b3c402dbeedd8fe94d319df7bd7de0025c22839fec06631a025ec1e0e69', '11', 'Student', '11', '', 'Active'); | ||||
| (19, '11@11.11', 'dfdf', '760a8f4f392f1f6bc3ecb118365c6cd039b59fdce96122897d5157970d9c9c129bd73b3c402dbeedd8fe94d319df7bd7de0025c22839fec06631a025ec1e0e69', '11', 'Student', '11', '', 'Active'), | ||||
| (20,'goodstd@qq.com','$2y$10$RXIjONOK.mw74pSxPrsnGuccQsFq4O4.e71vaxfGHHhtzHREtfqkG','','Good Std','Student','201932130101',NULL,'Active'),(21,'goodstd2@qq.com','$2y$10$kmqrGuZd7hCiiaHFDQr2vObpD7BgEnCKlgQ/EcLHYnsQenMbNKcHy','','Good Std2','Student','201920781742',NULL,'Active'); | ||||
| 
 | ||||
| CREATE TABLE `password_recovery_security_questions` ( | ||||
|   `user_id` int NOT NULL, | ||||
|   `user_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL, | ||||
|   `student_id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL, | ||||
|   `email` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL, | ||||
|   `question1` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL, | ||||
|   `answer1` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL, | ||||
|   `question2` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL, | ||||
|   `answer2` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL, | ||||
|   PRIMARY KEY (`user_id`), | ||||
|   CONSTRAINT `password_recovery_security_questions_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users_table` (`User_ID`) ON DELETE CASCADE | ||||
| ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin; | ||||
| 
 | ||||
| INSERT INTO `password_recovery_security_questions` VALUES  | ||||
| (3,'Admin',NULL,'admin@qq.com','What is the name of your first pet?','mimi','What was the name of your first school?','zjnu'), | ||||
| (7,'Lecturer',NULL,'peter@qq.com','What was the name of your first best friend?','chen','What is your favorite food?','hotpot'), | ||||
| (8,'Lecturer',NULL,'lanhui@qq.com','What is the name of the town where you were born?','jinhua','What is your favorite movie?','titanic'), | ||||
| (9,'Student','201825800050','mohamed@qq.com','What was the make and model of your first car?','audi','What is the name of your favorite teacher?','chen'), | ||||
| (21,'Student','201920781742','goodstd2@qq.com','What is the name of the town where you were born?','wenzhou','What is your favorite food?','hotpot'); | ||||
| -- | ||||
| -- Indexes for dumped tables | ||||
| -- | ||||
|  | @ -349,12 +373,6 @@ ALTER TABLE `lab_report_submissions` | |||
| ALTER TABLE `students_data` | ||||
|   ADD PRIMARY KEY (`ID`); | ||||
| 
 | ||||
| -- | ||||
| -- Indexes for table `users_table` | ||||
| -- | ||||
| ALTER TABLE `users_table` | ||||
|   ADD PRIMARY KEY (`User_ID`); | ||||
| 
 | ||||
| -- | ||||
| -- AUTO_INCREMENT for dumped tables | ||||
| -- | ||||
|  | @ -412,12 +430,7 @@ ALTER TABLE `students_data` | |||
| -- | ||||
| ALTER TABLE courses_table | ||||
| MODIFY Course_Name varchar(500); | ||||
| -- | ||||
| -- AUTO_INCREMENT for table `users_table` | ||||
| -- | ||||
| ALTER TABLE `users_table` | ||||
|   MODIFY `User_ID` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=20; | ||||
| COMMIT; | ||||
| 
 | ||||
| 
 | ||||
| /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; | ||||
| /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; | ||||
|  |  | |||
|  | @ -0,0 +1,37 @@ | |||
| from selenium.webdriver.common.by import By | ||||
| from selenium.webdriver.support.ui import WebDriverWait | ||||
| from selenium.webdriver.support import expected_conditions as EC | ||||
| from selenium.common.exceptions import NoSuchElementException, UnexpectedAlertPresentException | ||||
| 
 | ||||
| 
 | ||||
| def login(driver, url, username, password): | ||||
|     try: | ||||
|         driver.get(url) | ||||
| 
 | ||||
|         # Fill in the login form | ||||
|         user_input = WebDriverWait(driver, 10).until( | ||||
|             EC.element_to_be_clickable((By.ID, "user_name")) | ||||
|         ) | ||||
|         user_input.send_keys(username) | ||||
| 
 | ||||
|         password_input = WebDriverWait(driver, 10).until( | ||||
|             EC.element_to_be_clickable((By.ID, "user_password")) | ||||
|         ) | ||||
|         password_input.send_keys(password) | ||||
| 
 | ||||
|         # Click the login button | ||||
|         login_button = WebDriverWait(driver, 10).until( | ||||
|             EC.element_to_be_clickable((By.ID, "login_btn")) | ||||
|         ) | ||||
|         login_button.click() | ||||
|     except (NoSuchElementException, UnexpectedAlertPresentException) as e: | ||||
|         return f"Error: {str(e)}" | ||||
| 
 | ||||
| 
 | ||||
| def logout(driver): | ||||
|     logout_button = WebDriverWait(driver, 10).until( | ||||
|         EC.element_to_be_clickable( | ||||
|             (By.XPATH, "//a[contains(@class, 'nav-link') and contains(@href, 'logout.php')]") | ||||
|         ) | ||||
|     ) | ||||
|     logout_button.click() | ||||
|  | @ -0,0 +1,156 @@ | |||
| from helper import login, logout | ||||
| import time | ||||
| import pytest | ||||
| from selenium.webdriver.common.by import By | ||||
| from selenium.webdriver.support.wait import WebDriverWait | ||||
| from selenium.webdriver.support import expected_conditions as EC | ||||
| from selenium.webdriver.support.ui import Select | ||||
| 
 | ||||
| def test_attempt_recovery_with_unanswered_security_questions(driver, url, restore_database): | ||||
|     # Student goodstd@qq.com with no answered questions | ||||
|     driver.get(url) | ||||
|     driver.maximize_window() | ||||
|      | ||||
|     elem = driver.find_element(By.ID, 'goRecover') | ||||
|     elem.click() | ||||
|     elem = driver.find_element(By.NAME, 'email') | ||||
|     elem.send_keys("goodstd@qq.com") | ||||
|     elem = driver.find_element(By.ID, 'rec') | ||||
|     elem.click() | ||||
|      | ||||
|     wait = WebDriverWait(driver, 10) | ||||
|     alert_elem = wait.until(EC.presence_of_element_located((By.CLASS_NAME, "alert-warning"))) | ||||
|     assert "no security questions found for this user." in alert_elem.text.lower()  | ||||
|   | ||||
|     driver.quit() | ||||
| 
 | ||||
| def test_set_security_questions(driver, url, restore_database): | ||||
|     # Student goodstd@qq.com logs in | ||||
|     driver.get(url) | ||||
|     driver.maximize_window() | ||||
|     login(driver, url, 'goodstd@qq.com', '[123Abc]') | ||||
|     question1 = driver.find_element(By.ID, 'security_question1') | ||||
|     question2 = driver.find_element(By.ID, 'security_question2') | ||||
|     select_question1 = Select(question1) | ||||
|     select_question1.select_by_index(1) | ||||
|     select_question2 = Select(question2) | ||||
|     select_question2.select_by_index(2) | ||||
|     answer1 = driver.find_element(By.ID, 'security_answer1') | ||||
|     answer1.send_keys("mImI") | ||||
|     answer2 = driver.find_element(By.ID, 'security_answer2') | ||||
|     answer2.send_keys("TitaNic") | ||||
|     submit_button = driver.find_element(By.ID, 'submit_recovery') | ||||
|     submit_button.click()  | ||||
|      | ||||
|     # Assertion: Check if password recovery confirmation or success message appears | ||||
|     WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, 'alertgood'))) | ||||
|     recovery_success = driver.find_element(By.ID, 'alertgood') | ||||
|     assert recovery_success.is_displayed(), "Password recovery failed or confirmation message not displayed." | ||||
|      | ||||
|     logout(driver) | ||||
|      | ||||
|     #Log in Student account | ||||
|     login(driver, url, 'goodstd@qq.com', '[123Abc]') | ||||
|     elems = driver.find_elements(By.CLASS_NAME, 'nav-link') | ||||
|     assert 'Student ID' in elems[0].text | ||||
|     assert 'Good Std' in elems[0].text  | ||||
|      | ||||
|     driver.quit() | ||||
| 
 | ||||
| 
 | ||||
| def test_password_recover_wrong_answers(driver, url, restore_database): | ||||
|     # Student goodstd2@qq.com recover password --> wrong answers | ||||
|     driver.get(url) | ||||
|     driver.maximize_window() | ||||
|     elem = driver.find_element(By.ID, 'goRecover') | ||||
|     elem.click() | ||||
|     elem = driver.find_element(By.NAME, 'email') | ||||
|     elem.send_keys("goodstd2@qq.com") | ||||
|     elem = driver.find_element(By.ID, 'rec') | ||||
|     elem.click() | ||||
|     elem = driver.find_element(By.NAME, 'answer1') | ||||
|     elem.send_keys("wrong") | ||||
|     elem = driver.find_element(By.NAME, 'answer2') | ||||
|     elem.send_keys("wrong") | ||||
|     elem = driver.find_element(By.ID, 'sub') | ||||
|     elem.click() | ||||
|      | ||||
|     driver.quit() | ||||
|      | ||||
| def test_recover_password_with_weak_password(driver, url, restore_database): | ||||
|     driver.get(url) | ||||
|     driver.maximize_window() | ||||
|     elem = driver.find_element(By.ID, 'goRecover') | ||||
|     elem.click() | ||||
|     elem = driver.find_element(By.NAME, 'email') | ||||
|     elem.send_keys("goodstd2@qq.com") | ||||
|     elem = driver.find_element(By.ID, 'rec') | ||||
|     elem.click() | ||||
|     elem = driver.find_element(By.NAME, 'answer1') | ||||
|     elem.send_keys("Wenzhou") | ||||
|     elem = driver.find_element(By.NAME, 'answer2') | ||||
|     elem.send_keys("HotPot") | ||||
|     elem = driver.find_element(By.ID, 'sub') | ||||
|     elem.click() | ||||
|     elem = driver.find_element(By.NAME, 'new_password') | ||||
|     elem.send_keys("123") | ||||
|     elem = driver.find_element(By.NAME, 'confirm_password') | ||||
|     elem.send_keys("123") | ||||
|     elem = driver.find_element(By.ID, "butt") | ||||
|     elem.click() | ||||
|      | ||||
|     wait = WebDriverWait(driver, 10) | ||||
|     alert_elem = wait.until(EC.presence_of_element_located((By.CLASS_NAME, "alert-danger"))) | ||||
|     assert "password must be at least 8 characters long and include uppercase and lowercase letters, numbers, and special characters." in alert_elem.text.lower()  | ||||
|      | ||||
|     driver.quit() | ||||
| 
 | ||||
| def test_recover_password_successfully(driver, url, restore_database): | ||||
|     # Student goodstd2@qq.com recover password ---> correct answers | ||||
|     driver.get(url) | ||||
|     driver.maximize_window() | ||||
|     elem = driver.find_element(By.ID, 'goRecover') | ||||
|     elem.click() | ||||
|     elem = driver.find_element(By.NAME, 'email') | ||||
|     elem.send_keys("goodstd2@qq.com") | ||||
|     elem = driver.find_element(By.ID, 'rec') | ||||
|     elem.click() | ||||
|     elem = driver.find_element(By.NAME, 'answer1') | ||||
|     elem.send_keys("wenzhou") | ||||
|     elem = driver.find_element(By.NAME, 'answer2') | ||||
|     elem.send_keys("hotpot") | ||||
|     elem = driver.find_element(By.ID, 'sub') | ||||
|     elem.click() | ||||
|     elem = driver.find_element(By.NAME, 'new_password') | ||||
|     elem.send_keys("123Abc!!") | ||||
|     elem = driver.find_element(By.NAME, 'confirm_password') | ||||
|     elem.send_keys("123Abc!!") | ||||
|     elem = driver.find_element(By.ID, "butt") | ||||
|     elem.click() | ||||
|      | ||||
|     #Log in Student account | ||||
|     login(driver, url, 'goodstd2@qq.com', '123Abc!!') | ||||
|     elems = driver.find_elements(By.CLASS_NAME, 'nav-link') | ||||
|     assert 'Student ID' in elems[0].text | ||||
|     assert 'Good Std2' in elems[0].text     | ||||
|     driver.quit() | ||||
| 
 | ||||
| def test_recovery_invalid_user_cannot_recover(driver, url, restore_database): | ||||
|     # Unrecognizable user cannot recover | ||||
|     driver.get(url) | ||||
|     driver.maximize_window() | ||||
|     elem = driver.find_element(By.ID, 'goRecover') | ||||
|     elem.click() | ||||
|     elem = driver.find_element(By.NAME, 'email') | ||||
|     elem.send_keys("goodstd3@qq.com") | ||||
|     elem = driver.find_element(By.ID, 'rec') | ||||
|     elem.click() | ||||
|      | ||||
|     wait = WebDriverWait(driver, 10) | ||||
|     alert_elem = wait.until(EC.presence_of_element_located((By.CLASS_NAME, "alert-danger"))) | ||||
|     assert "email address is not recognized." in alert_elem.text.lower() | ||||
|     | ||||
|     driver.quit() | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|  | @ -30,9 +30,12 @@ def test_admin_can_create_lecturer_account(driver, url, admin_username, admin_pa | |||
| 
 | ||||
|     # Log in Lecturer account | ||||
|     login(driver, url, 'mrlan@qq.com', '123Abc!!') | ||||
|     elems = driver.find_elements(By.CLASS_NAME, 'nav-link') | ||||
|     assert '(Lecturer)' in elems[0].text | ||||
|     assert 'Mr Lan' in elems[0].text | ||||
|     #elems = driver.find_elements(By.CLASS_NAME, 'nav-link') | ||||
|     #assert '(Lecturer)' in elems[0].text | ||||
|     #assert 'Mr Lan' in elems[0].text | ||||
|     wait = WebDriverWait(driver, 10) | ||||
|     wait.until(EC.url_contains('SecurityQuestions.php')) | ||||
|      | ||||
|     driver.quit() | ||||
| 
 | ||||
| 
 | ||||
|  | @ -73,9 +76,9 @@ def test_lecturer_can_post_assignment(driver, url, restore_database): | |||
|     ) | ||||
|     elem.click() | ||||
|     elem = driver.find_element(By.NAME, 'deadlinedate') | ||||
|     elem.send_keys('002024/12/30') | ||||
|     elem.send_keys('05/30/2025') | ||||
|     elem = driver.find_element(By.NAME, 'deadlinetime') | ||||
|     elem.send_keys('23:59') | ||||
|     elem.send_keys('11:53PM') | ||||
|     elem = driver.find_element(By.NAME, 'title') | ||||
|     elem.send_keys('Take-home quiz 1') | ||||
|     elem = driver.find_element(By.NAME, 'instructions') | ||||
|  | @ -91,7 +94,7 @@ def test_lecturer_can_post_assignment(driver, url, restore_database): | |||
|     elem = driver.find_element(By.CLASS_NAME, 'card-title') | ||||
|     assert 'Take-home quiz 1 (10 Marks, Individual)' in elem.text | ||||
|     elem = driver.find_element(By.CLASS_NAME, 'text-muted') | ||||
|     assert 'Deadline: 2024-12-30' in elem.text | ||||
|     assert 'Deadline: 2025-05-30' in elem.text | ||||
|     driver.quit() | ||||
| 
 | ||||
| 
 | ||||
|  | @ -161,9 +164,11 @@ def test_student_with_valid_student_number_can_sign_up(driver, url, restore_data | |||
| 
 | ||||
|     # Log in Student account | ||||
|     login(driver, url, '202400000001', '[123Abc]') | ||||
|     elems = driver.find_elements(By.CLASS_NAME, 'nav-link') | ||||
|     assert 'Student ID' in elems[0].text | ||||
|     assert 'Good Student' in elems[0].text | ||||
|     #elems = driver.find_elements(By.CLASS_NAME, 'nav-link') | ||||
|     #assert 'Student ID' in elems[0].text | ||||
|     #assert 'Good Student' in elems[0].text | ||||
|     wait = WebDriverWait(driver, 10)     | ||||
|     wait.until(EC.url_contains('SecurityQuestions.php')) | ||||
|     driver.quit() | ||||
| 
 | ||||
| 
 | ||||
|  | @ -245,6 +250,7 @@ def test_student_can_join_course(driver, url, restore_database): | |||
|     assert 'CSC1111' in elems[0].text | ||||
|     assert 'Project Management' in elems[0].text | ||||
|     assert 'Joined' in elems[0].text | ||||
|     driver.quit() | ||||
| 
 | ||||
| 
 | ||||
| def test_student_can_submit_assignment(driver, url, restore_database): | ||||
|  | @ -264,7 +270,7 @@ def test_student_can_submit_assignment(driver, url, restore_database): | |||
|     elem = driver.find_element(By.NAME, 'title') | ||||
|     elem.send_keys('Assignment submission from Mohamed') | ||||
|     elem = driver.find_element(By.NAME, 'attachment1') | ||||
|     elem.send_keys('/home/mrlan/Downloads/test/SeleniumHui/helper.py') # attach a file | ||||
|     elem.send_keys('/var/www/html/LRR/test/SeleniumHui/helper.py') # attach a file | ||||
|     elem = driver.find_element(By.XPATH, '//form/button') | ||||
|     elem.click() | ||||
| 
 | ||||
|  | @ -277,6 +283,8 @@ def test_student_can_submit_assignment(driver, url, restore_database): | |||
|     assert 'Reading 2 (6 Marks)' in elem.text | ||||
|     assert 'SUBMITTED' in elem.text | ||||
|     assert 'helper.py' in elem.text | ||||
|      | ||||
|     driver.quit() | ||||
| 
 | ||||
| 
 | ||||
| def test_student_can_request_remarking(driver, url, restore_database): | ||||
|  | @ -302,6 +310,8 @@ def test_student_can_request_remarking(driver, url, restore_database): | |||
| 
 | ||||
|     elem = driver.find_element(By.XPATH, '//div[@id="menu4"]/div/div/p/span') | ||||
|     assert 'Remarking request sent' == elem.text | ||||
|      | ||||
|     driver.quit() | ||||
| 
 | ||||
| 
 | ||||
| def test_lecturer_can_mark_assignment(driver, url, restore_database): | ||||
|  | @ -333,6 +343,8 @@ def test_lecturer_can_mark_assignment(driver, url, restore_database): | |||
|     elems[1].click() | ||||
|     elem = driver.find_element(By.XPATH, "//div[@id='menu2']/div/b") | ||||
|     assert 'Reading 1 submission' in elem.text | ||||
|      | ||||
|     driver.quit() | ||||
| 
 | ||||
| 
 | ||||
| def test_lecturer_cannot_see_tas_not_from_his_course(driver, url, restore_database): | ||||
|  |  | |||
|  | @ -11,7 +11,7 @@ def restore_database(): | |||
|         Benefit: we can reproduce the same test result. | ||||
|     ''' | ||||
| 
 | ||||
|     PASSWORD = 'p-@va9'  # root password | ||||
|     PASSWORD = 'root'  # root password | ||||
|     DB_NAME = 'lrr' # database name used for LRR | ||||
| 
 | ||||
|     # commands used to import data to DB_NAME | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue