Compare commits

..

No commits in common. "Hui-Organize" and "Bug352-Neil-Revised" have entirely different histories.

24 changed files with 118 additions and 1497 deletions

3
.gitignore vendored
View File

@ -1,5 +1,2 @@
.vscode
.DS_Store
venv/
__pycache__/
*.pyc

View File

@ -30,7 +30,7 @@ if ($_SESSION['user_type'] != "Lecturer" && $_SESSION['user_type'] != "Admin") {
<ul class="nav nav-tabs" id="myTab">
<li class="nav-item">
<a class="nav-link active" href="#tab-student-accounts" id="batch_tab">Enter student numbers</a>
<a class="nav-link active" href="#tab-student-accounts" id="batch_tab">Create student accounts</a>
</li>
<li class="nav-item">
@ -66,7 +66,7 @@ if ($_SESSION['user_type'] != "Lecturer" && $_SESSION['user_type'] != "Admin") {
?>
<form method="post" action="Script.php" id="create_account_form">
<input type="hidden" name="form_createlecturer" value="true" required="" />
<input type="hidden" name="form_createlecturrer" value="true" required="" />
Full name
<input type="text" name="fullname" placeholder="Full Name" class="form-control" required=""> <br>
Email
@ -93,6 +93,10 @@ if ($_SESSION['user_type'] != "Lecturer" && $_SESSION['user_type'] != "Admin") {
echo '<hr><div class="alert alert-warning" role="alert">' . $_SESSION['info_Admin_Users'] . '</div>';
$_SESSION['info_Admin_Users'] = null;
}
if (isset($_SESSION['info_Admin_Users'])) {
echo '<hr><div class="alert alert-warning" role="alert">' . $_SESSION['info_Admin_Users'] . '</div>';
$_SESSION['info_Admin_Users'] = null;
}
?>
</form>
@ -113,21 +117,10 @@ if ($_SESSION['user_type'] != "Lecturer" && $_SESSION['user_type'] != "Admin") {
<?php
if ($_SESSION['user_type'] == "Lecturer") {
$user_id = $_SESSION['user_id'];
echo "<script>console.log('here {$user_id}');</script>"; // debug trick
// find the TAs in the courses taught by this instructor
$ta_result = mysqli_query(
$con,
"SELECT TA FROM course_ta INNER JOIN courses_table ON course_ta.Course_ID=courses_table.Course_ID WHERE courses_table.Lecturer_User_ID=$user_id"
);
$ta_ids = array(-1); // -1 is non-existent ID
while ($row = mysqli_fetch_assoc($ta_result)) {
array_push($ta_ids, $row['TA']);
}
$ta_ids2 = implode(', ', $ta_ids);
$result = mysqli_query(
$con,
"SELECT * FROM users_table WHERE UserType in ('TA') and User_ID in ($ta_ids2)"
"SELECT * FROM users_table WHERE UserType in ('TA')"
);
}
@ -138,7 +131,6 @@ if ($_SESSION['user_type'] != "Lecturer" && $_SESSION['user_type'] != "Admin") {
);
}
$num_rows = 0;
while ($row = mysqli_fetch_assoc($result)) {
$pass = $row['Password'];
$btn = "<button class='btn btn-warning' onclick=\"updatePassword(" . $row['User_ID'] . ",'$pass')\">Reset</button>";
@ -151,10 +143,6 @@ if ($_SESSION['user_type'] != "Lecturer" && $_SESSION['user_type'] != "Admin") {
}
echo "<tr><td>" . $row['User_ID'] . "</td><td>" . $row['Full_Name'] . "</td><td>" . $row['Email'] . "</td><td>$btn</td><td>$btnBlock</td></tr>";
$num_rows += 1;
}
if ($num_rows == 0) {
echo "<p>No TA</p>";
}
?>
</table>
@ -239,22 +227,8 @@ if ($_SESSION['user_type'] != "Lecturer" && $_SESSION['user_type'] != "Admin") {
</div>
<?php include 'Footer.php';?>
<script>
/** After creating a TA account, stay on the same tab "Create instructor account"
Side effect: ?tacreated will be appended on the URL
*/
document.addEventListener("DOMContentLoaded", () => {
const url = new URL(window.location.href);
if (url.searchParams.has('tacreated')) {
const elem = document.querySelector('#tab_ins_accounts');
elem.click();
}
});
</script>
<script>
function updatePassword(id, pass) {
if (!confirm('Are you sure to reset user password?')) {

View File

@ -1,87 +0,0 @@
<?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);
?>

View File

@ -86,22 +86,22 @@ include 'Header.php';
<ul class="nav nav-tabs" id="myTab">
<li class="nav-item">
<a class="nav-link <?php if (!isset($_GET['tab']) || $_GET['tab'] == 'New') echo 'active'; ?>" data-toggle="tab" href="#menu1">New</a>
<a class="nav-link active" href="#menu1">New</a>
</li>
<li class="nav-item">
<a class="nav-link <?php if ($_GET['tab'] == 'Missed') echo 'active'; ?>" data-toggle="tab" href="#menu2">Missed</a>
<a class="nav-link" href="#menu2">Missed</a>
</li>
<li class="nav-item">
<a class="nav-link <?php if ($_GET['tab'] == 'Submitted') echo 'active'; ?>" data-toggle="tab" href="#menu3">Submitted</a>
<a class="nav-link" href="#menu3">Submitted</a>
</li>
<li class="nav-item">
<a class="nav-link <?php if ($_GET['tab'] == 'Marked') echo 'active'; ?>" data-toggle="tab" href="#menu4">Marked</a>
<a class="nav-link" href="#menu4">Marked</a>
</li>
</ul>
<div class="tab-content">
<div id="menu1" class="tab-pane <?php if (!isset($_GET['tab']) || $_GET['tab'] == 'New') echo 'active'; ?>">
<div id="menu1" class="tab-pane active">
<?php
@ -152,7 +152,7 @@ include 'Header.php';
$att3 = $row['Attachment_link_3'];
$att4 = $row['Attachment_link_4'];
$labid = $row['Lab_Report_ID'];
$days_remaining = "Days remaining: ".date_diff(date_create($deadline), date_create())->format('%a days, %h hours, %i minutes');
$days_remaining = date_diff(date_create($deadline), date_create())->format('%a days, %h hours, %i minutes');
$full_link = "<a href='~\..\Download.php?file=$att1'>$att1</a>";
if($att2 != "") {
@ -165,11 +165,6 @@ include 'Header.php';
$full_link = $full_link."| <a href='~\..\Download.php?file=$att4'>$att4</a>";
}
// check if the student has already submitted the assignment
$query_result = mysqli_query($con, "SELECT * FROM lab_report_submissions WHERE Student_id=$student_id AND Lab_Report_ID=$labid");
if (mysqli_num_rows($query_result) > 0)
$days_remaining = 'You have already submitted this assignment.';
echo "<div class='card mt-md-2' style='word-wrap: break-word;'>
<div class='card-body'>
<h5 class='card-title'>$title</h5>
@ -177,7 +172,7 @@ include 'Header.php';
<p class='card-text'> $ins </p>
<p> <small>Attachments</small>: $full_link </p>
<p class='card-text'> <small> Posted: $posted &nbsp;&nbsp; Deadline: $deadline </small> </p>
<div class='alert alert-warning'>$days_remaining</div>
<div class='alert alert-warning'>Time left: $days_remaining</div>
<p><a href='~\..\SubmitLab.php?id=$labid&url=$url' class='btn btn-primary'>Submit</a></p>
</div>
</div>";
@ -190,7 +185,7 @@ include 'Header.php';
<div id="menu2" class="tab-pane <?php if ($_GET['tab'] == 'Missed') echo 'active'; ?>">
<div id="menu2" class="tab-pane">
<?php
$group_id = $_SESSION['group_id'];
@ -256,7 +251,7 @@ include 'Header.php';
<div id="menu3" class="tab-pane <?php if ($_GET['tab'] == 'Submitted') echo 'active'; ?>">
<div id="menu3" class="tab-pane">
<?php
$group_id = $_SESSION['group_id'];
@ -329,10 +324,10 @@ include 'Header.php';
$att2 = $row['Attachment2'];
$att3 = $row['Attachment3'];
$att4 = $row['Attachment4'];
$base_att1 = basename(rawurldecode($att1));
$base_att2 = basename(rawurldecode($att2));
$base_att3 = basename(rawurldecode($att3));
$base_att4 = basename(rawurldecode($att4));
$base_att1 = basename($att1);
$base_att2 = basename($att2);
$base_att3 = basename($att3);
$base_att4 = basename($att4);
$full_link = "<a href='~\..\Download.php?file=$att1&attachment=1'>$base_att1</a>"; // prevent students from directly accessing their classmates' submissions
@ -376,7 +371,7 @@ include 'Header.php';
?>
<div id="menu4" class="tab-pane <?php if ($_GET['tab'] == 'Marked') echo 'active'; ?>">
<div id="menu4" class="tab-pane">
<?php
$resultx = mysqli_query($con, "SELECT Submission_ID, Submission_Date, lab_reports_table.Lab_Report_ID, Student_id, Course_Group_id, Notes, lab_report_submissions.Marks, lab_report_submissions.Remarking_Reason, Status, lab_reports_table.Title Lab_Title, lab_reports_table.Marks Original_marks
FROM lab_report_submissions
@ -652,12 +647,11 @@ include 'Header.php';
function remarking(url)
function remarking(data)
{
const details = prompt("Please enter your remarking reasons","");
if (details != null) {
window.location.href = url+"&details="+details;
}
window.location.href = data+"&details="+details;
}

View File

@ -324,7 +324,7 @@ include 'Header.php';
}
echo "</div>";
$resultx1 = mysqli_query($con, "SELECT DISTINCT course_students_table.Student_ID, users_table.Full_Name
$resultx1 = mysqli_query($con, "SELECT course_students_table.Student_ID, users_table.Full_Name
FROM course_students_table
INNER JOIN users_table on users_table.Student_ID=course_students_table.Student_ID
WHERE Course_ID=$course_id");
@ -494,10 +494,6 @@ include 'Header.php';
echo '<hr><span class="alert alert-success" role="alert">' . $_SESSION['info_Courses_student'] . '</span>';
$_SESSION['info_Courses_student'] = null;
}
if (isset($_SESSION['info_signup'])) {
echo '<hr><div class="alert alert-danger" role="alert">' . $_SESSION['info_signup'] . '</div>';
$_SESSION['info_signup'] = null;
}
?>
<br><br>
</div>
@ -538,7 +534,7 @@ include 'Header.php';
}
if (mysqli_num_rows($result) == 0) {
echo "No such course offered in this academic year. Please check that your have entered the correct course code.<hr>";
echo "No results. <hr>";
} else {
while($row = mysqli_fetch_assoc($result)) {
$name = $row['Course_Name'];

View File

@ -1,24 +1,14 @@
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
?>
<?php
session_start();
error_reporting(0);
date_default_timezone_set('Asia/Shanghai');
include "get_mysql_credentials.php";
try {
$con = mysqli_connect("localhost", $mysql_username, $mysql_password, "lrr");
} catch (mysqli_sql_exception $e) {
echo $e->getMessage();
}
$con = mysqli_connect("localhost", $mysql_username, $mysql_password, "lrr");
// Check database connection
if (mysqli_connect_errno()) {
echo " Error number: ".mysqli_connect_errno();
exit();
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
?>
@ -162,7 +152,7 @@ if (mysqli_connect_errno()) {
<?php
if (isset($_SESSION["user_fullname"])) {
if ($_SESSION['user_type'] == "Student" || $_SESSION['user_type'] == 'Lecturer' || $_SESSION['user_type'] == 'TA') {
if ($_SESSION['user_type'] == "Student" || $_SESSION['user_type'] == 'Lecturer') {
echo "<a class='nav-link' href='~\..\Courses.php'><i class='fa fa-book'></i> My courses </a>";
}
?>

View File

@ -3,9 +3,9 @@
LRR (Lab Report Repository) is an online software application for course instructors to post, receive and mark assignments, and for students to submit assignments, or submit re-marking requests.
This software was originally developed by Mahomed Nor in 2018, a graduate student in the Department of Computer Science at the Zhejiang Normal University,
while he was taking a graduate course called Advanced Software Engineering.
while he was taking a graduate course called **Advanced Software Engineering** (http://lanlab.org/course/2018f/se/homepage.html).
For potential project contributors, we recommend that you browse its home page at ./homepage/index.html first to familiarize yourself with the project.
The LRR's project home page is at http://121.4.94.30/homepage/. For potential project contributors, we recommend that you browse its home page first to familiarize yourself with the project.
@ -159,16 +159,7 @@ https://github.com/spm2020spring/TeamCollaborationTutorial/blob/master/team.rst
## Testing
Make sure your changes can pass all the tests in folder ./test.
You cannot do too much unit testing for LRR because it almost does not
have functions or classes. However, you can do end-to-end testing.
It is important that you *restore* the database each time before your
run a test case. The fixture *restore_database* in ./test/conftest.py
is used to restore the database. Please check that. A use case for
this fixture can be found in the test script
./test/SeleniumMpiana/test_bug418_yaaqob.py. You could run this test script
by typing the following command: `pytest ./SeleniumMpiana/test_bug418_yaaqob.py`
Make sure your changes can pass all the tests in folder [./test](http://121.4.94.30:3000/mrlan/LRR/src/branch/master/test).
## Communications Method
@ -258,6 +249,6 @@ Nicole-Rutagengwa - Nicole Rutagengwa - 2019169
# References
- 詹沈晨. (2020). 网页程序测试自动化 (Selenium) 测试效率.
- 詹沈晨. (2020). [网页程序测试自动化 (Selenium) 测试效率](http://lanlab.org/ZhanShenchen-On-Automated-Web-Application-Test-Efficiency-with-Selenium.doc)
- Ibrahim. (2021). Defect analysis for LRR]
- Ibrahim. (2021). [Defect analysis for LRR](http://lanlab.org/thesis/Defect-Analysis-for-LRR.docx)

View File

@ -1,78 +0,0 @@
<?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);
?>

View File

@ -70,20 +70,15 @@ if (!empty($_POST["form_signup"])) {
// check if email is taken
$result = mysqli_query($con, "SELECT * FROM users_table WHERE email='$email'");
if (mysqli_num_rows($result) != 0) {
$_SESSION["info_signup"] = "Email address " . $email . " is already in use. You have already signed up?";
$_SESSION["info_signup"] = "Email address " . $email . " is already in use.";
$_SESSION['user_fullname'] = null;
header("Location: signup.php");
return;
}
$_SESSION['user_fullname'] = $_POST["fullname"];
$_SESSION['user_fullname_temp'] = $_POST["fullname"];
$_SESSION['user_email'] = $_POST["email"];
$_SESSION['user_student_id_temp'] = $_POST["user_student_id"];
// validate student number
if (!is_valid_student_number($student_id)) {
$_SESSION["info_signup"] = "Invalid student number.";
$_SESSION['user_fullname'] = null;
header("Location: signup.php");
return;
}
@ -92,10 +87,6 @@ if (!empty($_POST["form_signup"])) {
$result = mysqli_query($con, "SELECT * FROM `students_data` WHERE Student_ID='$student_id'");
if (mysqli_num_rows($result) == 0) {
$_SESSION["info_signup"] = "Your entered student number could not be verified. Please contact Student Management Office <lanhui at zjnu.edu.cn>. Thanks.";
$_SESSION['user_fullname'] = null;
header("Location: signup.php");
return;
}
@ -106,7 +97,6 @@ if (!empty($_POST["form_signup"])) {
$student_result = mysqli_query($con, "SELECT * FROM `users_table` WHERE Student_ID='$student_id'");
if (mysqli_num_rows($student_result) > 0) {
$_SESSION["info_signup"] = "This Student ID is already in use! Please contact Student Management Office <lanhui at zjnu.edu.cn> for help.";
$_SESSION['user_fullname'] = null;
header("Location: signup.php");
return;
}
@ -116,75 +106,18 @@ if (!empty($_POST["form_signup"])) {
if (!empty($_POST["form_signup"])) {
$fullname = mysqli_real_escape_string($con, $_POST["fullname"]);
$student_id = mysqli_real_escape_string($con, $_POST["user_student_id"]);
$email = mysqli_real_escape_string($con, $_POST["email"]);
$password = mysqli_real_escape_string($con, $_POST["password"]);
$confirmpassword = mysqli_real_escape_string($con, $_POST["confirmpassword"]);
$_SESSION['user_student_id'] = $_POST["student_id"];
$_SESSION['user_type'] = "Student";
// check confirmed password
if (strcasecmp($password, $confirmpassword) != 0) {
$_SESSION['info_signup'] = "Password confirmation failed.";
$_SESSION['user_fullname'] = null; // such that Header.php do not show the header information.
header("Location: signup.php");
return;
}
// validate email
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$_SESSION['info_signup'] = "Invalid email address.";
$_SESSION['user_fullname'] = null;
header("Location: signup.php");
return;
}
$upperLetter = preg_match('@[A-Z]@', $password);
$smallLetter = preg_match('@[a-z]@', $password);
$containsDigit = preg_match('@[0-9]@', $password);
$containsSpecial = preg_match('@[^\w]@', $password);
$containsAll = $upperLetter && $smallLetter && $containsDigit && $containsSpecial;
// check for strong password
if (!$containsAll) {
$_SESSION['info_signup'] = "Password must have at least characters that include lowercase letters, uppercase letters, numbers and special characters (e.g., !?.,*^).";
$_SESSION['user_fullname'] = null;
header("Location: signup.php");
return;
}
// check if email is taken
$result = mysqli_query($con, "SELECT * FROM users_table WHERE email='$email'");
if(mysqli_num_rows($result) != 0)
{
$_SESSION["info_signup"]="Email address ".$email." is already in use. Do you have an old LRR account?";
}
$_SESSION['user_fullname'] = $fullname;
$_SESSION['user_type'] = "Student";
$_SESSION['user_email'] = $email;
$_SESSION['user_student_id'] = $student_id;
// apply password_hash()
$password_hash = password_hash($password, PASSWORD_DEFAULT);
$sql = "INSERT INTO `users_table`(`Email`, `Password`, `HashPassword`, `Full_Name`, `UserType`, `Student_ID`) VALUES "
. "('$email','$password_hash','','$fullname','Student','$student_id')";
$_SESSION['user_fullname'] =$_SESSION['user_fullname_temp'];
$sql = "INSERT INTO `users_table`(`Email`, `Password`, `Full_Name`, `UserType`, `Student_ID`) VALUES "
. "('$email','$password_hash','$fullname','Student','$student_id')";
if ($con->query($sql) === TRUE) {
// Get the newly inserted user's ID
$user_id = $con->insert_id;
//Set the user_id in the session
$_SESSION['user_id'] = $user_id;
//Redirect to SecurityQuestions.php
header("Location: SecurityQuestions.php");
header("Location: Courses.php");
} else {
echo "Something really bad (SQL insertion error) happened during sign up.";
}
@ -197,15 +130,11 @@ if (!empty($_POST["form_login"])) {
$user = mysqli_real_escape_string($con, $_POST["user"]); // user could be a 12-digit student number or an email address
$is_student_number = 0;
$_SESSION["failed_login_user"] = $user; // Save the entered username in a session variable
echo "Failed login user: " . $_SESSION["failed_login_user"];
// Validate student number
if (is_valid_student_number($user)) {
$is_student_number = 1;
}
// Validate email address if what provided is not a student number
if (!$is_student_number && !filter_var($user, FILTER_VALIDATE_EMAIL)) {
$_SESSION["info_login"] = "Invalid email address: " . "$user";
@ -231,91 +160,61 @@ 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") {
// 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") {
$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"); }
header("Location: Courses.php");
}
if ($_SESSION['user_type'] == "TA") {
$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"); }
header("Location: Courses.php");
}
if ($_SESSION['user_type'] == "Admin") {
$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"); }
header("Location: Admin.php");
}
// report wrong pass if not correct
return;
} else {
$_SESSION["wrong_pass"] = "Wrong Password.";
echo $_SESSION["wrong_pass"]; // Optional: Display the error message for debugging
header("Location: index.php");
exit(); // Add this line to prevent further execution after redirect
}
// 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 email
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$_SESSION["info_recover_password"] = "Invalid email address.";
header("Location: RecoverPassword.php");
// 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;
}
// 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");
}
// 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");
return;
}
$result = mysqli_query($con, "SELECT * FROM users_table WHERE Email='$email' and Student_ID='$student_id'");
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");
} else {
$result = mysqli_query($con, "DELETE FROM users_table WHERE Email='$email' and Student_ID='$student_id'");
header("Location: signup.php");
}
}
// ################################ RESET Password #####################################
@ -364,7 +263,7 @@ if (!empty($_POST["form_reset_password"])) {
}
// ############################### CREATE Lecturer/TA USER ##################################
if (!empty($_POST["form_createlecturer"])){
if (!empty($_POST["form_createlecturrer"])){
$email = mysqli_real_escape_string($con, $_POST["email"]);
$fullname = mysqli_real_escape_string($con, $_POST["fullname"]);
$type = mysqli_real_escape_string($con, $_POST["type"]);
@ -384,15 +283,17 @@ if (!empty($_POST["form_createlecturer"])){
exit;
}
$password_hash = password_hash("$password", PASSWORD_DEFAULT);
$sql = "INSERT INTO `users_table`(`Email`, `Password`, `HashPassword`, `Full_Name`, `UserType`) VALUES ('$email','$password_hash','','$fullname','$type')";
$sql = "INSERT INTO `users_table`(`Email`, `Password`, `Full_Name`, `UserType`) VALUES "
. "('$email','$password_hash','$fullname','$type')";
try {
$result = mysqli_query($con, $sql);
if ($con->query($sql) === TRUE) {
$_SESSION["info_Admin_Users"] = $type . " user created successfully. Use email " . $email . " as account name and ". $password ." as password.";
header("Location: Admin.php?tacreated");
} catch (Exception $ex) {
echo "$ex";
header("Location: Admin.php");
} else {
alert("Error: " . $sql . "<br>" . $con->error);
}
}
// ### FUNCTION TO GENERATE INITIAL PASSWORDS ###//
@ -812,8 +713,8 @@ if (!empty($_GET["remarking"])) {
if ($con->query($sql) === TRUE) {
$_SESSION["info_general"] = "Remarking Request Sent";
header("Location: Course.php?url=" . $url . "&tab=Marked");
$_SESSION["info_general"] = "Remarking request sent";
header("Location: Course.php?url=" . $url);
} else {
echo "Error: " . $sql . "<br>" . $con->error;
}

View File

@ -1,139 +0,0 @@
<?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>

View File

@ -151,10 +151,10 @@ echo "<div><a href='Courses.php?course=$url'> $header </a></div>";
$submitted_by = "$student_name ($submitter_student_number) for group $groupname ";
}
$base_att1 = basename(rawurldecode($att1));
$base_att2 = basename(rawurldecode($att2));
$base_att3 = basename(rawurldecode($att3));
$base_att4 = basename(rawurldecode($att4));
$base_att1 = basename($att1);
$base_att2 = basename($att2);
$base_att3 = basename($att3);
$base_att4 = basename($att4);
$full_link = "<a href='~\..\Download.php?file=$att1&attachment=1'>$base_att1</a>"; // prevent students from directly accessing their classmates' submissions

View File

@ -1,94 +0,0 @@
Contributed by Aya Boussouf 2025-05-19
# ---------------------- System Update & LAMP Stack Installation ----------------------
sudo apt update && sudo apt upgrade -y
sudo apt install apache2 mysql-server php libapache2-mod-php php-mysql unzip git -y
# ---------------------- Start and Enable Apache & MySQL Services ----------------------
sudo systemctl start apache2
sudo systemctl enable apache2
sudo systemctl start mysql
sudo systemctl enable mysql
# ---------------------- Configure MySQL Root User ----------------------
sudo mysql
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'root';
FLUSH PRIVILEGES;
exit;
# ---------------------- Create LRR Database ----------------------
mysql -u root -p
CREATE DATABASE lrr;
exit;
# ---------------------- Clone LRR Project Repository ----------------------
cd /var/www/html/
sudo git clone http://118.25.96.118:3000/mrlan/LRR.git
sudo chown -R $USER:$USER /var/www/html/LRR
# ---------------------- Switch to Hui-Organize Branch ----------------------
cd /var/www/html/LRR
git branch
git checkout -b Hui-Organize
git pull origin Hui-Organize
# ---------------------- Import SQL Data into MySQL ----------------------
sudo mysql -u root -p lrr < /var/www/html/LRR/lrr_database.sql
# ---------------------- Create Submission Folder for Assignments ----------------------
cd /var/www/
sudo mkdir lrr_submission
sudo chown -R www-data:www-data lrr_submission
sudo chmod -R g+rw lrr_submission
# ---------------------- Configure Database Credentials in KeepItSafe.txt ----------------------
sudo nano /var/www/lrr_submission/KeepItSafe.txt
# Add: root,root (username,password for MySQL connection)
# ---------------------- Configure Apache Virtual Host for LRR ----------------------
sudo nano /etc/apache2/sites-available/LRR.conf
<VirtualHost *:80>
ServerName localhost
DocumentRoot /var/www/html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
# ---------------------- Enable Apache Config and Rewrite Module ----------------------
sudo a2ensite LRR
sudo a2enmod rewrite
sudo systemctl reload apache2
# ---------------------- Install Google Chrome (for Selenium Tests) ----------------------
cd ~/Downloads
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
sudo apt install ./google-chrome-stable_current_amd64.deb
# ---------------------- Install ChromeDriver ----------------------
wget https://storage.googleapis.com/chrome-for-testing-public/136.0.7103.92/linux64/chromedriver-linux64.zip
unzip chromedriver-linux64.zip
sudo mv chromedriver-linux64/chromedriver /usr/local/bin/
sudo chmod +x /usr/local/bin/chromedriver
# ---------------------- Install Python, pip and Virtual Environment ----------------------
sudo apt install python3 python3-pip -y
sudo apt install python3-venv -y
# ---------------------- Create and Activate Virtual Environment for LRR ----------------------
cd /var/www/html/LRR
python3 -m venv venv
source venv/bin/activate
# ---------------------- Install Required Python Packages ----------------------
pip install selenium
pip install pytest
# ---------------------- Run Selenium Tests ----------------------
cd test
# Make necessary edits in `conftest.py` and `test_lrr.py`.
pytest -v SeleniumHui/test_lrr.py

View File

@ -30,7 +30,7 @@ if (isset($_SESSION["user_fullname"])) {
<legend>Sign in</legend>
<input type="hidden" name="form_login" value="true"/>
<label for="user_name" class="form-label">Account name</label>
<input type="text" name="user" placeholder="Student Number / Email address" class="form-control" required="required" id="user_name" value="<?php echo isset($_SESSION['failed_login_user']) ? htmlspecialchars($_SESSION['failed_login_user']) : ''; ?>" />
<input type="text" name="user" placeholder="Student Number / Email address" class="form-control" required="required" id="user_name" />
<br>
<label for="user_password" class="form-label">Password</label>
<input type="password" class="form-control" name="password" placeholder="password" required="required" id="user_password" />
@ -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 id="goRecover" href="RecoverPassword.php">Recover</a>
<label class="form-text">Forget your password?</label> <a href="recover_password.php">Recover</a>
<?php

View File

@ -61,7 +61,7 @@ CREATE TABLE `courses_table` (
INSERT INTO `courses_table` (`Course_ID`, `Course_Name`, `Academic_Year`, `Faculty`, `Lecturer_User_ID`, `TA_User_ID`, `Course_Code`, `URL`, `Verify_New_Members`) VALUES
(10, 'Software Engineering', '2018', 'Computing', 8, 0, 'CSC1234', 'CSC12342018', '1'),
(11, 'Project Management', '2024', 'Computing', 8, 0, 'CSC1111', 'CSC11112024', '0'),
(11, 'Project Management', '2019', 'Computing', 8, 0, 'P.M2019', 'P.M20192019', '0'),
(12, 'Ashly Course Testing', '2020', 'Testing', 8, 0, 'Teecloudy', 'Teecloudy2020', '1');
-- --------------------------------------------------------
@ -136,7 +136,7 @@ INSERT INTO `course_students_table` (`Course_ID`, `Student_ID`, `ID`, `Status`)
(10, '201825800050', 13, 'Joined'),
(10, '201825800054', 14, 'Joined'),
(12, '201632120150', 15, 'Joined'),
(12, '201632120150', 16, 'Joined'),
(12, '2016321201502', 16, 'Joined'),
(12, '201825800050', 17, 'Joined');
-- --------------------------------------------------------
@ -200,7 +200,7 @@ CREATE TABLE `lab_reports_table` (
INSERT INTO `lab_reports_table` (`Lab_Report_ID`, `Course_ID`, `Posted_Date`, `Deadline`, `Instructions`, `Title`, `Attachment_link_1`, `Attachment_link_2`, `Attachment_link_3`, `Attachment_link_4`, `Marks`, `Type`) VALUES
(1, 10, '2019-01-11 16:52', '2019-02-11 17:00', 'Description of the lab....', 'Reading 1', '700IMPORTANT WORDS.txt', '', '', '', '4', 'Individual'),
(2, 10, '2024-09-29 11:12', '2025-07-30 23:59', 'Read this paper http://sunnyday.mit.edu/16.355/budgen-david.pdf', 'Reading 2', '586LRR-Test-caseS.pdf', '', '', '', '6', 'Individual'),
(2, 10, '2019-01-17 11:12', '2019-01-25 23:59', 'Read this paper http://sunnyday.mit.edu/16.355/budgen-david.pdf', 'Reading 2', '586LRR-Test-caseS.pdf', '', '', '', '6', 'Individual'),
(3, 12, '2020-04-05 02:48', '2020-04-12 ', 'Do this assignment in time for testing', 'First Assignment Testing', '', '', '', '', '3', 'Group'),
(4, 12, '2020-04-05 05:36', '2020-04-06 ', 'We are testing to see if the instructor can be able to modify the work', 'Second Assignment Testing', '', '', '', '', '3', 'Individual'),
(5, 12, '2020-04-05 05:51', '2020-04-08 ', 'ASQDASDASCDD', 'Third Assignment Testingas', '', '', '', '', '3', 'Individual'),
@ -235,7 +235,7 @@ CREATE TABLE `lab_report_submissions` (
--
INSERT INTO `lab_report_submissions` (`Submission_ID`, `Submission_Date`, `Lab_Report_ID`, `Student_id`, `Course_Group_id`, `Attachment1`, `Notes`, `Attachment2`, `Attachment3`, `Attachment4`, `Marks`, `Status`, `Title`, `Visibility`, `Remarking_Reason`) VALUES
(1, '2019-01-17 00:00:00', 1, '201825800050', 0, 'Reading list.txt', '-', '', '', '', NULL, 'Pending', 'Reading 1 submission', 'Public', ''),
(1, '2019-01-17 00:00:00', 1, '201825800050', 0, 'Reading list.txt', '-', '', '', '', 5, 'Marked', 'Reading 1 submission', 'Public', ''),
(5, '2019-01-21 08:31:00', 2, '201825800050', 0, 'Trial Balance.txt', ' - @2019-01-21 09:35 : Sorry I missed some details from your report', 'Boorka.jpg', '', '', 6, 'Marked', 'Submission x', 'Private', ''),
(30, '2020-04-06 23:18:00', 3, '0', 31, '/2016321201502/First Assignment Testing/UR Diagram.pdf', '<br>@2020-04-06 23:19 : ', '', '', '', 3, 'Marked', 'First Assignment Testing', 'Private', '');
@ -259,11 +259,7 @@ INSERT INTO `students_data` (`ID`, `Student_ID`, `Passport_Number`) VALUES
(1, '201825800054', 'LJ7951632'),
(2, '201825800050', 'P00581929'),
(3, '201632120150', 'FN524516'),
(4, '202400000001', 'NA'),
(5,'201932130101',''),
(6,'201920781742','');
(4, '11', '11');
-- --------------------------------------------------------
@ -272,7 +268,7 @@ INSERT INTO `students_data` (`ID`, `Student_ID`, `Passport_Number`) VALUES
--
CREATE TABLE `users_table` (
`User_ID` int(11) NOT NULL AUTO_INCREMENT,
`User_ID` int(11) NOT NULL,
`Email` varchar(50) COLLATE utf8mb4_bin DEFAULT NULL,
`Password` varchar(250) CHARACTER SET utf8 DEFAULT NULL,
`HashPassword` varchar(250) COLLATE utf8mb4_bin NOT NULL,
@ -280,8 +276,7 @@ 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',
PRIMARY KEY (`User_ID`)
`Status` varchar(30) COLLATE utf8mb4_bin NOT NULL DEFAULT 'Active'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
--
@ -290,36 +285,15 @@ CREATE TABLE `users_table` (
INSERT INTO `users_table` (`User_ID`, `Email`, `Password`, `HashPassword`, `Full_Name`, `UserType`, `Student_ID`, `Passport_Number`, `Status`) VALUES
(3, 'admin@qq.com', '$2y$10$8GCG6lTo1LFRD3bOkAyKYeOMOrFSBUgrTxaPLS5ynWN1bYDHf89pO', '', 'Kamal', 'Admin', '0', NULL, 'Active'),
(7, 'peter@qq.com', '$2y$10$8GCG6lTo1LFRD3bOkAyKYeOMOrFSBUgrTxaPLS5ynWN1bYDHf89pO', '', 'Peter', 'Lecturer', NULL, '123', 'Active'),
(8, 'lanhui@qq.com', '$2y$10$8GCG6lTo1LFRD3bOkAyKYeOMOrFSBUgrTxaPLS5ynWN1bYDHf89pO', '', 'Lanhui', 'Lecturer', NULL, '123', 'Active'),
(9, 'mohamed@qq.com', '$2y$10$8GCG6lTo1LFRD3bOkAyKYeOMOrFSBUgrTxaPLS5ynWN1bYDHf89pO', '', 'Mohamed', 'Student', '201825800050', 'P00581929', 'Active'),
(8, 'lanhui@qq.com', '1234', '', 'Lanhui', 'Lecturer', NULL, '123', 'Active'),
(9, 'mohamed@qq.com', '123', '', 'Mohamed', 'Student', '201825800050', 'P00581929', 'Active'),
(10, 'mark@qq.com', '123', '', 'Mark ', 'TA', NULL, '123', 'Active'),
(11, 'john@qq.com', '123', '', 'John', 'TA', NULL, '123', 'Active'),
(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'),
(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');
(19, '11@11.11', 'dfdf', '760a8f4f392f1f6bc3ecb118365c6cd039b59fdce96122897d5157970d9c9c129bd73b3c402dbeedd8fe94d319df7bd7de0025c22839fec06631a025ec1e0e69', '11', 'Student', '11', '', '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
--
@ -373,6 +347,12 @@ 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
--
@ -430,7 +410,12 @@ 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 */;

View File

@ -15,9 +15,11 @@ 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 id="rec" type="submit" class="btn btn-primary">Recover</button>
<button type="submit" class="btn btn-primary">Recover</button>
</form>
</div>
</div>

View File

@ -22,10 +22,10 @@ include 'Header.php';
<input type="hidden" name="form_signup" value="true" />
Full Name
<input type="text" name="fullname" placeholder="Your full name" class="form-control" value="<?php echo isset($_SESSION['user_fullname_temp']) ? $_SESSION['user_fullname_temp'] : ''; ?>" required="required" id="full_name"/> <br>
<input type="text" name="fullname" placeholder="Your full name" class="form-control" value="<?php echo $_SESSION['user_fullname']; ?>" required="required" id="full_name"/> <br>
Student ID
<input type="text" name="user_student_id" placeholder="Entre your student ID" class="form-control" value="<?php echo isset($_SESSION['user_student_id_1']) ? $_SESSION['user_student_id_temp'] : ''; ?>" required="required" id="student_id"> <br>
<input type="text" name="user_student_id" placeholder="Entre your student ID" class="form-control" value="<?php echo $_SESSION['user_student_id']; ?>" required="required" id="student_id"> <br>
Email
<input type="text" name="email" placeholder="Email" class="form-control" value="<?php echo $_SESSION['user_email']; ?>" required="required" id="email" /> <br>

View File

@ -1,37 +0,0 @@
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()

View File

@ -1,156 +0,0 @@
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()

View File

@ -1,46 +0,0 @@
Sign-Up Automation Test Script
Overview
This script automates the sign-up process for a web application using Selenium WebDriver. It tests whether form values are retained correctly if the initial sign-up attempt fails and requires modification of the student ID before resubmission.
Prerequisites
Python 3
Selenium library
Chrome WebDriver
A running instance of the web application on http://localhost:8080
Configuration
Web Application URL: Make sure the web application is running at http://localhost:8080. Adjust the URL in the script if necessary.
Update Element Locators: Ensure the IDs used in the script (signup_link, signup_form, full_name, student_id, email, password1, password2, signup_btn) match those in your web application.
Run the script:
Script Logic
Open the Login Page: The script navigates to the login page of the web application.
Click the "Sign Up" Link: It waits for the "Sign Up" link to appear and clicks it to navigate to the sign-up page.
Fill Out the Sign-Up Form: It fills out the form fields (Full Name, Student ID, Email, Password).
Submit the Form: It submits the form and waits for the result.
Check for Sign-Up Failure: If sign-up fails, it checks if form values are retained.
Modify Student ID: If the form values are retained, it modifies the student ID and resubmits the form.
Verify Retained Values: It verifies if other fields retain their values after modifying the student ID.
Print Retained Values: If the second attempt is successful, it prints the retained form values.
Close the Browser: The browser is closed at the end of the script execution.
The script provides the following output:
Sign-Up Successful: Indicates the sign-up was successful on the first attempt.
Sign-Up Failed: Indicates the sign-up failed on the first attempt and checks for retained values.
Second Sign-Up Attempt Successful: Indicates the second sign-up attempt was successful and prints the retained values.
Second Sign-Up Attempt Failed: Indicates the second sign-up attempt also failed, suggesting further investigation is needed.
Notes
Form Field IDs: Ensure the IDs used in the script match those in your web application.
Password Fields: The script intentionally does not print password fields for security reasons.
Adjust Wait Times: Modify the wait times as needed depending on your application's response times.
Troubleshooting
Element Not Found: Verify the element IDs and update them in the script.
WebDriver Errors: Ensure the Chrome WebDriver is installed and matches your Chrome browser version.
Connection Errors: Ensure the web application is running and accessible at the specified URL.
Contributing

View File

@ -1,88 +0,0 @@
import time # Import time module for waiting
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# New instance of the Chrome driver
driver = webdriver.Chrome()
try:
# Step 1: Open the login page
driver.get("http://localhost:8080/lrr/lrr/admin.php") # Replace with your actual login page URL
# Step 2: Wait for the login page to fully load and locate the "Sign Up" link
sign_up_link = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "signup_link"))
)
# Step 3: Click the "Sign Up" link to navigate to the sign-up page
sign_up_link.click()
# Step 4: Wait for the sign-up page to fully load
WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "signup_form"))
)
# Step 5: Fill out the sign-up form
driver.find_element(By.ID, "full_name").send_keys("John Doe")
driver.find_element(By.ID, "student_id").send_keys("12345678")
driver.find_element(By.ID, "email").send_keys("john.doe@example.com")
driver.find_element(By.ID, "password1").send_keys("Password123!")
driver.find_element(By.ID, "password2").send_keys("Password123!")
# Step 6: Submit the sign-up form
driver.find_element(By.ID, "signup_btn").click()
# Step 7: Wait for the sign-up result
WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.TAG_NAME, "body"))
)
# Check if sign-up failed
if "alert-danger" in driver.page_source:
print("Sign-up failed. Checking if form values are retained...")
# Wait for a few seconds (adjust as needed)
time.sleep(3)
# Modify the student ID again
driver.find_element(By.ID, "student_id").clear()
driver.find_element(By.ID, "student_id").send_keys("87654321")
# Verify if the other fields retain their values
assert driver.find_element(By.ID, "full_name").get_attribute("value") == "John Doe"
assert driver.find_element(By.ID, "email").get_attribute("value") == "john.doe@example.com"
assert driver.find_element(By.ID, "password1").get_attribute("value") == ""
assert driver.find_element(By.ID, "password2").get_attribute("value") == ""
# Resubmit the form
driver.find_element(By.ID, "signup_btn").click()
# Wait for the result again
WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.TAG_NAME, "body"))
)
# Check for success or failure after second attempt
if "alert-danger" in driver.page_source:
print("Second sign-up attempt failed. Further investigation needed.")
# Print the retained values
print("Retained form values after second attempt:")
print("Full Name:", driver.find_element(By.ID, "full_name").get_attribute("value"))
print("Email:", driver.find_element(By.ID, "email").get_attribute("value"))
# Password fields might be intentionally cleared, so they won't be printed here
print("Modified Student ID:", driver.find_element(By.ID, "student_id").get_attribute("value"))
else:
print("Second sign-up attempt successful!")
else:
print("Sign-up successful!")
finally:
# Close the browser
driver.quit()

View File

@ -1,6 +0,0 @@
Sign-up failed. Checking if form values are retained...
Second sign-up attempt failed. Further investigation needed.
Retained form values after second attempt:
Full Name: John Doe
Email: john.doe@example.com
Modified Student ID: 87654321

View File

@ -1,37 +0,0 @@
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()

View File

@ -1,364 +0,0 @@
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
def test_admin_can_create_lecturer_account(driver, url, admin_username, admin_password, restore_database):
# Administrator (admin@qq.com, password 123) logs in
driver.maximize_window()
login(driver, url, admin_username, admin_password)
# Create a Lecturer account for Mr Lan (mrlan@qq.com, password [123Abc!])
tab = driver.find_element(By.ID, 'tab_ins_accounts')
tab.click()
elem = driver.find_element(By.NAME, 'fullname')
elem.send_keys('Mr Lan')
elem = driver.find_element(By.NAME, 'email')
elem.send_keys('mrlan@qq.com')
elem = driver.find_element(By.NAME, 'password')
elem.send_keys('123Abc!!')
radio_button = driver.find_element(By.NAME, 'type')
radio_button.click()
button = driver.find_element(By.NAME, 'create_btn')
button.click()
# Log out Admin account
logout(driver)
# 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
wait = WebDriverWait(driver, 10)
wait.until(EC.url_contains('SecurityQuestions.php'))
driver.quit()
def test_lecturer_can_create_course(driver, url, restore_database):
# Lecturer lanhui@qq.com logs in
driver.maximize_window()
login(driver, url, 'lanhui@qq.com', '123')
# Create a course called CSC1001 Advanced Software Engineering, 2024
elem = driver.find_element(By.NAME, 'name')
elem.send_keys('Advanced Software Engineering')
elem = driver.find_element(By.NAME, 'code')
elem.send_keys('CSC1001')
elem = driver.find_element(By.NAME, 'academic')
elem.send_keys('2004')
elem = driver.find_element(By.NAME, 'faculty')
elem.send_keys('School of Computer Science and Technology')
elem = driver.find_element(By.CLASS_NAME, 'btn-primary')
elem.click()
elems = driver.find_elements(By.CLASS_NAME, 'btn-default')
last_elem = elems[-1]
assert 'Advanced Software Engineering' in last_elem.text
assert '(CSC1001)' in last_elem.text
# Logout
logout(driver)
driver.quit()
def test_lecturer_can_post_assignment(driver, url, restore_database):
# Lecturer lanhui@qq.com logs in
driver.maximize_window()
login(driver, url, 'lanhui@qq.com', '123')
# Create an assignment called Take-home quiz 1 for course (CSC1111) - Project Management
elem = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.XPATH, '//div[@class="col-md-8"]/a[1]/div'))
)
elem.click()
elem = driver.find_element(By.NAME, 'deadlinedate')
elem.send_keys('002025/05/30')
elem = driver.find_element(By.NAME, 'deadlinetime')
elem.send_keys('23:59')
elem = driver.find_element(By.NAME, 'title')
elem.send_keys('Take-home quiz 1')
elem = driver.find_element(By.NAME, 'instructions')
elem.send_keys('This is a closed-book quiz.')
elem = driver.find_element(By.NAME, 'marks')
elem.send_keys('10')
radio_button = driver.find_element(By.NAME, 'type')
radio_button.click()
elem = driver.find_element(By.CLASS_NAME, 'btn-primary')
elem.click()
# Check if the assignment has been successfully posted
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: 2025-05-30' in elem.text
driver.quit()
def test_lecturer_can_add_student_numbers(driver, url, restore_database):
# Lecturer lanhui@qq.com logs in
driver.maximize_window()
login(driver, url, 'lanhui@qq.com', '123')
# Add ASE student numbers
student_numbers = '''
202420781739
202420781740
202420781741
202420781742
202420781743
202420781745
202420581366
202420581368
202420581369
202420581370
202420581372
202420581373
202420581374
202420581376
202420581378
202420581381
'''
elem = driver.find_element(By.ID, 'admin_tab')
elem.click()
elem = driver.find_element(By.NAME, 'users')
elem.send_keys(student_numbers)
elem = driver.find_element(By.ID, 'register_btn')
elem.click()
elems = driver.find_elements(By.CSS_SELECTOR, 'p')
added = 0
student_lst = [number.strip() for number in student_numbers.strip().split('\n')]
print(student_lst)
for student_no in student_lst:
for elem in elems:
if student_no in elem.text and 'added' in elem.text:
added += 1
break
assert added == len(student_lst)
driver.quit()
def test_student_with_valid_student_number_can_sign_up(driver, url, restore_database):
# Student with recognizable student number 202400000001 can sign up an account
driver.get(url)
driver.maximize_window()
elem = driver.find_element(By.ID, 'signup_link')
elem.click()
elem = driver.find_element(By.NAME, 'fullname')
elem.send_keys('Good Student')
elem = driver.find_element(By.NAME, 'user_student_id')
elem.send_keys('202400000001')
elem = driver.find_element(By.NAME, 'email')
elem.send_keys('goodstudent@qq.com')
elem = driver.find_element(By.NAME, 'password')
elem.send_keys('[123Abc]')
elem = driver.find_element(By.NAME, 'confirmpassword')
elem.send_keys('[123Abc]')
elem = driver.find_element(By.ID, 'signup_btn')
elem.click()
driver.get(url + 'logout.php')
# 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
wait = WebDriverWait(driver, 10)
wait.until(EC.url_contains('SecurityQuestions.php'))
driver.quit()
def test_student_with_invalid_student_number_cannot_sign_up(driver, url, restore_database):
# Student with unrecognizable student number cannot sign up an account
driver.get(url)
driver.maximize_window()
elem = driver.find_element(By.ID, 'signup_link')
elem.click()
elem = driver.find_element(By.NAME, 'fullname')
elem.send_keys('Good Student')
elem = driver.find_element(By.NAME, 'user_student_id')
elem.send_keys('202400000002')
elem = driver.find_element(By.NAME, 'email')
elem.send_keys('goodstudent@qq.com')
elem = driver.find_element(By.NAME, 'password')
elem.send_keys('[123Abc]')
elem = driver.find_element(By.NAME, 'confirmpassword')
elem.send_keys('[123Abc]')
elem = driver.find_element(By.ID, 'signup_btn')
elem.click()
# Log in Student account
login(driver, url, '202400000002', '[123Abc]')
elems = driver.find_elements(By.CLASS_NAME, 'nav-link')
assert not 'Student ID' in elems[0].text
assert not 'Good Student' in elems[0].text
driver.quit()
def test_student_with_weak_password_cannot_sign_up(driver, url, restore_database):
driver.get(url)
driver.maximize_window()
weak_password = '123Abc'
elem = driver.find_element(By.ID, 'signup_link')
elem.click()
elem = driver.find_element(By.NAME, 'fullname')
elem.send_keys('Good Student')
elem = driver.find_element(By.NAME, 'user_student_id')
elem.send_keys('202400000001')
elem = driver.find_element(By.NAME, 'email')
elem.send_keys('goodstudent@qq.com')
elem = driver.find_element(By.NAME, 'password')
elem.send_keys(weak_password)
elem = driver.find_element(By.NAME, 'confirmpassword')
elem.send_keys(weak_password)
elem = driver.find_element(By.ID, 'signup_btn')
elem.click()
# Log in Student account
login(driver, url, '202400000001', weak_password)
elems = driver.find_elements(By.CLASS_NAME, 'nav-link')
assert not 'Student ID' in elems[0].text
assert not 'Good Student' in elems[0].text
driver.quit()
def test_student_can_join_course(driver, url, restore_database):
# Student can join (CSC1111) - Project Management
login(driver, url, '201825800050', '123')
driver.maximize_window()
# Search for CSC1111
elem = driver.find_element(By.NAME, 'search')
elem.send_keys('CSC1111')
elem = driver.find_element(By.CLASS_NAME, 'btn-primary')
elem.click()
elems = driver.find_elements(By.CLASS_NAME, 'btn-default')
assert 'CSC1111' in elems[0].text
# Join
elem = driver.find_element(By.CLASS_NAME, 'btn-success') # find the green Join button
elem.click()
# Log out, then log in to check the course-joining status
logout(driver)
login(driver, url, '201825800050', '123')
elems = driver.find_elements(By.CLASS_NAME, 'btn-default')
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):
''' Note: Make sure the fields Posted_Date and Deadline in the second row of lab_reports_table are in the current year'''
# Student can submit assignment for CSC1111
login(driver, url, '201825800050', '123')
driver.maximize_window()
# Enter into the course and the find the assignment
elems = driver.find_elements(By.CLASS_NAME, 'btn-default')
elems[1].click()
elem = driver.find_element(By.XPATH, '//div[@id="menu1"]/div/div/p/a[text()="Submit"]') # find the submit button
elem.click()
# Fill submission title, attach file, and submit
elem = driver.find_element(By.NAME, 'title')
elem.send_keys('Assignment submission from Mohamed')
elem = driver.find_element(By.NAME, 'attachment1')
elem.send_keys('/var/www/html/LRR/test/SeleniumHui/helper.py') # attach a file
elem = driver.find_element(By.XPATH, '//form/button')
elem.click()
# Go the Submitted tab
elem = driver.find_element(By.ID, 'myTab')
elems = elem.find_elements(By.CLASS_NAME, 'nav-link')
elems[2].click()
elem = driver.find_element(By.XPATH, '//div[@id="menu3"]/div')
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):
# Student logs in
login(driver, url, '201825800050', '123')
driver.maximize_window()
# Enter into the course
elems = driver.find_elements(By.CLASS_NAME, 'btn-default')
elems[1].click()
# Go the Marked tab
elem = driver.find_element(By.ID, 'myTab')
elems = elem.find_elements(By.CLASS_NAME, 'nav-link')
elems[3].click()
# Send remarking request
remarking_buttons = driver.find_elements(By.CLASS_NAME, 'btn-light')
remarking_buttons[0].click()
alert = driver.switch_to.alert
alert.send_keys('I need higher marks, teacher.')
alert.accept()
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):
# Lecturer lanhui@qq.com logs in
driver.maximize_window()
login(driver, url, 'lanhui@qq.com', '123')
# Enter into the course and the find the assignment
elem = driver.find_element(By.XPATH, '//div[1]/a[3]/div') # course Software Engineering
elem.click()
elem = driver.find_element(By.XPATH, '//div[2]/div[2]/div/a[2]') # View link
elem.click()
elem = driver.find_element(By.CLASS_NAME, 'btn-primary') # Blue Mark button
elem.click()
# Submit mark and comment
elem = driver.find_element(By.NAME, 'marks')
elem.send_keys('1')
elem = driver.find_element(By.NAME, 'feedback')
elem.send_keys('Inadequate')
form = driver.find_element(By.ID, 'submit-form')
form.submit()
elem = driver.find_element(By.ID, 'myTab')
elems = elem.find_elements(By.CLASS_NAME, 'nav-link')
assert 'Marked submissions (1)' == elems[1].text
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):
# Lecturer lanhui@qq.com logs in
driver.maximize_window()
login(driver, url, 'peter@qq.com', '123')
elem = driver.find_element(By.ID, 'admin_tab')
elem.click()
tab = driver.find_element(By.ID, 'existing_accounts_tab')
tab.click()
elem = driver.find_element(By.ID, 'tab-existing-accounts')
assert 'No TA' in elem.text
# Logout
logout(driver)
driver.quit()

View File

@ -1,77 +0,0 @@
import pytest
from selenium import webdriver
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, TimeoutException
import time
import traceback
driver = webdriver.Chrome()
try:
# Navigate to the page with tabs
driver.get("http://localhost:8080/lrr/")
driver.maximize_window()
wait = WebDriverWait(driver, 10)
# Login as a Lecturer
username_input = wait.until(EC.presence_of_element_located((By.NAME, "user")))
password_input = driver.find_element(By.NAME, "password")
login_button = driver.find_element(By.ID, "login_btn")
username_input.send_keys("ashly@qq.com")
password_input.send_keys("admin123")
time.sleep(5)
login_button.click()
course_but= driver.find_element(By.XPATH, "(//div[@class='btn btn-default'])[1]") # Adjust this XPATH as needed
# Click on the alert
course_but.click()
time.sleep(5)
marked_tab = wait.until(
EC.element_to_be_clickable((By.XPATH, "//a[text()='Marked']"))
)
marked_tab.click()
# Wait for the Marked tab content to be present
marked_tab_content = wait.until(
EC.presence_of_element_located((By.XPATH, "//div[@id='menu4' and contains(@class, 'active')]"))
)
time.sleep(5)
remark_but = wait.until(
EC.presence_of_element_located((By.XPATH, "//button[normalize-space()='Request remarking']"))
)
remark_but.click()
time.sleep(2)
# Switch to the alert
alert = driver.switch_to.alert
# Send keys to the prompt
alert.send_keys("Number 2 was correct")
# Accept the prompt (click OK)
alert.accept()
time.sleep(5)
except NoSuchElementException as e:
print("NoSuchElementException: Could not find an element.")
traceback.print_exc()
except TimeoutException as e:
print("TimeoutException: An element took too long to load.")
traceback.print_exc()
except Exception as e:
print(f"An unexpected error occurred: {e}")
traceback.print_exc()
finally:
driver.quit()