From 63d70fc0373397d79e4a8f918a71b0be0c5bdf2c Mon Sep 17 00:00:00 2001 From: pateljannat Date: Thu, 5 Aug 2021 15:51:21 +0530 Subject: [PATCH 1/3] fix: username space and empty validations --- community/lms/web_form/profile/profile.json | 14 +++++++++++++- community/overrides/user.py | 19 +++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/community/lms/web_form/profile/profile.json b/community/lms/web_form/profile/profile.json index 4c3fcc7d..bcea7451 100644 --- a/community/lms/web_form/profile/profile.json +++ b/community/lms/web_form/profile/profile.json @@ -20,7 +20,7 @@ "is_standard": 1, "login_required": 1, "max_attachment_size": 0, - "modified": "2021-07-14 17:15:15.424855", + "modified": "2021-08-05 10:27:15.727657", "modified_by": "Administrator", "module": "LMS", "name": "profile", @@ -72,6 +72,18 @@ "reqd": 0, "show_in_filter": 0 }, + { + "allow_read_on_all_link_options": 0, + "fieldname": "username", + "fieldtype": "Data", + "hidden": 0, + "label": "Username", + "max_length": 0, + "max_value": 0, + "read_only": 0, + "reqd": 0, + "show_in_filter": 0 + }, { "allow_read_on_all_link_options": 0, "description": "Get your globally recognized avatar from Gravatar.com", diff --git a/community/overrides/user.py b/community/overrides/user.py index bcb1496a..78839e82 100644 --- a/community/overrides/user.py +++ b/community/overrides/user.py @@ -2,9 +2,28 @@ import frappe from frappe.core.doctype.user.user import User from frappe.utils import cint import hashlib +import random +import re +from frappe import _ class CustomUser(User): + """ def validate(self): + super(CustomUser, self).validate() + self.validate_username() """ + + """ def validate_username(self): + if self.is_new(): + if self.username.find(" "): + self.username.replace(" ", "") + if not self.username: + self.username = frappe.scrub(self.first_name) + random.randint() + + elif not re.match("^[A-Za-z0-9_]*$", self.username): + frappe.throw(_("Username can only contain alphabets, numbers and underscore.")) """ + + + def get_authored_courses(self) -> int: """Returns the number of courses authored by this user. """ From 844fcc9bcab04163220b97d03f9f6b92925d1f03 Mon Sep 17 00:00:00 2001 From: pateljannat Date: Fri, 6 Aug 2021 14:41:11 +0530 Subject: [PATCH 2/3] fix: username validations --- community/lms/web_form/profile/profile.js | 7 +++ community/overrides/test_user.py | 54 +++++++++++++++++++++++ community/overrides/user.py | 34 +++++++++++--- 3 files changed, 89 insertions(+), 6 deletions(-) create mode 100644 community/overrides/test_user.py diff --git a/community/lms/web_form/profile/profile.js b/community/lms/web_form/profile/profile.js index 027cef49..286ed9b5 100644 --- a/community/lms/web_form/profile/profile.js +++ b/community/lms/web_form/profile/profile.js @@ -1,7 +1,14 @@ frappe.ready(function () { + frappe.web_form.after_load = () => { if (!frappe.utils.get_url_arg("name")) { window.location.href = `/edit-profile?name=${frappe.session.user}`; } } + + frappe.web_form.after_save = () => { + setTimeout(() => { + window.location.href = `/${frappe.web_form.get_value(["username"])}`; + }) + } }) diff --git a/community/overrides/test_user.py b/community/overrides/test_user.py new file mode 100644 index 00000000..cb6ce268 --- /dev/null +++ b/community/overrides/test_user.py @@ -0,0 +1,54 @@ +# Copyright (c) 2021, FOSS United and Contributors +# See license.txt + +# import frappe +import unittest +import frappe + +class TestCustomUser(unittest.TestCase): + + def test_with_basic_username(self): + new_user = frappe.get_doc({ + "doctype": "User", + "email": "test_with_basic_username@example.com", + "first_name": "Username" + }).insert() + self.assertEqual(new_user.username, "username") + + def test_without_username(self): + """ The user in this test has the same first name as the user of the test test_with_basic_username. + In such cases frappe makes the username of the second user empty. + The condition in community app should override this and save a username. """ + new_user = frappe.get_doc({ + "doctype": "User", + "email": "test-without-username@example.com", + "first_name": "Username" + }).insert() + self.assertTrue(new_user.username) + + def test_with_illegal_characters(self): + new_user = frappe.get_doc({ + "doctype": "User", + "email": "test_with_illegal_characters@example.com", + "first_name": "Username$$" + }).insert() + self.assertEqual(new_user.username[:8], "username") + + def test_with_hyphen_at_end(self): + new_user = frappe.get_doc({ + "doctype": "User", + "email": "test_with_hyphen_at_end@example.com", + "first_name": "Username---" + }).insert() + length = len(new_user.username) + self.assertNotEqual(new_user.username[length-1], "-") + + @classmethod + def tearDownClass(cls) -> None: + users = [ + "test_with_basic_username@example.com", + "test-without-username@example.com", + "test_with_illegal_characters@example.com", + "test_with_hyphen_at_end@example.com" + ] + frappe.db.delete("User", {"name": ["in", users]}) diff --git a/community/overrides/user.py b/community/overrides/user.py index 78839e82..0a85e44c 100644 --- a/community/overrides/user.py +++ b/community/overrides/user.py @@ -8,21 +8,43 @@ from frappe import _ class CustomUser(User): - """ def validate(self): + def validate(self): super(CustomUser, self).validate() - self.validate_username() """ + self.validate_username_characters() - """ def validate_username(self): + def validate_username_characters(self): if self.is_new(): + if self.username.find(" "): self.username.replace(" ", "") + + if not re.match("^[A-Za-z0-9_]*$", self.username): + self.username = self.remove_illegal_characters() + if not self.username: - self.username = frappe.scrub(self.first_name) + random.randint() + self.username = self.get_username_from_first_name() - elif not re.match("^[A-Za-z0-9_]*$", self.username): - frappe.throw(_("Username can only contain alphabets, numbers and underscore.")) """ + if self.username_exists(): + self.username = self.remove_illegal_characters() + str(random.randint(0, 99)) + else: + if not re.match("^[A-Za-z0-9_-]*$", self.username): + frappe.throw(_("Username can only contain alphabets, numbers, hyphen and underscore.")) + if self.username[0] == "-" or self.username[len(self.username) - 1] == "-": + frappe.throw(_("First and Last character of username cannot be Hyphen(-).")) + + def get_username_from_first_name(self): + return frappe.scrub(self.first_name) + str(random.randint(0, 99)) + + def remove_illegal_characters(self): + username = ''.join([c for c in self.username if c.isalnum() or c in ['-', '_']]) + while username[0] == "-" or username[len(username) - 1] == "-": + if username[0] == "-": + username = username[1:] + if username[len(username) - 1]: + username = username[:1] + return username def get_authored_courses(self) -> int: """Returns the number of courses authored by this user. From 04d44510ded1b065b3ca36b06dd7a9be0b832424 Mon Sep 17 00:00:00 2001 From: pateljannat Date: Fri, 6 Aug 2021 14:41:37 +0530 Subject: [PATCH 3/3] fix: redirect after edit profile save --- community/lms/web_form/profile/profile.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/community/lms/web_form/profile/profile.json b/community/lms/web_form/profile/profile.json index bcea7451..3ba731a9 100644 --- a/community/lms/web_form/profile/profile.json +++ b/community/lms/web_form/profile/profile.json @@ -11,6 +11,7 @@ "apply_document_permissions": 0, "breadcrumbs": "", "button_label": "Save", + "client_script": "", "creation": "2021-06-30 13:48:13.682851", "custom_css": "[data-doctype=\"Web Form\"] {\n max-width: 720px;\n margin: 6rem auto;\n}", "doc_type": "User", @@ -20,7 +21,7 @@ "is_standard": 1, "login_required": 1, "max_attachment_size": 0, - "modified": "2021-08-05 10:27:15.727657", + "modified": "2021-08-06 14:40:39.013776", "modified_by": "Administrator", "module": "LMS", "name": "profile",