From 63547b875924eaaa596a76c167c910a942259de4 Mon Sep 17 00:00:00 2001 From: Rita Lei Date: Wed, 29 Nov 2023 09:35:05 -0500 Subject: [PATCH 01/58] Step 1 ~ Creating Boolean --- .setup/CONFIGURE_SUBMITTY.py | 13 ++++++++++++- site/app/models/Config.php | 6 ++++++ site/app/templates/Authentication.twig | 1 + site/app/templates/CreateNewAccount.twig | 23 +++++++++++++++++++++++ site/tests/app/models/ConfigTester.php | 2 ++ 5 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 site/app/templates/CreateNewAccount.twig diff --git a/.setup/CONFIGURE_SUBMITTY.py b/.setup/CONFIGURE_SUBMITTY.py index 4888b7597c9..2b54824fe3c 100644 --- a/.setup/CONFIGURE_SUBMITTY.py +++ b/.setup/CONFIGURE_SUBMITTY.py @@ -180,6 +180,7 @@ def __call__(self, parser, namespace, values, option_string=None): 'authentication_method': 0, 'institution_name' : '', 'institution_homepage' : '', + 'create_new_account' : False, 'timezone' : tzlocal.get_localzone().zone, 'submitty_admin_username': '', 'email_user': '', @@ -304,7 +305,15 @@ def __call__(self, parser, namespace, values, option_string=None): INSTITUTION_HOMEPAGE = '' print() - + while True: + CREATE_NEW_ACCOUNT = get_input("Enable Create New Account feature? [y/n]", 'y') + if (CREATE_NEW_ACCOUNT.lower() in ['yes', 'y']): + create_new_account = True + elif (CREATE_NEW_ACCOUNT.lower() in ['no', 'n']): + create_new_account = False + break + print() + SYS_ADMIN_EMAIL = get_input("What is the email for system administration?", defaults['sys_admin_email']) SYS_ADMIN_URL = get_input("Where to report problems with Submitty (url for help link)?", defaults['sys_admin_url']) @@ -439,6 +448,7 @@ def __call__(self, parser, namespace, values, option_string=None): config['institution_name'] = INSTITUTION_NAME config['institution_homepage'] = INSTITUTION_HOMEPAGE + config['create_new_account'] = CREATE_NEW_ACCOUNT config['debugging_enabled'] = DEBUGGING_ENABLED # site_log_path is a holdover name. This could more accurately be called the "log_path" @@ -624,6 +634,7 @@ def write(x=''): config['timezone'] = TIMEZONE config['default_locale'] = DEFAULT_LOCALE config['duck_special_effects'] = False + config['create_new_account'] = CREATE_NEW_ACCOUNT config['worker'] = True if args.worker == 1 else False diff --git a/site/app/models/Config.php b/site/app/models/Config.php index 43bee9bf307..6df43f7cff0 100644 --- a/site/app/models/Config.php +++ b/site/app/models/Config.php @@ -217,6 +217,10 @@ class Config extends AbstractModel { * @var string Text shown to all users for system announcement */ protected $system_message = ''; + /** @prop + * @var bool Create New Account shown to at login page */ + protected $create_new_account; + /** @prop * @var array */ protected $submitty_database_params = []; @@ -421,6 +425,8 @@ public function loadMasterConfigs($config_path) { $this->sys_admin_email = $submitty_json['sys_admin_email'] ?? ''; $this->sys_admin_url = $submitty_json['sys_admin_url'] ?? ''; + $this->create_new_account = $submitty_json['create_new_account'] ?? === false; + if (isset($submitty_json['timezone'])) { if (!in_array($submitty_json['timezone'], \DateTimeZone::listIdentifiers())) { throw new ConfigException("Invalid Timezone identifier: {$submitty_json['timezone']}"); diff --git a/site/app/templates/Authentication.twig b/site/app/templates/Authentication.twig index bf8c2cd6b90..b3ab5762e6f 100644 --- a/site/app/templates/Authentication.twig +++ b/site/app/templates/Authentication.twig @@ -24,6 +24,7 @@ + {{ new_account_name }} {% endif %} diff --git a/site/app/templates/CreateNewAccount.twig b/site/app/templates/CreateNewAccount.twig new file mode 100644 index 00000000000..4ce02249112 --- /dev/null +++ b/site/app/templates/CreateNewAccount.twig @@ -0,0 +1,23 @@ +
+
+ {% include "misc/Markdown.twig" with { + "content": login_content + } only %} +
+ +
+ + + + +
+
diff --git a/site/tests/app/models/ConfigTester.php b/site/tests/app/models/ConfigTester.php index 69d5103612b..35d17b90273 100644 --- a/site/tests/app/models/ConfigTester.php +++ b/site/tests/app/models/ConfigTester.php @@ -94,6 +94,7 @@ private function createConfigFile($extra = []) { "course_code_requirements" => "Please follow your school's convention for course code.", "institution_homepage" => "https://rpi.edu", 'system_message' => "Some system message", + 'create_new_account' => false, "duck_special_effects" => false, "default_locale" => "default", ]; @@ -330,6 +331,7 @@ public function testConfig() { 'vcs_url' => 'http://example.com/{$vcs_type}/', 'wrapper_files' => [], 'system_message' => 'Some system message', + 'create_new_account' => false, 'secret_session' => 'LIW0RT5XAxOn2xjVY6rrLTcb6iacl4IDNRyPw58M0Kn0haQbHtNvPfK18xpvpD93', 'email_enabled' => true, 'auto_rainbow_grades' => false, From 00c5f56ce857479b218ea3d5c2927583a284d632 Mon Sep 17 00:00:00 2001 From: Rita Lei Date: Wed, 29 Nov 2023 16:01:32 -0500 Subject: [PATCH 02/58] Fix Syntax --- site/app/models/Config.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/app/models/Config.php b/site/app/models/Config.php index 6df43f7cff0..c624eae13d4 100644 --- a/site/app/models/Config.php +++ b/site/app/models/Config.php @@ -425,7 +425,7 @@ public function loadMasterConfigs($config_path) { $this->sys_admin_email = $submitty_json['sys_admin_email'] ?? ''; $this->sys_admin_url = $submitty_json['sys_admin_url'] ?? ''; - $this->create_new_account = $submitty_json['create_new_account'] ?? === false; + $this->create_new_account = $submitty_json['create_new_account'] === false; if (isset($submitty_json['timezone'])) { if (!in_array($submitty_json['timezone'], \DateTimeZone::listIdentifiers())) { From 188da0813e43231cf7fad2353b89fd43186ea8f0 Mon Sep 17 00:00:00 2001 From: Rita Lei Date: Fri, 1 Dec 2023 15:24:16 -0500 Subject: [PATCH 03/58] Changes --- .../controllers/AuthenticationController.php | 54 +++++++++++++++++++ site/app/templates/CreateNewAccount.twig | 4 ++ site/app/views/AuthenticationView.php | 24 +++++++++ 3 files changed, 82 insertions(+) diff --git a/site/app/controllers/AuthenticationController.php b/site/app/controllers/AuthenticationController.php index 882608e5fd1..81702577000 100644 --- a/site/app/controllers/AuthenticationController.php +++ b/site/app/controllers/AuthenticationController.php @@ -311,4 +311,58 @@ public function userSelection() { return new WebResponse(AuthenticationView::class, 'userSelection', $users); } + + /** + * Display the form for creating a new account + * + * @Route("/authentication/create_account") + * + * @return ResponseInterface + */ + public function createAccountForm() { + // Check if the user is already logged in, if yes, redirect to home or another appropriate page + if ($this->logged_in) { + return new RedirectResponse($this->core->buildUrl(['home'])); + } + // Check if the creating a new account is allowed, if yes, redirect to create account page + if ($this->create_new_account) { + return new WebResponse('Authentication', 'createAccountForm'); + } + } + + /** + * Handles the submission of the new account creation form + * + * @Route("/authentication/checkNewUser") + * + * @return MultiResponse + */ + public function checkNewUser() { + // Check if the user is already logged in, if yes, redirect to home or another appropriate page + if ($this->logged_in) { + return MultiResponse::RedirectOnlyResponse( + new RedirectResponse($this->core->buildUrl(['home'])) + ); + } + // Handle the form submission here + $username = $_POST['new_username']; + $password = $_POST['new_password']; + + // Call the UserModel or authentication service to create the new account + $success = $this->core->getAuthentication()->createUser($username, $password); + + if ($success) { + // Redirect to a login page and show a success message + $this->core->addSuccessMessage('Account created successfully!'); + return MultiResponse::RedirectOnlyResponse( + new RedirectResponse($this->core->buildUrl(['authentication', 'login'])) + ); + } else { + // Handle account creation failure + $this->core->addErrorMessage('Failed to create the account.'); + return MultiResponse::RedirectOnlyResponse( + new RedirectResponse($this->core->buildUrl(['authentication', 'create_account'])) + ); + } + } } diff --git a/site/app/templates/CreateNewAccount.twig b/site/app/templates/CreateNewAccount.twig index 4ce02249112..e97f5272129 100644 --- a/site/app/templates/CreateNewAccount.twig +++ b/site/app/templates/CreateNewAccount.twig @@ -18,6 +18,10 @@ Password + diff --git a/site/app/views/AuthenticationView.php b/site/app/views/AuthenticationView.php index 881cdd16eb2..2380d473549 100644 --- a/site/app/views/AuthenticationView.php +++ b/site/app/views/AuthenticationView.php @@ -38,4 +38,28 @@ public function userSelection(array $users) { "login_url" => $this->core->buildUrl(['authentication', 'check_login']) ]); } + + public function signupForm($old = null, $isSaml = false) { + if (!isset($old)) { + $old = urlencode($this->core->buildUrl(['home'])); + } + $this->core->getOutput()->addInternalCss("input.css"); + $this->core->getOutput()->addInternalCss("links.css"); + $this->core->getOutput()->addInternalCss("authentication.css"); + $this->core->getOutput()->enableMobileViewport(); + + $login_content = "# Sign Up"; + $path = FileUtils::joinPaths($this->core->getConfig()->getConfigPath(), "signup.md"); + if (file_exists($path) && is_readable($path)) { + $login_content = file_get_contents($path); + } + + return $this->core->getOutput()->renderTwigTemplate("Authentication.twig", [ + "signup_url" => $this->core->buildUrl(['authentication', 'checkNewUser']) . '?' . http_build_query(['old' => $old]), + "is_new_account" => $isNewAccount, + "new_account_url" => $this->core->buildUrl(['authentication', 'new_account_start']) . '?' . http_build_query(['old' => $old]), + "new_account_name" => $this->core->getConfig()->getSamlOptions()['name'], + "new_account_content" => $login_content + ]); + } } From fa329e02da1afed972ba75d4160de1790184c1b4 Mon Sep 17 00:00:00 2001 From: Rita Lei Date: Mon, 4 Dec 2023 04:07:35 -0500 Subject: [PATCH 04/58] Fix class --- site/app/templates/Authentication.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/app/templates/Authentication.twig b/site/app/templates/Authentication.twig index b3ab5762e6f..350d2d070dc 100644 --- a/site/app/templates/Authentication.twig +++ b/site/app/templates/Authentication.twig @@ -24,7 +24,7 @@ - {{ new_account_name }} + {{ new_account_name }} {% endif %} From 9fe327f0d54f57e0264b28623119d40bf65e4c8c Mon Sep 17 00:00:00 2001 From: Michael Papadopoulos Date: Mon, 3 Jun 2024 12:52:26 -0400 Subject: [PATCH 05/58] missing break --- .setup/CONFIGURE_SUBMITTY.py | 1 + 1 file changed, 1 insertion(+) diff --git a/.setup/CONFIGURE_SUBMITTY.py b/.setup/CONFIGURE_SUBMITTY.py index 1a5a1eba8dc..962111b708d 100644 --- a/.setup/CONFIGURE_SUBMITTY.py +++ b/.setup/CONFIGURE_SUBMITTY.py @@ -314,6 +314,7 @@ def __call__(self, parser, namespace, values, option_string=None): CREATE_NEW_ACCOUNT = get_input("Enable Create New Account feature? [y/n]", 'y') if (CREATE_NEW_ACCOUNT.lower() in ['yes', 'y']): create_new_account = True + break elif (CREATE_NEW_ACCOUNT.lower() in ['no', 'n']): create_new_account = False break From 44827114da52981c2b2a690e715b7b6ccbb4e3ba Mon Sep 17 00:00:00 2001 From: Michael Papadopoulos Date: Mon, 17 Jun 2024 12:53:58 -0400 Subject: [PATCH 06/58] Clean up links, and make progress on page Todos are included, needs someone with experience on auth --- .../roles/submitty_install/defaults/main.yml | 1 + .../roles/submitty_install/tasks/main.yml | 1 + autograder/tests/data/submitty_config.json | 1 + .../controllers/AuthenticationController.php | 26 +++++++++++------ site/app/models/Config.php | 4 +-- site/app/templates/Authentication.twig | 2 +- site/app/templates/CreateNewAccount.twig | 10 +++---- site/app/views/AuthenticationView.php | 28 ++++++++++--------- 8 files changed, 44 insertions(+), 29 deletions(-) diff --git a/.setup/ansible/roles/submitty_install/defaults/main.yml b/.setup/ansible/roles/submitty_install/defaults/main.yml index 2ef16557ca2..fadf70c9fa2 100644 --- a/.setup/ansible/roles/submitty_install/defaults/main.yml +++ b/.setup/ansible/roles/submitty_install/defaults/main.yml @@ -11,6 +11,7 @@ language: en_US submitty_url: localhost vcs_url: git.localhost institution_name: Example University +create_new_account: n sysadmin_email: sysadmin@localhost submitty_email: submitty@localhost institution_url: localhost diff --git a/.setup/ansible/roles/submitty_install/tasks/main.yml b/.setup/ansible/roles/submitty_install/tasks/main.yml index d1942853932..58f490de60c 100644 --- a/.setup/ansible/roles/submitty_install/tasks/main.yml +++ b/.setup/ansible/roles/submitty_install/tasks/main.yml @@ -44,6 +44,7 @@ {{ 'https' if ssl_enabled else 'http' }}://{{ submitty_url }} {{ vcs_url }} {{ institution_name }} + {{ create_new_account }} {{ sysadmin_email }} {{ submitty_email }} {{ institution_url }} diff --git a/autograder/tests/data/submitty_config.json b/autograder/tests/data/submitty_config.json index a13c8a0111c..dfdc9b55d9e 100644 --- a/autograder/tests/data/submitty_config.json +++ b/autograder/tests/data/submitty_config.json @@ -12,6 +12,7 @@ "cgi_url": "https://submitty.test.com/cgi-bin", "websocket_port": 8443, "institution_name": "Test University", + "create_new_account": false, "institution_homepage": "https://test.com", "timezone": "America/Los_Angeles", "duck_special_effects": false, diff --git a/site/app/controllers/AuthenticationController.php b/site/app/controllers/AuthenticationController.php index 81702577000..123b41d8f17 100644 --- a/site/app/controllers/AuthenticationController.php +++ b/site/app/controllers/AuthenticationController.php @@ -81,7 +81,7 @@ public function loginForm($old = null) { $old = null; } $is_saml_auth = $this->core->getAuthentication() instanceof SamlAuthentication; - return new WebResponse('Authentication', 'loginForm', $old, $is_saml_auth); + return new WebResponse(AuthenticationView::class, 'loginForm', $old, $is_saml_auth); } /** @@ -319,26 +319,24 @@ public function userSelection() { * * @return ResponseInterface */ - public function createAccountForm() { + public function signupForm() { // Check if the user is already logged in, if yes, redirect to home or another appropriate page if ($this->logged_in) { return new RedirectResponse($this->core->buildUrl(['home'])); } - // Check if the creating a new account is allowed, if yes, redirect to create account page - if ($this->create_new_account) { - return new WebResponse('Authentication', 'createAccountForm'); - } + return new WebResponse(AuthenticationView::class, 'signupForm'); } /** * Handles the submission of the new account creation form * - * @Route("/authentication/checkNewUser") + * @Route("/authentication/check_new_user") * * @return MultiResponse */ public function checkNewUser() { // Check if the user is already logged in, if yes, redirect to home or another appropriate page + if ($this->logged_in) { return MultiResponse::RedirectOnlyResponse( new RedirectResponse($this->core->buildUrl(['home'])) @@ -347,8 +345,19 @@ public function checkNewUser() { // Handle the form submission here $username = $_POST['new_username']; $password = $_POST['new_password']; + $confirm_password = $_POST['confirm_password']; + + // TODO: Add email confirmation + + if (!($password === $confirm_password)) { + $this->core->addErrorMessage('Passwords did not match.'); + return MultiResponse::RedirectOnlyResponse( + new RedirectResponse($this->core->buildUrl(['authentication', 'create_account'])) + ); + } // Call the UserModel or authentication service to create the new account + // TODO: Make this function! $success = $this->core->getAuthentication()->createUser($username, $password); if ($success) { @@ -357,7 +366,8 @@ public function checkNewUser() { return MultiResponse::RedirectOnlyResponse( new RedirectResponse($this->core->buildUrl(['authentication', 'login'])) ); - } else { + } + else { // Handle account creation failure $this->core->addErrorMessage('Failed to create the account.'); return MultiResponse::RedirectOnlyResponse( diff --git a/site/app/models/Config.php b/site/app/models/Config.php index c624eae13d4..798c46955cd 100644 --- a/site/app/models/Config.php +++ b/site/app/models/Config.php @@ -217,7 +217,7 @@ class Config extends AbstractModel { * @var string Text shown to all users for system announcement */ protected $system_message = ''; - /** @prop + /** @prop * @var bool Create New Account shown to at login page */ protected $create_new_account; @@ -426,7 +426,7 @@ public function loadMasterConfigs($config_path) { $this->sys_admin_url = $submitty_json['sys_admin_url'] ?? ''; $this->create_new_account = $submitty_json['create_new_account'] === false; - + if (isset($submitty_json['timezone'])) { if (!in_array($submitty_json['timezone'], \DateTimeZone::listIdentifiers())) { throw new ConfigException("Invalid Timezone identifier: {$submitty_json['timezone']}"); diff --git a/site/app/templates/Authentication.twig b/site/app/templates/Authentication.twig index 350d2d070dc..ed08c0ad93a 100644 --- a/site/app/templates/Authentication.twig +++ b/site/app/templates/Authentication.twig @@ -24,7 +24,7 @@ - {{ new_account_name }} + {{ new_account_text }} {% endif %} diff --git a/site/app/templates/CreateNewAccount.twig b/site/app/templates/CreateNewAccount.twig index e97f5272129..e0b67151f3d 100644 --- a/site/app/templates/CreateNewAccount.twig +++ b/site/app/templates/CreateNewAccount.twig @@ -1,26 +1,26 @@
{% include "misc/Markdown.twig" with { - "content": login_content + "content": signup_content } only %}
-
+
diff --git a/site/app/views/AuthenticationView.php b/site/app/views/AuthenticationView.php index 2380d473549..9d00db94734 100644 --- a/site/app/views/AuthenticationView.php +++ b/site/app/views/AuthenticationView.php @@ -21,12 +21,20 @@ public function loginForm($old = null, $isSaml = false) { $login_content = file_get_contents($path); } + $new_account_text = "New to Submitty? Sign up here."; + $path = FileUtils::joinPaths($this->core->getConfig()->getConfigPath(), "new_account.md"); + if (file_exists($path) && is_readable($path)) { + $new_account_text = file_get_contents($path); + } + return $this->core->getOutput()->renderTwigTemplate("Authentication.twig", [ "login_url" => $this->core->buildUrl(['authentication', 'check_login']) . '?' . http_build_query(['old' => $old]), "is_saml" => $isSaml, "saml_url" => $this->core->buildUrl(['authentication', 'saml_start']) . '?' . http_build_query(['old' => $old]), "saml_name" => $this->core->getConfig()->getSamlOptions()['name'], - "login_content" => $login_content + "login_content" => $login_content, + "new_account_url" => $this->core->buildUrl(['authentication', 'create_account']), + "new_account_text" => $new_account_text ]); } @@ -39,27 +47,21 @@ public function userSelection(array $users) { ]); } - public function signupForm($old = null, $isSaml = false) { - if (!isset($old)) { - $old = urlencode($this->core->buildUrl(['home'])); - } + public function signupForm() { $this->core->getOutput()->addInternalCss("input.css"); $this->core->getOutput()->addInternalCss("links.css"); $this->core->getOutput()->addInternalCss("authentication.css"); $this->core->getOutput()->enableMobileViewport(); - $login_content = "# Sign Up"; + $signup_content = "# Sign Up"; $path = FileUtils::joinPaths($this->core->getConfig()->getConfigPath(), "signup.md"); if (file_exists($path) && is_readable($path)) { - $login_content = file_get_contents($path); + $signup_content = file_get_contents($path); } - return $this->core->getOutput()->renderTwigTemplate("Authentication.twig", [ - "signup_url" => $this->core->buildUrl(['authentication', 'checkNewUser']) . '?' . http_build_query(['old' => $old]), - "is_new_account" => $isNewAccount, - "new_account_url" => $this->core->buildUrl(['authentication', 'new_account_start']) . '?' . http_build_query(['old' => $old]), - "new_account_name" => $this->core->getConfig()->getSamlOptions()['name'], - "new_account_content" => $login_content + return $this->core->getOutput()->renderTwigTemplate("CreateNewAccount.twig", [ + "signup_url" => $this->core->buildUrl(['authentication', 'check_new_user']), + "signup_content" => $signup_content ]); } } From 34f015d243b8c9c79725e0c77dc209e2389cf075 Mon Sep 17 00:00:00 2001 From: IDzyre Date: Mon, 15 Jul 2024 09:45:01 -0800 Subject: [PATCH 07/58] Adds user to database, can't login yet --- .setup/CONFIGURE_SUBMITTY.py | 16 ++-- autograder/tests/data/submitty_config.json | 2 +- .../controllers/AuthenticationController.php | 75 ++++++++++++------- .../libraries/database/DatabaseQueries.php | 10 +++ site/app/models/Config.php | 7 +- site/app/templates/Authentication.twig | 4 +- site/app/templates/CreateNewAccount.twig | 14 +++- site/app/views/AuthenticationView.php | 6 +- site/tests/app/models/ConfigTester.php | 4 +- 9 files changed, 89 insertions(+), 49 deletions(-) diff --git a/.setup/CONFIGURE_SUBMITTY.py b/.setup/CONFIGURE_SUBMITTY.py index 39f98f97b94..015d2c93343 100644 --- a/.setup/CONFIGURE_SUBMITTY.py +++ b/.setup/CONFIGURE_SUBMITTY.py @@ -185,7 +185,7 @@ def __call__(self, parser, namespace, values, option_string=None): 'authentication_method': 0, 'institution_name' : '', 'institution_homepage' : '', - 'create_new_account' : False, + 'user_create_account' : False, 'timezone' : tzlocal.get_localzone().zone, 'submitty_admin_username': '', 'email_user': '', @@ -311,12 +311,12 @@ def __call__(self, parser, namespace, values, option_string=None): print() while True: - CREATE_NEW_ACCOUNT = get_input("Enable Create New Account feature? [y/n]", 'y') - if (CREATE_NEW_ACCOUNT.lower() in ['yes', 'y']): - create_new_account = True + user_create_account = get_input("Enable Create New Account feature? [y/n]", 'y') + if (user_create_account.lower() in ['yes', 'y']): + USER_CREATE_ACCOUNT = True break - elif (CREATE_NEW_ACCOUNT.lower() in ['no', 'n']): - create_new_account = False + elif (USER_CREATE_ACCOUNT.lower() in ['no', 'n']): + USER_CREATE_ACCOUNT = False break print() @@ -455,7 +455,7 @@ def __call__(self, parser, namespace, values, option_string=None): config['institution_name'] = INSTITUTION_NAME config['institution_homepage'] = INSTITUTION_HOMEPAGE - config['create_new_account'] = CREATE_NEW_ACCOUNT + config['user_create_account'] = USER_CREATE_ACCOUNT config['debugging_enabled'] = DEBUGGING_ENABLED # site_log_path is a holdover name. This could more accurately be called the "log_path" @@ -649,7 +649,7 @@ def write(x=''): config['timezone'] = TIMEZONE config['default_locale'] = DEFAULT_LOCALE config['duck_special_effects'] = False - config['create_new_account'] = CREATE_NEW_ACCOUNT + config['user_create_account'] = USER_CREATE_ACCOUNT config['worker'] = True if args.worker == 1 else False diff --git a/autograder/tests/data/submitty_config.json b/autograder/tests/data/submitty_config.json index dfdc9b55d9e..bb22b2732ae 100644 --- a/autograder/tests/data/submitty_config.json +++ b/autograder/tests/data/submitty_config.json @@ -12,7 +12,7 @@ "cgi_url": "https://submitty.test.com/cgi-bin", "websocket_port": 8443, "institution_name": "Test University", - "create_new_account": false, + "user_create_account": false, "institution_homepage": "https://test.com", "timezone": "America/Los_Angeles", "duck_special_effects": false, diff --git a/site/app/controllers/AuthenticationController.php b/site/app/controllers/AuthenticationController.php index 77104077c25..ed0ec456586 100644 --- a/site/app/controllers/AuthenticationController.php +++ b/site/app/controllers/AuthenticationController.php @@ -13,6 +13,7 @@ use app\libraries\Logger; use app\libraries\response\MultiResponse; use app\views\AuthenticationView; +use app\models\User; use app\repositories\VcsAuthTokenRepository; use Symfony\Component\Routing\Annotation\Route; @@ -321,55 +322,71 @@ public function signupForm() { if ($this->logged_in) { return new RedirectResponse($this->core->buildUrl(['home'])); } - return new WebResponse(AuthenticationView::class, 'signupForm'); + return new WebResponse('Authentication', 'signupForm'); } /** * Handles the submission of the new account creation form * - * @Route("/authentication/check_new_user") + * @Route("/authentication/self_add_user") * * @return MultiResponse */ - public function checkNewUser() { + public function addNewUser() { // Check if the user is already logged in, if yes, redirect to home or another appropriate page - if ($this->logged_in) { - return MultiResponse::RedirectOnlyResponse( - new RedirectResponse($this->core->buildUrl(['home'])) - ); + return new RedirectResponse($this->core->buildUrl(['home'])); + } + + // Should never happen, as the user + if (!$this->core->getConfig()->isUserCreateAccount()) { + $this->core->addErrorMessage('Users cannot create their own account, Please have your system administrator add you.'); + return new RedirectResponse($this->core->buildUrl(['authentication', 'login'])); } - // Handle the form submission here - $username = $_POST['new_username']; - $password = $_POST['new_password']; + + $user_id = $_POST['user_id']; + $email = $_POST['email']; + $password = $_POST['password']; $confirm_password = $_POST['confirm_password']; - // TODO: Add email confirmation + $queried_list = $this->core->getQueries()->getFullEmailList(); - if (!($password === $confirm_password)) { - $this->core->addErrorMessage('Passwords did not match.'); - return MultiResponse::RedirectOnlyResponse( - new RedirectResponse($this->core->buildUrl(['authentication', 'create_account'])) - ); + if (array_search($email, array_column($queried_list, 'user_email')) !== FALSE) { + $this->core->addErrorMessage('Email already exists'); + return true; } - // Call the UserModel or authentication service to create the new account - // TODO: Make this function! - $success = $this->core->getAuthentication()->createUser($username, $password); + if (array_search($user_id, array_column($queried_list, 'user_id')) !== FALSE) { + $this->core->addErrorMessage('User ID already exists'); + return true; + } - if ($success) { - // Redirect to a login page and show a success message + if (!($password === $confirm_password)) { + $this->core->addErrorMessage('Passwords did not match.'); + return new RedirectResponse($this->core->buildUrl(['authentication', 'create_account'])); + } + + $user = new User($this->core, [ + 'user_id' => $user_id, + 'user_givenname' => $_POST['given_name'], + 'user_familyname' => $_POST['family_name'], + 'user_password' => $password, + 'user_pronouns' => '', + 'display_pronouns' => false, + 'user_email' => $_POST['email'], + 'user_email_secondary' => '', + 'user_email_secondary_notify' => false + ]); + + try { + $this->core->getQueries()->insertSubmittyUser($user); $this->core->addSuccessMessage('Account created successfully!'); - return MultiResponse::RedirectOnlyResponse( - new RedirectResponse($this->core->buildUrl(['authentication', 'login'])) - ); + return new RedirectResponse($this->core->buildUrl(['authentication', 'login'])); } - else { - // Handle account creation failure + catch(Error $e) { $this->core->addErrorMessage('Failed to create the account.'); - return MultiResponse::RedirectOnlyResponse( - new RedirectResponse($this->core->buildUrl(['authentication', 'create_account'])) - ); + return new RedirectResponse($this->core->buildUrl(['authentication', 'create_account'])); } } + } diff --git a/site/app/libraries/database/DatabaseQueries.php b/site/app/libraries/database/DatabaseQueries.php index e96ca75754a..cd8bfa81056 100644 --- a/site/app/libraries/database/DatabaseQueries.php +++ b/site/app/libraries/database/DatabaseQueries.php @@ -7700,6 +7700,16 @@ public function getEmailListWithIds() { return $this->course_db->rows(); } + /** + * Gets a list of emails with user ids for all active particpants in Submitty + */ + public function getFullEmailList() { + $parameters = []; + $this->submitty_db->query('SELECT user_id, user_email FROM users', $parameters); + + return $this->submitty_db->rows(); + } + /** * Gives true if thread is locked */ diff --git a/site/app/models/Config.php b/site/app/models/Config.php index 798c46955cd..64ff76cff6d 100644 --- a/site/app/models/Config.php +++ b/site/app/models/Config.php @@ -55,6 +55,7 @@ * @method string getSysAdminEmail() * @method string getSysAdminUrl() * @method string getCourseEmail() + * @method bool isUserCreateAccount() * @method string getVcsUser() * @method string getVcsType() * @method string getPrivateRepository() @@ -219,7 +220,7 @@ class Config extends AbstractModel { /** @prop * @var bool Create New Account shown to at login page */ - protected $create_new_account; + protected $user_create_account; /** @prop * @var array */ @@ -425,8 +426,8 @@ public function loadMasterConfigs($config_path) { $this->sys_admin_email = $submitty_json['sys_admin_email'] ?? ''; $this->sys_admin_url = $submitty_json['sys_admin_url'] ?? ''; - $this->create_new_account = $submitty_json['create_new_account'] === false; - + // $this->user_create_account = $submitty_json['user_create_account'] === false; + $this->user_create_account = true; if (isset($submitty_json['timezone'])) { if (!in_array($submitty_json['timezone'], \DateTimeZone::listIdentifiers())) { throw new ConfigException("Invalid Timezone identifier: {$submitty_json['timezone']}"); diff --git a/site/app/templates/Authentication.twig b/site/app/templates/Authentication.twig index ed08c0ad93a..6d76d68fcaa 100644 --- a/site/app/templates/Authentication.twig +++ b/site/app/templates/Authentication.twig @@ -24,7 +24,9 @@ - {{ new_account_text }} + {% if user_create_account %} + {{ new_account_text }} + {% endif %} {% endif %}
diff --git a/site/app/templates/CreateNewAccount.twig b/site/app/templates/CreateNewAccount.twig index e0b67151f3d..6b89db68589 100644 --- a/site/app/templates/CreateNewAccount.twig +++ b/site/app/templates/CreateNewAccount.twig @@ -8,15 +8,23 @@
+ + - {% if user_create_account %} + {% if user_create_account and is_database_auth %} {{ new_account_text }} {% endif %}
diff --git a/site/app/views/AuthenticationView.php b/site/app/views/AuthenticationView.php index 8f31255cf4b..36756a7cb4d 100644 --- a/site/app/views/AuthenticationView.php +++ b/site/app/views/AuthenticationView.php @@ -35,8 +35,9 @@ public function loginForm($old = null, $isSaml = false) { "saml_name" => $this->core->getConfig()->getSamlOptions()['name'], "login_content" => $login_content, "user_create_account" => $this->core->getConfig()->isUserCreateAccount(), + "is_database_auth" => $this->core->getAuthentication() instanceof DatabaseAuthentication, "new_account_url" => $this->core->buildUrl(['authentication', 'create_account']), - "new_account_text" =>$this->core->getAuthentication() instanceof DatabaseAuthentication + "new_account_text" => "New to Submitty? Sign up now!" ]); } From 71badd7de10bad422fecfd82358b0fc8a560040c Mon Sep 17 00:00:00 2001 From: IDzyre Date: Tue, 16 Jul 2024 10:33:58 -0800 Subject: [PATCH 11/58] Maybe fix php unit tests? --- site/app/controllers/AuthenticationController.php | 2 +- site/tests/app/models/ConfigTester.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/site/app/controllers/AuthenticationController.php b/site/app/controllers/AuthenticationController.php index 96638d09007..0a21cd24eb2 100644 --- a/site/app/controllers/AuthenticationController.php +++ b/site/app/controllers/AuthenticationController.php @@ -81,7 +81,7 @@ public function loginForm($old = null) { $old = null; } $is_saml_auth = $this->core->getAuthentication() instanceof SamlAuthentication; - return new WebResponse(AuthenticationView::class, 'loginForm', $old, $is_saml_auth); + return new WebResponse('Authentication', 'loginForm', $old, $is_saml_auth); } /** diff --git a/site/tests/app/models/ConfigTester.php b/site/tests/app/models/ConfigTester.php index 7f69051de57..79a4d09175d 100644 --- a/site/tests/app/models/ConfigTester.php +++ b/site/tests/app/models/ConfigTester.php @@ -331,7 +331,7 @@ public function testConfig() { 'vcs_url' => 'http://example.com/{$vcs_type}/', 'wrapper_files' => [], 'system_message' => 'Some system message', - 'user_create_account' => false, + 'user_create_account' => true, 'secret_session' => 'LIW0RT5XAxOn2xjVY6rrLTcb6iacl4IDNRyPw58M0Kn0haQbHtNvPfK18xpvpD93', 'email_enabled' => true, 'auto_rainbow_grades' => false, From 2c737591a70347c344d5999c26701e41bf63bb2e Mon Sep 17 00:00:00 2001 From: IDzyre Date: Tue, 16 Jul 2024 10:40:10 -0800 Subject: [PATCH 12/58] Fix php lint --- .../app/controllers/AuthenticationController.php | 16 ++++++++-------- site/app/libraries/database/DatabaseQueries.php | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/site/app/controllers/AuthenticationController.php b/site/app/controllers/AuthenticationController.php index 0a21cd24eb2..79554c591b8 100644 --- a/site/app/controllers/AuthenticationController.php +++ b/site/app/controllers/AuthenticationController.php @@ -325,7 +325,7 @@ public function signupForm(): ResponseInterface { /** * Check if password has at least one of the following, Upper case letter, Lower case letter, Special character, and number */ - function checkChars($str): bool { + public function checkChars($str): bool { $upperCase = preg_match('/[A-Z]/', $str); $lowerCase = preg_match('/[a-z]/', $str); $specialChar = preg_match('/[^A-Za-z0-9]/', $str); @@ -350,12 +350,13 @@ public function isAcceptedEmail($email): bool { // Check if the file was read successfully try { $email_extension = explode('@', $email)[1]; - } catch (\Error $error) { + } + catch (\Error $error) { return false; } if ($json === false) { - return false; + return false; } // Decode the JSON file @@ -392,12 +393,12 @@ public function addNewUser(): RedirectResponse { $queried_list = $this->core->getQueries()->getFullEmailList(); - if (array_search($email, array_column($queried_list, 'user_email')) !== FALSE) { + if (array_search($email, array_column($queried_list, 'user_email')) !== false) { $this->core->addErrorMessage('Email already exists'); return new RedirectResponse($this->core->buildUrl(['authentication', 'create_account'])); } - if (array_search($user_id, array_column($queried_list, 'user_id')) !== FALSE) { + if (array_search($user_id, array_column($queried_list, 'user_id')) !== false) { $this->core->addErrorMessage('User ID already exists'); return new RedirectResponse($this->core->buildUrl(['authentication', 'create_account'])); } @@ -416,7 +417,7 @@ public function addNewUser(): RedirectResponse { $this->core->addErrorMessage('This email is not accepted.'); return new RedirectResponse($this->core->buildUrl(['authentication', 'create_account'])); } - + $user = new User($this->core, [ 'user_id' => $user_id, 'user_givenname' => $_POST['given_name'], @@ -434,10 +435,9 @@ public function addNewUser(): RedirectResponse { $this->core->addSuccessMessage('Account created successfully!'); return new RedirectResponse($this->core->buildUrl(['authentication', 'login'])); } - catch(Error $e) { + catch (Error $e) { $this->core->addErrorMessage('Failed to create the account.'); return new RedirectResponse($this->core->buildUrl(['authentication', 'create_account'])); } } - } diff --git a/site/app/libraries/database/DatabaseQueries.php b/site/app/libraries/database/DatabaseQueries.php index cd8bfa81056..de7acc5c620 100644 --- a/site/app/libraries/database/DatabaseQueries.php +++ b/site/app/libraries/database/DatabaseQueries.php @@ -7700,7 +7700,7 @@ public function getEmailListWithIds() { return $this->course_db->rows(); } - /** + /** * Gets a list of emails with user ids for all active particpants in Submitty */ public function getFullEmailList() { From f6f111b7366a663161646455b7f5917cd555582e Mon Sep 17 00:00:00 2001 From: IDzyre Date: Tue, 16 Jul 2024 10:49:30 -0800 Subject: [PATCH 13/58] Fix more php linting --- site/app/controllers/AuthenticationController.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/site/app/controllers/AuthenticationController.php b/site/app/controllers/AuthenticationController.php index 79554c591b8..9a094ce6022 100644 --- a/site/app/controllers/AuthenticationController.php +++ b/site/app/controllers/AuthenticationController.php @@ -350,7 +350,7 @@ public function isAcceptedEmail($email): bool { // Check if the file was read successfully try { $email_extension = explode('@', $email)[1]; - } + } catch (\Error $error) { return false; } @@ -364,7 +364,7 @@ public function isAcceptedEmail($email): bool { // Check if the JSON was decoded successfully if ($json_data === null) { - return false; + return false; } return in_array($email_extension, array_keys($json_data)); From 848715cd872fbf81dc09f7a190f0f596f26804b9 Mon Sep 17 00:00:00 2001 From: IDzyre Date: Tue, 16 Jul 2024 11:37:37 -0800 Subject: [PATCH 14/58] phpstan errors --- site/app/controllers/AuthenticationController.php | 11 ++++++----- site/app/libraries/database/DatabaseQueries.php | 2 +- site/app/views/AuthenticationView.php | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/site/app/controllers/AuthenticationController.php b/site/app/controllers/AuthenticationController.php index 9a094ce6022..48ff3890fee 100644 --- a/site/app/controllers/AuthenticationController.php +++ b/site/app/controllers/AuthenticationController.php @@ -324,26 +324,27 @@ public function signupForm(): ResponseInterface { /** * Check if password has at least one of the following, Upper case letter, Lower case letter, Special character, and number + * @param string $str */ public function checkChars($str): bool { $upperCase = preg_match('/[A-Z]/', $str); $lowerCase = preg_match('/[a-z]/', $str); $specialChar = preg_match('/[^A-Za-z0-9]/', $str); $numericVal = preg_match('/[0-9]/', $str); - return strlen($upperCase) > 1 && strlen($lowerCase) > 1 && strlen($specialChar) > 1 && strlen($numericVal) > 1; + return $upperCase >= 1 && $lowerCase >= 1 && $specialChar >= 1 && $numericVal >= 1; } /** * Returns true if the password is greater than or equal to 12 characters, and has the required characters + * @param string $password */ public function isGoodPassword($password): bool { return strlen($password) >= 12 && $this->checkChars($password); } /** - * * Checks if the email extension is in the accepted emails JSON file - * + * @param string $email */ public function isAcceptedEmail($email): bool { $json = file_get_contents('/usr/local/submitty/GIT_CHECKOUT/Submitty/.setup/accepted_emails.json'); @@ -367,7 +368,7 @@ public function isAcceptedEmail($email): bool { return false; } - return in_array($email_extension, array_keys($json_data)); + return in_array($email_extension, array_keys($json_data), true); } /** @@ -435,7 +436,7 @@ public function addNewUser(): RedirectResponse { $this->core->addSuccessMessage('Account created successfully!'); return new RedirectResponse($this->core->buildUrl(['authentication', 'login'])); } - catch (Error $e) { + catch (\Error $e) { $this->core->addErrorMessage('Failed to create the account.'); return new RedirectResponse($this->core->buildUrl(['authentication', 'create_account'])); } diff --git a/site/app/libraries/database/DatabaseQueries.php b/site/app/libraries/database/DatabaseQueries.php index de7acc5c620..edd334af95e 100644 --- a/site/app/libraries/database/DatabaseQueries.php +++ b/site/app/libraries/database/DatabaseQueries.php @@ -7703,7 +7703,7 @@ public function getEmailListWithIds() { /** * Gets a list of emails with user ids for all active particpants in Submitty */ - public function getFullEmailList() { + public function getFullEmailList(): array { $parameters = []; $this->submitty_db->query('SELECT user_id, user_email FROM users', $parameters); diff --git a/site/app/views/AuthenticationView.php b/site/app/views/AuthenticationView.php index 36756a7cb4d..7c364163196 100644 --- a/site/app/views/AuthenticationView.php +++ b/site/app/views/AuthenticationView.php @@ -50,7 +50,7 @@ public function userSelection(array $users) { ]); } - public function signupForm() { + public function signupForm(): string { $this->core->getOutput()->addInternalCss("input.css"); $this->core->getOutput()->addInternalCss("links.css"); $this->core->getOutput()->addInternalCss("authentication.css"); From ad8522ab4d5d645ee6d01f39406f6ec5938c0d7b Mon Sep 17 00:00:00 2001 From: IDzyre Date: Tue, 16 Jul 2024 13:13:55 -0800 Subject: [PATCH 15/58] More phpstan stuff --- site/app/controllers/AuthenticationController.php | 4 ++-- site/app/libraries/database/DatabaseQueries.php | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/site/app/controllers/AuthenticationController.php b/site/app/controllers/AuthenticationController.php index 48ff3890fee..2c9cbe0b4d7 100644 --- a/site/app/controllers/AuthenticationController.php +++ b/site/app/controllers/AuthenticationController.php @@ -394,12 +394,12 @@ public function addNewUser(): RedirectResponse { $queried_list = $this->core->getQueries()->getFullEmailList(); - if (array_search($email, array_column($queried_list, 'user_email')) !== false) { + if (array_search($email, array_column($queried_list, 'user_email'), true) !== false) { $this->core->addErrorMessage('Email already exists'); return new RedirectResponse($this->core->buildUrl(['authentication', 'create_account'])); } - if (array_search($user_id, array_column($queried_list, 'user_id')) !== false) { + if (array_search($user_id, array_column($queried_list, 'user_id'), true) !== false) { $this->core->addErrorMessage('User ID already exists'); return new RedirectResponse($this->core->buildUrl(['authentication', 'create_account'])); } diff --git a/site/app/libraries/database/DatabaseQueries.php b/site/app/libraries/database/DatabaseQueries.php index edd334af95e..ee6b611a0f7 100644 --- a/site/app/libraries/database/DatabaseQueries.php +++ b/site/app/libraries/database/DatabaseQueries.php @@ -7702,6 +7702,8 @@ public function getEmailListWithIds() { /** * Gets a list of emails with user ids for all active particpants in Submitty + * array + * @return array */ public function getFullEmailList(): array { $parameters = []; From d3d775c6bf935e252f79c62e8c269a0faf860802 Mon Sep 17 00:00:00 2001 From: IDzyre Date: Thu, 18 Jul 2024 09:10:48 -0800 Subject: [PATCH 16/58] Add migration --- .../20240718015237_self_account_creation.py | 32 +++++++++++++++++++ site/app/models/Config.php | 8 ++--- 2 files changed, 35 insertions(+), 5 deletions(-) create mode 100644 migration/migrator/migrations/master/20240718015237_self_account_creation.py diff --git a/migration/migrator/migrations/master/20240718015237_self_account_creation.py b/migration/migrator/migrations/master/20240718015237_self_account_creation.py new file mode 100644 index 00000000000..b97dffebec4 --- /dev/null +++ b/migration/migrator/migrations/master/20240718015237_self_account_creation.py @@ -0,0 +1,32 @@ +"""Migration for the Submitty master database.""" + +import json + +def up(config, database): + """ + Run up migration. + + :param config: Object holding configuration details about Submitty + :type config: migrator.config.Config + :param database: Object for interacting with given database for environment + :type database: migrator.db.Database + """ + with open('/usr/local/submitty/config/submitty.json', 'r') as conf: + SUBMITTY_CONFIG_JSON = json.load(conf) + if 'self_create_account' not in SUBMITTY_CONFIG_JSON: + SUBMITTY_CONFIG_JSON['self_create_account'] = False + + dump = open('/usr/local/submitty/config/submitty.json', 'w') + json.dump(SUBMITTY_CONFIG_JSON, dump, indent=4) + + +def down(config, database): + """ + Run down migration (rollback). + + :param config: Object holding configuration details about Submitty + :type config: migrator.config.Config + :param database: Object for interacting with given database for environment + :type database: migrator.db.Database + """ + pass diff --git a/site/app/models/Config.php b/site/app/models/Config.php index 64ff76cff6d..d63ff7f6883 100644 --- a/site/app/models/Config.php +++ b/site/app/models/Config.php @@ -218,10 +218,6 @@ class Config extends AbstractModel { * @var string Text shown to all users for system announcement */ protected $system_message = ''; - /** @prop - * @var bool Create New Account shown to at login page */ - protected $user_create_account; - /** @prop * @var array */ protected $submitty_database_params = []; @@ -426,8 +422,10 @@ public function loadMasterConfigs($config_path) { $this->sys_admin_email = $submitty_json['sys_admin_email'] ?? ''; $this->sys_admin_url = $submitty_json['sys_admin_url'] ?? ''; - // $this->user_create_account = $submitty_json['user_create_account'] === false; + $this->user_create_account = $submitty_json['user_create_account'] === true; + $this->user_create_account = true; + if (isset($submitty_json['timezone'])) { if (!in_array($submitty_json['timezone'], \DateTimeZone::listIdentifiers())) { throw new ConfigException("Invalid Timezone identifier: {$submitty_json['timezone']}"); From ca3cd5a003940119aba0404cbb9d8b310f890193 Mon Sep 17 00:00:00 2001 From: IDzyre Date: Thu, 18 Jul 2024 10:15:59 -0800 Subject: [PATCH 17/58] Fix migration --- .../migrations/master/20240718015237_self_account_creation.py | 4 ++-- site/app/models/Config.php | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/migration/migrator/migrations/master/20240718015237_self_account_creation.py b/migration/migrator/migrations/master/20240718015237_self_account_creation.py index b97dffebec4..fe6520200c8 100644 --- a/migration/migrator/migrations/master/20240718015237_self_account_creation.py +++ b/migration/migrator/migrations/master/20240718015237_self_account_creation.py @@ -13,8 +13,8 @@ def up(config, database): """ with open('/usr/local/submitty/config/submitty.json', 'r') as conf: SUBMITTY_CONFIG_JSON = json.load(conf) - if 'self_create_account' not in SUBMITTY_CONFIG_JSON: - SUBMITTY_CONFIG_JSON['self_create_account'] = False + if 'user_create_account' not in SUBMITTY_CONFIG_JSON: + SUBMITTY_CONFIG_JSON['user_create_account'] = False dump = open('/usr/local/submitty/config/submitty.json', 'w') json.dump(SUBMITTY_CONFIG_JSON, dump, indent=4) diff --git a/site/app/models/Config.php b/site/app/models/Config.php index d63ff7f6883..864bce422d8 100644 --- a/site/app/models/Config.php +++ b/site/app/models/Config.php @@ -424,8 +424,6 @@ public function loadMasterConfigs($config_path) { $this->user_create_account = $submitty_json['user_create_account'] === true; - $this->user_create_account = true; - if (isset($submitty_json['timezone'])) { if (!in_array($submitty_json['timezone'], \DateTimeZone::listIdentifiers())) { throw new ConfigException("Invalid Timezone identifier: {$submitty_json['timezone']}"); From ee8d9426cc862f530ab3bf6d177b9bb6cd48be43 Mon Sep 17 00:00:00 2001 From: IDzyre Date: Thu, 18 Jul 2024 11:24:43 -0800 Subject: [PATCH 18/58] Fix variable --- .../20240718015237_self_account_creation.py | 19 +++++++++++-------- site/app/models/Config.php | 3 +++ 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/migration/migrator/migrations/master/20240718015237_self_account_creation.py b/migration/migrator/migrations/master/20240718015237_self_account_creation.py index fe6520200c8..8b5ee6daba8 100644 --- a/migration/migrator/migrations/master/20240718015237_self_account_creation.py +++ b/migration/migrator/migrations/master/20240718015237_self_account_creation.py @@ -1,7 +1,7 @@ """Migration for the Submitty master database.""" import json - +from pathlib import Path def up(config, database): """ Run up migration. @@ -11,13 +11,16 @@ def up(config, database): :param database: Object for interacting with given database for environment :type database: migrator.db.Database """ - with open('/usr/local/submitty/config/submitty.json', 'r') as conf: - SUBMITTY_CONFIG_JSON = json.load(conf) - if 'user_create_account' not in SUBMITTY_CONFIG_JSON: - SUBMITTY_CONFIG_JSON['user_create_account'] = False - - dump = open('/usr/local/submitty/config/submitty.json', 'w') - json.dump(SUBMITTY_CONFIG_JSON, dump, indent=4) + + my_file = Path("/usr/local/submitty/config/submitty.json") + if my_file.is_file(): + with open('/usr/local/submitty/config/submitty.json', 'r') as conf: + SUBMITTY_CONFIG_JSON = json.load(conf) + if 'user_create_account' not in SUBMITTY_CONFIG_JSON: + SUBMITTY_CONFIG_JSON['user_create_account'] = False + + dump = open('/usr/local/submitty/config/submitty.json', 'w') + json.dump(SUBMITTY_CONFIG_JSON, dump, indent=4) def down(config, database): diff --git a/site/app/models/Config.php b/site/app/models/Config.php index 864bce422d8..caa00e96c4c 100644 --- a/site/app/models/Config.php +++ b/site/app/models/Config.php @@ -293,6 +293,9 @@ class Config extends AbstractModel { /** @prop * @var bool */ protected $seating_only_for_instructor; + /** @prop + * @var bool */ + protected $user_create_account; /** @prop * @var string|null */ protected $room_seating_gradeable_id; From 13f147c1a0ed5f57f3bb2c78eee3ce0b2b3b3342 Mon Sep 17 00:00:00 2001 From: IDzyre Date: Mon, 22 Jul 2024 11:48:11 -0800 Subject: [PATCH 19/58] Should fix php unit tests --- .../admin/ConfigurationControllerTester.php | 11 +++++++---- site/tests/app/models/ConfigTester.php | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/site/tests/app/controllers/admin/ConfigurationControllerTester.php b/site/tests/app/controllers/admin/ConfigurationControllerTester.php index c7d63a2e878..1ec5c597fca 100644 --- a/site/tests/app/controllers/admin/ConfigurationControllerTester.php +++ b/site/tests/app/controllers/admin/ConfigurationControllerTester.php @@ -32,7 +32,7 @@ public function setUpConfig($seating_dirs = []): void { 'email' => '{"email_enabled":true,"email_user":"","email_password":"","email_sender":"submitty@vagrant","email_reply_to":"do-not-reply@vagrant","email_server_hostname":"localhost","email_server_port":25}', 'secrets_submitty_php' => '{"session":"cGRZSDnVxdDjQwGyiq4ECnJyiZ8IQXEL1guSsJ1XlSKSEqisqvdCPhCRcYDEjpjm"}', 'submitty_admin' => '{"submitty_admin_username":"submitty-admin","token":"token"}', - 'submitty' => '{"submitty_install_dir":' . json_encode($this->test_dir) . ',"submitty_repository":' . json_encode($this->test_dir) . ',"submitty_data_dir":' . json_encode($this->test_dir) . ',"autograding_log_path":' . json_encode($this->test_dir) . ',"site_log_path":' . json_encode($this->test_dir) . ',"submission_url":"http:\/\/localhost:1501","vcs_url":"","cgi_url":"http:\/\/localhost:1501\/cgi-bin","institution_name":"","username_change_text":"foo","institution_homepage":"" ,"sys_admin_email": "admin@example.com","sys_admin_url": "https:\/\/example.com\/admin","timezone":"America\/New_York","worker":false,"duck_special_effects" : false}', + 'submitty' => '{"submitty_install_dir":' . json_encode($this->test_dir) . ',"submitty_repository":' . json_encode($this->test_dir) . ',"submitty_data_dir":' . json_encode($this->test_dir) . ',"autograding_log_path":' . json_encode($this->test_dir) . ',"site_log_path":' . json_encode($this->test_dir) . ',"submission_url":"http:\/\/localhost:1501","vcs_url":"","cgi_url":"http:\/\/localhost:1501\/cgi-bin","institution_name":"","username_change_text":"foo","institution_homepage":"" ,"sys_admin_email": "admin@example.com","sys_admin_url": "https:\/\/example.com\/admin","timezone":"America\/New_York","worker":false,"duck_special_effects" : false, user_create_account : false}', 'submitty_users' => '{"num_grading_scheduler_workers":5,"num_untrusted":60,"first_untrusted_uid":900,"first_untrusted_gid":900,"daemon_uid":1003,"daemon_gid":1006,"daemon_user":"submitty_daemon","course_builders_group":"submitty_course_builders","php_uid":1001,"php_gid":1004,"php_user":"submitty_php","cgi_user":"submitty_cgi","daemonphp_group":"submitty_daemonphp","daemoncgi_group":"submitty_daemoncgi","verified_submitty_admin_user":"submitty-admin"}', 'version' => '{"installed_commit":"7da8417edd6ff46f1d56e1a938b37c054a7dd071","short_installed_commit":"7da8417ed","most_recent_git_tag":"v19.09.04"}' ]; @@ -108,7 +108,8 @@ public function testViewConfiguration(): void { 'queue_announcement_message' => 'announcement message', 'seek_message_enabled' => false, 'seek_message_instructions' => '', - 'polls_enabled' => false + 'polls_enabled' => false, + 'user_create_account' => false ]; $gradeable_seating_options = [ @@ -190,7 +191,8 @@ public function testViewConfigurationWithSeatingChartsFirstItem(): void { 'queue_announcement_message' => 'announcement message', 'seek_message_enabled' => false, 'seek_message_instructions' => '', - 'polls_enabled' => false + 'polls_enabled' => false, + 'user_create_account' => false ]; $gradeable_seating_options = [ @@ -279,7 +281,8 @@ public function testViewConfigurationWithSeatingChartsNonFirstItem(): void { 'queue_announcement_message' => 'announcement message', 'seek_message_enabled' => false, 'seek_message_instructions' => '', - 'polls_enabled' => false + 'polls_enabled' => false, + 'user_create_account' => false ]; $gradeable_seating_options = [ diff --git a/site/tests/app/models/ConfigTester.php b/site/tests/app/models/ConfigTester.php index 79a4d09175d..7f69051de57 100644 --- a/site/tests/app/models/ConfigTester.php +++ b/site/tests/app/models/ConfigTester.php @@ -331,7 +331,7 @@ public function testConfig() { 'vcs_url' => 'http://example.com/{$vcs_type}/', 'wrapper_files' => [], 'system_message' => 'Some system message', - 'user_create_account' => true, + 'user_create_account' => false, 'secret_session' => 'LIW0RT5XAxOn2xjVY6rrLTcb6iacl4IDNRyPw58M0Kn0haQbHtNvPfK18xpvpD93', 'email_enabled' => true, 'auto_rainbow_grades' => false, From d2d613b78ab9f8e15ff4ce2ffb5d7389ff8a0a03 Mon Sep 17 00:00:00 2001 From: Cameron Peterson <46759635+IDzyre@users.noreply.github.com> Date: Sun, 28 Jul 2024 12:13:11 -0800 Subject: [PATCH 20/58] Fix missing quotes --- .../app/controllers/admin/ConfigurationControllerTester.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/tests/app/controllers/admin/ConfigurationControllerTester.php b/site/tests/app/controllers/admin/ConfigurationControllerTester.php index 1ec5c597fca..2b34d5473c4 100644 --- a/site/tests/app/controllers/admin/ConfigurationControllerTester.php +++ b/site/tests/app/controllers/admin/ConfigurationControllerTester.php @@ -32,7 +32,7 @@ public function setUpConfig($seating_dirs = []): void { 'email' => '{"email_enabled":true,"email_user":"","email_password":"","email_sender":"submitty@vagrant","email_reply_to":"do-not-reply@vagrant","email_server_hostname":"localhost","email_server_port":25}', 'secrets_submitty_php' => '{"session":"cGRZSDnVxdDjQwGyiq4ECnJyiZ8IQXEL1guSsJ1XlSKSEqisqvdCPhCRcYDEjpjm"}', 'submitty_admin' => '{"submitty_admin_username":"submitty-admin","token":"token"}', - 'submitty' => '{"submitty_install_dir":' . json_encode($this->test_dir) . ',"submitty_repository":' . json_encode($this->test_dir) . ',"submitty_data_dir":' . json_encode($this->test_dir) . ',"autograding_log_path":' . json_encode($this->test_dir) . ',"site_log_path":' . json_encode($this->test_dir) . ',"submission_url":"http:\/\/localhost:1501","vcs_url":"","cgi_url":"http:\/\/localhost:1501\/cgi-bin","institution_name":"","username_change_text":"foo","institution_homepage":"" ,"sys_admin_email": "admin@example.com","sys_admin_url": "https:\/\/example.com\/admin","timezone":"America\/New_York","worker":false,"duck_special_effects" : false, user_create_account : false}', + 'submitty' => '{"submitty_install_dir":' . json_encode($this->test_dir) . ',"submitty_repository":' . json_encode($this->test_dir) . ',"submitty_data_dir":' . json_encode($this->test_dir) . ',"autograding_log_path":' . json_encode($this->test_dir) . ',"site_log_path":' . json_encode($this->test_dir) . ',"submission_url":"http:\/\/localhost:1501","vcs_url":"","cgi_url":"http:\/\/localhost:1501\/cgi-bin","institution_name":"","username_change_text":"foo","institution_homepage":"" ,"sys_admin_email": "admin@example.com","sys_admin_url": "https:\/\/example.com\/admin","timezone":"America\/New_York","worker":false,"duck_special_effects" : false, "user_create_account" : false}', 'submitty_users' => '{"num_grading_scheduler_workers":5,"num_untrusted":60,"first_untrusted_uid":900,"first_untrusted_gid":900,"daemon_uid":1003,"daemon_gid":1006,"daemon_user":"submitty_daemon","course_builders_group":"submitty_course_builders","php_uid":1001,"php_gid":1004,"php_user":"submitty_php","cgi_user":"submitty_cgi","daemonphp_group":"submitty_daemonphp","daemoncgi_group":"submitty_daemoncgi","verified_submitty_admin_user":"submitty-admin"}', 'version' => '{"installed_commit":"7da8417edd6ff46f1d56e1a938b37c054a7dd071","short_installed_commit":"7da8417ed","most_recent_git_tag":"v19.09.04"}' ]; From 4837d94999c8854e46346da91f3a2d3eb03bee80 Mon Sep 17 00:00:00 2001 From: IDzyre Date: Sun, 28 Jul 2024 18:55:52 -0800 Subject: [PATCH 21/58] Add user_id requirements --- .setup/user_id_requirements.json | 16 +++++ .../controllers/AuthenticationController.php | 63 +++++++++++++++++-- 2 files changed, 73 insertions(+), 6 deletions(-) create mode 100644 .setup/user_id_requirements.json diff --git a/.setup/user_id_requirements.json b/.setup/user_id_requirements.json new file mode 100644 index 00000000000..45bef14ae45 --- /dev/null +++ b/.setup/user_id_requirements.json @@ -0,0 +1,16 @@ +{ + "all": false, + "require_name": true, + "length": -1, + "name_requirements": { + "given_first": false, + "given_name": 2, + "family_name": 4 + }, + "require_email": false, + "email_requirements": { + "whole_email": false, + "whole_prefix": false, + "prefix_count": 6 + } +} \ No newline at end of file diff --git a/site/app/controllers/AuthenticationController.php b/site/app/controllers/AuthenticationController.php index 2c9cbe0b4d7..85d640b0ae9 100644 --- a/site/app/controllers/AuthenticationController.php +++ b/site/app/controllers/AuthenticationController.php @@ -326,14 +326,60 @@ public function signupForm(): ResponseInterface { * Check if password has at least one of the following, Upper case letter, Lower case letter, Special character, and number * @param string $str */ - public function checkChars($str): bool { - $upperCase = preg_match('/[A-Z]/', $str); - $lowerCase = preg_match('/[a-z]/', $str); - $specialChar = preg_match('/[^A-Za-z0-9]/', $str); - $numericVal = preg_match('/[0-9]/', $str); + public function checkChars(string $password): bool { + $upperCase = preg_match('/[A-Z]/', $password); + $lowerCase = preg_match('/[a-z]/', $password); + $specialChar = preg_match('/[^A-Za-z0-9]/', $password); + $numericVal = preg_match('/[0-9]/', $password); return $upperCase >= 1 && $lowerCase >= 1 && $specialChar >= 1 && $numericVal >= 1; } + /** + * Check if the user ID is valid + * @param string $str + */ + public function isAcceptedUserId(string $user_id, string $given_name, string $family_name, string $email): bool { + $json = file_get_contents('/usr/local/submitty/GIT_CHECKOUT/Submitty/.setup/requirements.json'); + // Check if the file was read successfully + if ($json === false) { + return false; + } + + $requirements = json_decode($json, true); + + if ($requirements === null) { + return false; + } + + // If length is -1, allow any length + if ($requirements['length'] !== -1 && strlen($user_id) > $requirements['length']) { + return false; + } + + if ($requirements['all'] === true) { + return true; + } + + else if ($requirements['require_name'] === true) { + $name_requirements = $requirements['name_requirements']; + $given_first = $name_requirements['given_first']; + + $id_given_name = substr($user_id, ($given_first ? 0 : $name_requirements['given_name']), ($given_first ? $name_requirements['given_name'] : strlen($user_id))); + $id_family_name = substr($user_id, ($given_first ? $name_requirements['given_name'] : 0), ($given_first ? strlen($user_id) : $name_requirements['given_name']) ); + + if (($id_given_name === substr($given_name, 0, $name_requirements['given_name'])) && ($id_family_name === substr($family_name, 0, $name_requirements['family_name'])) ) { + return true; + } + + return false; + } else if ($requirements['require_email'] === true) { + + return true; + } else { + return false; + } + } + /** * Returns true if the password is greater than or equal to 12 characters, and has the required characters * @param string $password @@ -409,7 +455,7 @@ public function addNewUser(): RedirectResponse { return new RedirectResponse($this->core->buildUrl(['authentication', 'create_account'])); } - if (!($password === $confirm_password)) { + if ($password !== $confirm_password) { $this->core->addErrorMessage('Passwords did not match.'); return new RedirectResponse($this->core->buildUrl(['authentication', 'create_account'])); } @@ -419,6 +465,11 @@ public function addNewUser(): RedirectResponse { return new RedirectResponse($this->core->buildUrl(['authentication', 'create_account'])); } + if (!$this->isAcceptedUserId($user_id, $_POST['given_name'], $_POST['family_name'], $email)) { + $this->core->addErrorMessage('This user id is not accepted.'); + return new RedirectResponse($this->core->buildUrl(['authentication', 'create_account'])); + } + $user = new User($this->core, [ 'user_id' => $user_id, 'user_givenname' => $_POST['given_name'], From 043d14e523952898fd672632dbd9365af90a1821 Mon Sep 17 00:00:00 2001 From: IDzyre Date: Mon, 29 Jul 2024 11:19:33 -0800 Subject: [PATCH 22/58] Default to all user_ids --- .setup/user_id_requirements.json | 4 ++-- .../controllers/AuthenticationController.php | 17 +++++++++-------- .../admin/ConfigurationControllerTester.php | 11 ++++------- 3 files changed, 15 insertions(+), 17 deletions(-) diff --git a/.setup/user_id_requirements.json b/.setup/user_id_requirements.json index 45bef14ae45..5b6914e89b6 100644 --- a/.setup/user_id_requirements.json +++ b/.setup/user_id_requirements.json @@ -1,6 +1,6 @@ { - "all": false, - "require_name": true, + "all": true, + "require_name": false, "length": -1, "name_requirements": { "given_first": false, diff --git a/site/app/controllers/AuthenticationController.php b/site/app/controllers/AuthenticationController.php index 85d640b0ae9..db5abc13601 100644 --- a/site/app/controllers/AuthenticationController.php +++ b/site/app/controllers/AuthenticationController.php @@ -339,7 +339,7 @@ public function checkChars(string $password): bool { * @param string $str */ public function isAcceptedUserId(string $user_id, string $given_name, string $family_name, string $email): bool { - $json = file_get_contents('/usr/local/submitty/GIT_CHECKOUT/Submitty/.setup/requirements.json'); + $json = file_get_contents('/usr/local/submitty/GIT_CHECKOUT/Submitty/.setup/user_id_requirements.json'); // Check if the file was read successfully if ($json === false) { return false; @@ -364,10 +364,11 @@ public function isAcceptedUserId(string $user_id, string $given_name, string $fa $name_requirements = $requirements['name_requirements']; $given_first = $name_requirements['given_first']; - $id_given_name = substr($user_id, ($given_first ? 0 : $name_requirements['given_name']), ($given_first ? $name_requirements['given_name'] : strlen($user_id))); - $id_family_name = substr($user_id, ($given_first ? $name_requirements['given_name'] : 0), ($given_first ? strlen($user_id) : $name_requirements['given_name']) ); - - if (($id_given_name === substr($given_name, 0, $name_requirements['given_name'])) && ($id_family_name === substr($family_name, 0, $name_requirements['family_name'])) ) { + $id_given_name = substr($user_id, ($given_first ? 0 : $name_requirements['family_name']), ($given_first ? $name_requirements['given_name'] : strlen($user_id))); + $id_family_name = substr($user_id, ($given_first ? $name_requirements['given_name'] : 0), ($given_first ? strlen($user_id) : $name_requirements['family_name'])); + $is_given_name = (strtolower($id_given_name) === substr(strtolower($given_name), 0, $name_requirements['given_name'])); + $is_family_name = (strtolower($id_family_name) === substr(strtolower($family_name), 0, $name_requirements['family_name'])); + if ($is_family_name && $is_given_name) { return true; } @@ -440,12 +441,12 @@ public function addNewUser(): RedirectResponse { $queried_list = $this->core->getQueries()->getFullEmailList(); - if (array_search($email, array_column($queried_list, 'user_email'), true) !== false) { + if (in_array($email, array_column($queried_list, 'user_email'), true)) { $this->core->addErrorMessage('Email already exists'); return new RedirectResponse($this->core->buildUrl(['authentication', 'create_account'])); } - if (array_search($user_id, array_column($queried_list, 'user_id'), true) !== false) { + if (in_array($user_id, array_column($queried_list, 'user_id'), true)) { $this->core->addErrorMessage('User ID already exists'); return new RedirectResponse($this->core->buildUrl(['authentication', 'create_account'])); } @@ -466,7 +467,7 @@ public function addNewUser(): RedirectResponse { } if (!$this->isAcceptedUserId($user_id, $_POST['given_name'], $_POST['family_name'], $email)) { - $this->core->addErrorMessage('This user id is not accepted.'); + $this->core->addErrorMessage('This user id does not meet requirements.'); return new RedirectResponse($this->core->buildUrl(['authentication', 'create_account'])); } diff --git a/site/tests/app/controllers/admin/ConfigurationControllerTester.php b/site/tests/app/controllers/admin/ConfigurationControllerTester.php index 2b34d5473c4..1992f2e14e4 100644 --- a/site/tests/app/controllers/admin/ConfigurationControllerTester.php +++ b/site/tests/app/controllers/admin/ConfigurationControllerTester.php @@ -32,7 +32,7 @@ public function setUpConfig($seating_dirs = []): void { 'email' => '{"email_enabled":true,"email_user":"","email_password":"","email_sender":"submitty@vagrant","email_reply_to":"do-not-reply@vagrant","email_server_hostname":"localhost","email_server_port":25}', 'secrets_submitty_php' => '{"session":"cGRZSDnVxdDjQwGyiq4ECnJyiZ8IQXEL1guSsJ1XlSKSEqisqvdCPhCRcYDEjpjm"}', 'submitty_admin' => '{"submitty_admin_username":"submitty-admin","token":"token"}', - 'submitty' => '{"submitty_install_dir":' . json_encode($this->test_dir) . ',"submitty_repository":' . json_encode($this->test_dir) . ',"submitty_data_dir":' . json_encode($this->test_dir) . ',"autograding_log_path":' . json_encode($this->test_dir) . ',"site_log_path":' . json_encode($this->test_dir) . ',"submission_url":"http:\/\/localhost:1501","vcs_url":"","cgi_url":"http:\/\/localhost:1501\/cgi-bin","institution_name":"","username_change_text":"foo","institution_homepage":"" ,"sys_admin_email": "admin@example.com","sys_admin_url": "https:\/\/example.com\/admin","timezone":"America\/New_York","worker":false,"duck_special_effects" : false, "user_create_account" : false}', + 'submitty' => '{"submitty_install_dir":' . json_encode($this->test_dir) . ',"submitty_repository":' . json_encode($this->test_dir) . ',"submitty_data_dir":' . json_encode($this->test_dir) . ',"autograding_log_path":' . json_encode($this->test_dir) . ',"site_log_path":' . json_encode($this->test_dir) . ',"submission_url":"http:\/\/localhost:1501","vcs_url":"","cgi_url":"http:\/\/localhost:1501\/cgi-bin","institution_name":"","username_change_text":"foo","institution_homepage":"" ,"sys_admin_email": "admin@example.com","sys_admin_url": "https:\/\/example.com\/admin","timezone":"America\/New_York","worker":false,"duck_special_effects":false,"user_create_account":false}', 'submitty_users' => '{"num_grading_scheduler_workers":5,"num_untrusted":60,"first_untrusted_uid":900,"first_untrusted_gid":900,"daemon_uid":1003,"daemon_gid":1006,"daemon_user":"submitty_daemon","course_builders_group":"submitty_course_builders","php_uid":1001,"php_gid":1004,"php_user":"submitty_php","cgi_user":"submitty_cgi","daemonphp_group":"submitty_daemonphp","daemoncgi_group":"submitty_daemoncgi","verified_submitty_admin_user":"submitty-admin"}', 'version' => '{"installed_commit":"7da8417edd6ff46f1d56e1a938b37c054a7dd071","short_installed_commit":"7da8417ed","most_recent_git_tag":"v19.09.04"}' ]; @@ -108,8 +108,7 @@ public function testViewConfiguration(): void { 'queue_announcement_message' => 'announcement message', 'seek_message_enabled' => false, 'seek_message_instructions' => '', - 'polls_enabled' => false, - 'user_create_account' => false + 'polls_enabled' => false ]; $gradeable_seating_options = [ @@ -191,8 +190,7 @@ public function testViewConfigurationWithSeatingChartsFirstItem(): void { 'queue_announcement_message' => 'announcement message', 'seek_message_enabled' => false, 'seek_message_instructions' => '', - 'polls_enabled' => false, - 'user_create_account' => false + 'polls_enabled' => false ]; $gradeable_seating_options = [ @@ -281,8 +279,7 @@ public function testViewConfigurationWithSeatingChartsNonFirstItem(): void { 'queue_announcement_message' => 'announcement message', 'seek_message_enabled' => false, 'seek_message_instructions' => '', - 'polls_enabled' => false, - 'user_create_account' => false + 'polls_enabled' => false ]; $gradeable_seating_options = [ From b6285d716f662dc3e33ace3bb6fecf8e075f1317 Mon Sep 17 00:00:00 2001 From: IDzyre Date: Mon, 29 Jul 2024 11:30:19 -0800 Subject: [PATCH 23/58] linting --- site/app/controllers/AuthenticationController.php | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/site/app/controllers/AuthenticationController.php b/site/app/controllers/AuthenticationController.php index db5abc13601..32d51a39660 100644 --- a/site/app/controllers/AuthenticationController.php +++ b/site/app/controllers/AuthenticationController.php @@ -359,8 +359,7 @@ public function isAcceptedUserId(string $user_id, string $given_name, string $fa if ($requirements['all'] === true) { return true; } - - else if ($requirements['require_name'] === true) { + elseif ($requirements['require_name'] === true) { $name_requirements = $requirements['name_requirements']; $given_first = $name_requirements['given_first']; @@ -371,12 +370,12 @@ public function isAcceptedUserId(string $user_id, string $given_name, string $fa if ($is_family_name && $is_given_name) { return true; } - return false; - } else if ($requirements['require_email'] === true) { - + } + elseif ($requirements['require_email'] === true) { return true; - } else { + } + else { return false; } } From b92be11856ba81796a516d003319cec4fae2b75a Mon Sep 17 00:00:00 2001 From: IDzyre Date: Mon, 29 Jul 2024 11:36:53 -0800 Subject: [PATCH 24/58] phpstan --- site/app/controllers/AuthenticationController.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/site/app/controllers/AuthenticationController.php b/site/app/controllers/AuthenticationController.php index 32d51a39660..2a7b0db93c7 100644 --- a/site/app/controllers/AuthenticationController.php +++ b/site/app/controllers/AuthenticationController.php @@ -324,7 +324,6 @@ public function signupForm(): ResponseInterface { /** * Check if password has at least one of the following, Upper case letter, Lower case letter, Special character, and number - * @param string $str */ public function checkChars(string $password): bool { $upperCase = preg_match('/[A-Z]/', $password); @@ -336,7 +335,6 @@ public function checkChars(string $password): bool { /** * Check if the user ID is valid - * @param string $str */ public function isAcceptedUserId(string $user_id, string $given_name, string $family_name, string $email): bool { $json = file_get_contents('/usr/local/submitty/GIT_CHECKOUT/Submitty/.setup/user_id_requirements.json'); @@ -361,7 +359,7 @@ public function isAcceptedUserId(string $user_id, string $given_name, string $fa } elseif ($requirements['require_name'] === true) { $name_requirements = $requirements['name_requirements']; - $given_first = $name_requirements['given_first']; + $given_first = $name_requirements['given_first'] === 'true'; $id_given_name = substr($user_id, ($given_first ? 0 : $name_requirements['family_name']), ($given_first ? $name_requirements['given_name'] : strlen($user_id))); $id_family_name = substr($user_id, ($given_first ? $name_requirements['given_name'] : 0), ($given_first ? strlen($user_id) : $name_requirements['family_name'])); From a303aa26e986facafcc71ff4ac7b382b606622e7 Mon Sep 17 00:00:00 2001 From: IDzyre Date: Tue, 30 Jul 2024 11:16:57 -0800 Subject: [PATCH 25/58] Add tooltip for password --- site/app/templates/CreateNewAccount.twig | 22 +++++++++++++++++++++- site/public/css/authentication.css | 12 ++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/site/app/templates/CreateNewAccount.twig b/site/app/templates/CreateNewAccount.twig index 6b89db68589..cbf0fc9da71 100644 --- a/site/app/templates/CreateNewAccount.twig +++ b/site/app/templates/CreateNewAccount.twig @@ -23,7 +23,15 @@