From 73edbf7ff32d32af7287ee5c0236e8e598b860e4 Mon Sep 17 00:00:00 2001 From: Sagar Vora Date: Mon, 5 Dec 2022 00:19:33 +0530 Subject: [PATCH 01/15] fix: validate parentfield while checking child perms --- frappe/permissions.py | 39 ++++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/frappe/permissions.py b/frappe/permissions.py index 2997165dc9..d734f79a4e 100644 --- a/frappe/permissions.py +++ b/frappe/permissions.py @@ -707,8 +707,10 @@ def has_child_permission( parent_meta = frappe.get_meta(parent_doctype) - if parent_meta.istable or all( - df.options != child_doctype for df in parent_meta.get_table_fields() + if parent_meta.istable or not ( + valid_parentfields := [ + df.fieldname for df in parent_meta.get_table_fields() if df.options == child_doctype + ] ): push_perm_check_log( _("{0} is not a valid parent DocType for {1}").format( @@ -717,15 +719,30 @@ def has_child_permission( ) return False - if ( - child_doc - and (permlevel := parent_meta.get_field(child_doc.parentfield).permlevel) > 0 - and permlevel not in parent_meta.get_permlevel_access(ptype, user=user) - ): - push_perm_check_log( - _("Insufficient Permission Level for {0}").format(frappe.bold(parent_doctype)) - ) - return False + if child_doc: + parentfield = child_doc.parentfield + if not parentfield: + push_perm_check_log( + _("Parentfield not specified in {0}: {1}").format( + frappe.bold(child_doctype), frappe.bold(child_doc.name) + ) + ) + return False + + if parentfield not in valid_parentfields: + push_perm_check_log( + _("{0} is not a valid parentfield for {1}").format( + frappe.bold(parentfield), frappe.bold(child_doctype) + ) + ) + return False + + permlevel = parent_meta.get_field(parentfield).permlevel + if permlevel > 0 and permlevel not in parent_meta.get_permlevel_access(ptype, user=user): + push_perm_check_log( + _("Insufficient Permission Level for {0}").format(frappe.bold(parent_doctype)) + ) + return False return has_permission( parent_doctype, From 481ff1b2afcb81a1d07b1ca01c673e7b11f6baf6 Mon Sep 17 00:00:00 2001 From: Sagar Vora Date: Mon, 5 Dec 2022 01:35:57 +0530 Subject: [PATCH 02/15] test: add testcases for parentfield validations --- frappe/tests/test_permissions.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/frappe/tests/test_permissions.py b/frappe/tests/test_permissions.py index f48273135a..dbe3f20519 100644 --- a/frappe/tests/test_permissions.py +++ b/frappe/tests/test_permissions.py @@ -665,6 +665,16 @@ class TestPermissions(FrappeTestCase): doc = user.append("defaults") doc.check_permission() + # false due to missing parentfield + doc = user.append("roles") + doc.parentfield = None + self.assertRaises(frappe.PermissionError, doc.check_permission) + + # false due to invalid parentfield + doc = user.append("roles") + doc.parentfield = "first_name" + self.assertRaises(frappe.PermissionError, doc.check_permission) + # false by permlevel doc = user.append("roles") self.assertRaises(frappe.PermissionError, doc.check_permission) From 77976293ed87849189b0c3c4b074bd64c7d1bdcf Mon Sep 17 00:00:00 2001 From: Ejaaz Khan <67804911+iamejaaz@users.noreply.github.com> Date: Tue, 6 Dec 2022 18:31:06 +0530 Subject: [PATCH 03/15] fix: workflow icon not visible in mobile view --- frappe/public/js/frappe/ui/page.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frappe/public/js/frappe/ui/page.html b/frappe/public/js/frappe/ui/page.html index 06d1baec69..daea9fe03a 100644 --- a/frappe/public/js/frappe/ui/page.html +++ b/frappe/public/js/frappe/ui/page.html @@ -52,8 +52,8 @@
- \ No newline at end of file + From f2e1dbe7eb677ea3007bf8bb42ec94aba397cf2b Mon Sep 17 00:00:00 2001 From: Sagar Vora Date: Wed, 7 Dec 2022 13:13:27 +0530 Subject: [PATCH 04/15] fix: restore `_dict`, used in Jinja code --- frappe/tests/test_safe_exec.py | 3 +++ frappe/utils/safe_exec.py | 1 + 2 files changed, 4 insertions(+) diff --git a/frappe/tests/test_safe_exec.py b/frappe/tests/test_safe_exec.py index fcd5832680..1e370a1160 100644 --- a/frappe/tests/test_safe_exec.py +++ b/frappe/tests/test_safe_exec.py @@ -75,3 +75,6 @@ class TestSafeExec(FrappeTestCase): def test_unsafe_objects(self): unsafe_global = {"frappe": frappe} self.assertRaises(SyntaxError, safe_exec, """frappe.msgprint("Hello")""", unsafe_global) + + def test_frappe_dict_in_jinja(self): + frappe.render_template("{% set my_dict = _dict() %} {{- my_dict.works -}}", {}) diff --git a/frappe/utils/safe_exec.py b/frappe/utils/safe_exec.py index 890f16a1c3..a362664aad 100644 --- a/frappe/utils/safe_exec.py +++ b/frappe/utils/safe_exec.py @@ -105,6 +105,7 @@ def get_safe_globals(): json=NamespaceDict(loads=json.loads, dumps=json.dumps), as_json=frappe.as_json, dict=dict, + _dict=frappe._dict, # this isn't usable with RestrictedPython, but kept for Jinja compatibility log=frappe.log, args=form_dict, frappe=NamespaceDict( From 10695d3d496bd6f8a28e77eef675d161cb4909f6 Mon Sep 17 00:00:00 2001 From: Sagar Vora Date: Wed, 7 Dec 2022 13:32:38 +0530 Subject: [PATCH 05/15] feat: make context optional when calling `render_template` --- frappe/tests/test_safe_exec.py | 2 +- frappe/utils/jinja.py | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/frappe/tests/test_safe_exec.py b/frappe/tests/test_safe_exec.py index 1e370a1160..15d898b716 100644 --- a/frappe/tests/test_safe_exec.py +++ b/frappe/tests/test_safe_exec.py @@ -77,4 +77,4 @@ class TestSafeExec(FrappeTestCase): self.assertRaises(SyntaxError, safe_exec, """frappe.msgprint("Hello")""", unsafe_global) def test_frappe_dict_in_jinja(self): - frappe.render_template("{% set my_dict = _dict() %} {{- my_dict.works -}}", {}) + frappe.render_template("{% set my_dict = _dict() %} {{- my_dict.works -}}") diff --git a/frappe/utils/jinja.py b/frappe/utils/jinja.py index 5e3a70554d..01ab5ab48c 100644 --- a/frappe/utils/jinja.py +++ b/frappe/utils/jinja.py @@ -60,7 +60,7 @@ def validate_template(html): frappe.throw(frappe._("Syntax error in template")) -def render_template(template, context, is_path=None, safe_render=True): +def render_template(template, context=None, is_path=None, safe_render=True): """Render a template using Jinja :param template: path or HTML containing the jinja template @@ -76,6 +76,9 @@ def render_template(template, context, is_path=None, safe_render=True): if not template: return "" + if not context: + context = {} + if is_path or guess_is_path(template): return get_jenv().get_template(template).render(context) else: From 7d47d1069214873c86775746b77e800e284507a1 Mon Sep 17 00:00:00 2001 From: Sagar Vora Date: Wed, 7 Dec 2022 13:45:28 +0530 Subject: [PATCH 06/15] fix: override RestrictedPython transformer to allow `_dict`, revert `frappe.as_dict` --- frappe/tests/test_safe_exec.py | 6 +++++- frappe/utils/safe_exec.py | 16 +++++++++++++--- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/frappe/tests/test_safe_exec.py b/frappe/tests/test_safe_exec.py index 15d898b716..ad09aaea59 100644 --- a/frappe/tests/test_safe_exec.py +++ b/frappe/tests/test_safe_exec.py @@ -76,5 +76,9 @@ class TestSafeExec(FrappeTestCase): unsafe_global = {"frappe": frappe} self.assertRaises(SyntaxError, safe_exec, """frappe.msgprint("Hello")""", unsafe_global) - def test_frappe_dict_in_jinja(self): + def test_attrdict(self): + # jinja frappe.render_template("{% set my_dict = _dict() %} {{- my_dict.works -}}") + + # RestrictedPython + safe_exec("my_dict = _dict()") diff --git a/frappe/utils/safe_exec.py b/frappe/utils/safe_exec.py index a362664aad..c31c1b72d4 100644 --- a/frappe/utils/safe_exec.py +++ b/frappe/utils/safe_exec.py @@ -8,6 +8,7 @@ from functools import lru_cache import RestrictedPython.Guards from RestrictedPython import compile_restricted, safe_globals +from RestrictedPython.transformer import RestrictingNodeTransformer import frappe import frappe.exceptions @@ -45,6 +46,14 @@ class NamespaceDict(frappe._dict): return ret +class FrappeTransformer(RestrictingNodeTransformer): + def check_name(self, node, name, *args, **kwargs): + if name == "_dict": + return + + return super().check_name(node, name, *args, **kwargs) + + def safe_exec(script, _globals=None, _locals=None, restrict_commit_rollback=False): # server scripts can be disabled via site_config.json # they are enabled by default @@ -69,7 +78,9 @@ def safe_exec(script, _globals=None, _locals=None, restrict_commit_rollback=Fals with safe_exec_flags(), patched_qb(): # execute script compiled by RestrictedPython - exec(compile_restricted(script), exec_globals, _locals) # pylint: disable=exec-used + exec( + compile_restricted(script, policy=FrappeTransformer), exec_globals, _locals + ) # pylint: disable=exec-used return exec_globals, _locals @@ -105,7 +116,7 @@ def get_safe_globals(): json=NamespaceDict(loads=json.loads, dumps=json.dumps), as_json=frappe.as_json, dict=dict, - _dict=frappe._dict, # this isn't usable with RestrictedPython, but kept for Jinja compatibility + _dict=frappe._dict, log=frappe.log, args=form_dict, frappe=NamespaceDict( @@ -117,7 +128,6 @@ def get_safe_globals(): time_format=time_format, format_date=frappe.utils.data.global_date_format, form_dict=form_dict, - as_dict=frappe._dict, bold=frappe.bold, copy_doc=frappe.copy_doc, errprint=frappe.errprint, From aa53779e6b2abf9723b6c9460da8b2da6a0dc79a Mon Sep 17 00:00:00 2001 From: Sagar Vora Date: Wed, 7 Dec 2022 13:46:34 +0530 Subject: [PATCH 07/15] fix: improve condition to init context --- frappe/utils/jinja.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/utils/jinja.py b/frappe/utils/jinja.py index 01ab5ab48c..33bb929bc4 100644 --- a/frappe/utils/jinja.py +++ b/frappe/utils/jinja.py @@ -76,7 +76,7 @@ def render_template(template, context=None, is_path=None, safe_render=True): if not template: return "" - if not context: + if context is None: context = {} if is_path or guess_is_path(template): From 0c220169da7700a2eef0be87cbd2d10ff017161e Mon Sep 17 00:00:00 2001 From: Sagar Vora Date: Wed, 7 Dec 2022 13:50:59 +0530 Subject: [PATCH 08/15] chore: reorder pylint disable --- frappe/utils/safe_exec.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/frappe/utils/safe_exec.py b/frappe/utils/safe_exec.py index c31c1b72d4..01025c98bb 100644 --- a/frappe/utils/safe_exec.py +++ b/frappe/utils/safe_exec.py @@ -78,9 +78,8 @@ def safe_exec(script, _globals=None, _locals=None, restrict_commit_rollback=Fals with safe_exec_flags(), patched_qb(): # execute script compiled by RestrictedPython - exec( - compile_restricted(script, policy=FrappeTransformer), exec_globals, _locals - ) # pylint: disable=exec-used + # pylint: disable-next=exec-used + exec(compile_restricted(script, policy=FrappeTransformer), exec_globals, _locals) return exec_globals, _locals From 5f2cc8ec79f672ebf408d26d4ad466a92fa57871 Mon Sep 17 00:00:00 2001 From: Sagar Vora Date: Wed, 7 Dec 2022 14:09:02 +0530 Subject: [PATCH 09/15] chore: keep previous order for easy backport --- frappe/utils/safe_exec.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/utils/safe_exec.py b/frappe/utils/safe_exec.py index 01025c98bb..053793af03 100644 --- a/frappe/utils/safe_exec.py +++ b/frappe/utils/safe_exec.py @@ -115,8 +115,8 @@ def get_safe_globals(): json=NamespaceDict(loads=json.loads, dumps=json.dumps), as_json=frappe.as_json, dict=dict, - _dict=frappe._dict, log=frappe.log, + _dict=frappe._dict, args=form_dict, frappe=NamespaceDict( call=call_whitelisted_function, From dcae57475d2b26b3e343938bd02e30387919786f Mon Sep 17 00:00:00 2001 From: Raffael Meyer <14891507+barredterra@users.noreply.github.com> Date: Wed, 7 Dec 2022 10:27:07 +0100 Subject: [PATCH 10/15] fix: unscrub and translate field names in tooltip explaining fetch from (#19143) --- frappe/public/js/frappe/form/controls/base_input.js | 2 +- frappe/translations/de.csv | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/frappe/public/js/frappe/form/controls/base_input.js b/frappe/public/js/frappe/form/controls/base_input.js index 43fb4f54dc..0b9da726d7 100644 --- a/frappe/public/js/frappe/form/controls/base_input.js +++ b/frappe/public/js/frappe/form/controls/base_input.js @@ -109,7 +109,7 @@ frappe.ui.form.ControlInput = class ControlInput extends frappe.ui.form.Control "title", __( "This value is fetched from {0}'s {1} field", - me.df.fetch_from.split(".") + me.df.fetch_from.split(".").map((value) => __(frappe.unscrub(value))) ) ); } diff --git a/frappe/translations/de.csv b/frappe/translations/de.csv index fd81f8e87c..ffda3ca127 100644 --- a/frappe/translations/de.csv +++ b/frappe/translations/de.csv @@ -4828,3 +4828,4 @@ CSV Quoting,Anführungszeichen, CSV Preview,Vorschau, Non-numeric,Nicht-numerische, Minimal,Minimal, +This value is fetched from {0}'s {1} field,Dieser Wert ergibt sich aus dem Feld {1} von {0}, From d61748446bfa39c862d951cc7b7a5036846fbecb Mon Sep 17 00:00:00 2001 From: Sagar Vora Date: Wed, 7 Dec 2022 09:39:07 +0000 Subject: [PATCH 11/15] fix: validate email template subject and minor refactor (#19102) * fix: validate email template subject * chore: remove duplicate call to `json.loads` and minor refactor --- .../doctype/email_template/email_template.py | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/frappe/email/doctype/email_template/email_template.py b/frappe/email/doctype/email_template/email_template.py index fcc6ce5010..1ef8ec062b 100644 --- a/frappe/email/doctype/email_template/email_template.py +++ b/frappe/email/doctype/email_template/email_template.py @@ -9,33 +9,33 @@ from frappe.utils.jinja import validate_template class EmailTemplate(Document): + @property + def response_(self): + return self.response_html if self.use_html else self.response + def validate(self): - if self.use_html: - validate_template(self.response_html) - else: - validate_template(self.response) + validate_template(self.subject) + validate_template(self.response_) def get_formatted_subject(self, doc): return frappe.render_template(self.subject, doc) def get_formatted_response(self, doc): - if self.use_html: - return frappe.render_template(self.response_html, doc) - - return frappe.render_template(self.response, doc) + return frappe.render_template(self.response_, doc) def get_formatted_email(self, doc): if isinstance(doc, str): doc = json.loads(doc) - return {"subject": self.get_formatted_subject(doc), "message": self.get_formatted_response(doc)} + return { + "subject": self.get_formatted_subject(doc), + "message": self.get_formatted_response(doc), + } @frappe.whitelist() def get_email_template(template_name, doc): """Returns the processed HTML of a email template with the given doc""" - if isinstance(doc, str): - doc = json.loads(doc) email_template = frappe.get_doc("Email Template", template_name) return email_template.get_formatted_email(doc) From 02601dafd4c3de5d7d537cbb225af976033adf9a Mon Sep 17 00:00:00 2001 From: Mohammad Hussain Nagaria <34810212+NagariaHussain@users.noreply.github.com> Date: Wed, 7 Dec 2022 15:11:46 +0530 Subject: [PATCH 12/15] perf: remove redundant render template (#19123) --- frappe/website/doctype/website_theme/website_theme.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/frappe/website/doctype/website_theme/website_theme.py b/frappe/website/doctype/website_theme/website_theme.py index ca78adf94e..7abfab93e3 100644 --- a/frappe/website/doctype/website_theme/website_theme.py +++ b/frappe/website/doctype/website_theme/website_theme.py @@ -62,10 +62,6 @@ class WebsiteTheme(Document): def generate_bootstrap_theme(self): from subprocess import PIPE, Popen - self.theme_scss = frappe.render_template( - "frappe/website/doctype/website_theme/website_theme_template.scss", self.as_dict() - ) - # create theme file in site public files folder folder_path = abspath(frappe.utils.get_files_path("website_theme", is_private=False)) # create folder if not exist From b11793ab02ad2397072e80cb732278832ac5969b Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Wed, 7 Dec 2022 16:34:15 +0530 Subject: [PATCH 13/15] fix: set filename explicitly for safe_exec --- frappe/query_builder/utils.py | 3 +-- frappe/utils/safe_exec.py | 7 +++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/frappe/query_builder/utils.py b/frappe/query_builder/utils.py index be0403a291..91cdfd0a54 100644 --- a/frappe/query_builder/utils.py +++ b/frappe/query_builder/utils.py @@ -104,9 +104,8 @@ def patch_query_execute(): # frame1: execute_query() # frame2: frame that called `query.run()` # - # if frame2 is server script it wont have a filename and hence + # if frame2 is server script is set as the filename # it shouldn't be allowed. - # p.s. stack() returns `""` as filename if not a file. pass else: raise frappe.PermissionError("Only SELECT SQL allowed in scripting") diff --git a/frappe/utils/safe_exec.py b/frappe/utils/safe_exec.py index 053793af03..9e99754c67 100644 --- a/frappe/utils/safe_exec.py +++ b/frappe/utils/safe_exec.py @@ -78,8 +78,11 @@ def safe_exec(script, _globals=None, _locals=None, restrict_commit_rollback=Fals with safe_exec_flags(), patched_qb(): # execute script compiled by RestrictedPython - # pylint: disable-next=exec-used - exec(compile_restricted(script, policy=FrappeTransformer), exec_globals, _locals) + exec( + compile_restricted(script, filename="", policy=FrappeTransformer), + exec_globals, + _locals, + ) return exec_globals, _locals From b304751639d61efb3dc0319d822c5413f636f95a Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Thu, 8 Dec 2022 00:09:59 +0530 Subject: [PATCH 14/15] ci: common server test (#19177) --- .github/workflows/server-mariadb-tests.yml | 148 ------------------ ...er-postgres-tests.yml => server-tests.yml} | 26 ++- 2 files changed, 18 insertions(+), 156 deletions(-) delete mode 100644 .github/workflows/server-mariadb-tests.yml rename .github/workflows/{server-postgres-tests.yml => server-tests.yml} (87%) diff --git a/.github/workflows/server-mariadb-tests.yml b/.github/workflows/server-mariadb-tests.yml deleted file mode 100644 index ae101d003b..0000000000 --- a/.github/workflows/server-mariadb-tests.yml +++ /dev/null @@ -1,148 +0,0 @@ -name: Server (MariaDB) - -on: - pull_request: - workflow_dispatch: - push: - branches: [ develop ] - -concurrency: - group: server-mariadb-develop-${{ github.event_name }}-${{ github.event.number }} - cancel-in-progress: true - - -permissions: - contents: read - -jobs: - checkrun: - name: Build Check - runs-on: ubuntu-latest - - outputs: - build: ${{ steps.check-build.outputs.build }} - - steps: - - name: Clone - uses: actions/checkout@v3 - - - name: Check if build should be run - id: check-build - run: | - python "${GITHUB_WORKSPACE}/.github/helper/roulette.py" - env: - TYPE: "server" - PR_NUMBER: ${{ github.event.number }} - REPO_NAME: ${{ github.repository }} - - test: - name: Unit Tests - runs-on: ubuntu-latest - needs: checkrun - if: ${{ needs.checkrun.outputs.build == 'strawberry' }} - timeout-minutes: 60 - - strategy: - fail-fast: false - matrix: - container: [1, 2] - - services: - mariadb: - image: mariadb:10.6 - env: - MARIADB_ROOT_PASSWORD: travis - ports: - - 3306:3306 - options: --health-cmd="mysqladmin ping" --health-interval=5s --health-timeout=2s --health-retries=3 - - steps: - - name: Clone - uses: actions/checkout@v3 - - - name: Setup Python - uses: actions/setup-python@v4 - with: - python-version: '3.11' - - - name: Check for valid Python & Merge Conflicts - run: | - python -m compileall -q -f "${GITHUB_WORKSPACE}" - if grep -lr --exclude-dir=node_modules "^<<<<<<< " "${GITHUB_WORKSPACE}" - then echo "Found merge conflicts" - exit 1 - fi - - - uses: actions/setup-node@v3 - with: - node-version: 16 - check-latest: true - - - name: Add to Hosts - run: | - echo "127.0.0.1 test_site" | sudo tee -a /etc/hosts - - - name: Cache pip - uses: actions/cache@v3 - with: - path: ~/.cache/pip - key: ${{ runner.os }}-pip-${{ hashFiles('**/*requirements.txt', '**/pyproject.toml', '**/setup.py') }} - restore-keys: | - ${{ runner.os }}-pip- - ${{ runner.os }}- - - - name: Get yarn cache directory path - id: yarn-cache-dir-path - run: echo "::set-output name=dir::$(yarn cache dir)" - - - uses: actions/cache@v3 - id: yarn-cache - with: - path: ${{ steps.yarn-cache-dir-path.outputs.dir }} - key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} - restore-keys: | - ${{ runner.os }}-yarn- - - - name: Install Dependencies - run: | - bash ${GITHUB_WORKSPACE}/.github/helper/install_dependencies.sh - bash ${GITHUB_WORKSPACE}/.github/helper/install.sh - env: - BEFORE: ${{ env.GITHUB_EVENT_PATH.before }} - AFTER: ${{ env.GITHUB_EVENT_PATH.after }} - TYPE: server - DB: mariadb - - - name: Run Tests - run: cd ~/frappe-bench/sites && ../env/bin/python3 ../apps/frappe/.github/helper/ci.py - env: - SITE: test_site - CI_BUILD_ID: ${{ github.run_id }} - BUILD_NUMBER: ${{ matrix.container }} - TOTAL_BUILDS: 2 - - - name: Upload coverage data - uses: actions/upload-artifact@v3 - with: - name: coverage-${{ matrix.container }} - path: /home/runner/frappe-bench/sites/coverage.xml - - coverage: - name: Coverage Wrap Up - needs: [test, checkrun] - runs-on: ubuntu-latest - if: ${{ needs.checkrun.outputs.build == 'strawberry' }} - steps: - - name: Clone - uses: actions/checkout@v3 - - - name: Download artifacts - uses: actions/download-artifact@v3 - - - name: Upload coverage data - uses: codecov/codecov-action@v3 - with: - name: MariaDB - fail_ci_if_error: true - verbose: true - flags: server-mariadb diff --git a/.github/workflows/server-postgres-tests.yml b/.github/workflows/server-tests.yml similarity index 87% rename from .github/workflows/server-postgres-tests.yml rename to .github/workflows/server-tests.yml index dcc078ad2a..a003393782 100644 --- a/.github/workflows/server-postgres-tests.yml +++ b/.github/workflows/server-tests.yml @@ -1,4 +1,4 @@ -name: Server (Postgres) +name: Server on: pull_request: @@ -7,9 +7,10 @@ on: branches: [ develop ] concurrency: - group: server-postgres-develop-${{ github.event_name }}-${{ github.event.number }} + group: server-develop-${{ github.event_name }}-${{ github.event.number }} cancel-in-progress: true + permissions: contents: read @@ -44,9 +45,18 @@ jobs: strategy: fail-fast: false matrix: + db: ["mariadb", "postgres"] container: [1, 2] services: + mariadb: + image: mariadb:10.6 + env: + MARIADB_ROOT_PASSWORD: travis + ports: + - 3306:3306 + options: --health-cmd="mysqladmin ping" --health-interval=5s --health-timeout=2s --health-retries=3 + postgres: image: postgres:12.4 env: @@ -78,7 +88,7 @@ jobs: - uses: actions/setup-node@v3 with: - node-version: '16' + node-version: 16 check-latest: true - name: Add to Hosts @@ -114,7 +124,7 @@ jobs: BEFORE: ${{ env.GITHUB_EVENT_PATH.before }} AFTER: ${{ env.GITHUB_EVENT_PATH.after }} TYPE: server - DB: postgres + DB: ${{ matrix.db }} - name: Run Tests run: cd ~/frappe-bench/sites && ../env/bin/python3 ../apps/frappe/.github/helper/ci.py @@ -127,14 +137,14 @@ jobs: - name: Upload coverage data uses: actions/upload-artifact@v3 with: - name: coverage-${{ matrix.container }} + name: coverage-${{ matrix.db }}-${{ matrix.container }} path: /home/runner/frappe-bench/sites/coverage.xml coverage: name: Coverage Wrap Up needs: [test, checkrun] - if: ${{ needs.checkrun.outputs.build == 'strawberry' }} runs-on: ubuntu-latest + if: ${{ needs.checkrun.outputs.build == 'strawberry' }} steps: - name: Clone uses: actions/checkout@v3 @@ -145,7 +155,7 @@ jobs: - name: Upload coverage data uses: codecov/codecov-action@v3 with: - name: Postgres + name: Server fail_ci_if_error: true verbose: true - flags: server-postgres + flags: server From 19588b24f7b39efe7e9ede3c1cffda15a3b80047 Mon Sep 17 00:00:00 2001 From: phot0n Date: Wed, 7 Dec 2022 12:28:31 +0530 Subject: [PATCH 15/15] fix: stabilize shared with dialog --- frappe/public/js/frappe/form/sidebar/share.js | 14 ++++++++------ frappe/share.py | 2 +- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/frappe/public/js/frappe/form/sidebar/share.js b/frappe/public/js/frappe/form/sidebar/share.js index d2ed9cb349..dd310531f0 100644 --- a/frappe/public/js/frappe/form/sidebar/share.js +++ b/frappe/public/js/frappe/form/sidebar/share.js @@ -17,9 +17,12 @@ frappe.ui.form.Share = class Share { this.parent.find(".share-doc-btn").hide(); } - this.parent.find(".share-doc-btn").on("click", () => { - this.frm.share_doc(); - }); + this.parent + .find(".share-doc-btn") + .off("click") + .on("click", () => { + this.frm.share_doc(); + }); this.shares.empty(); @@ -41,6 +44,8 @@ frappe.ui.form.Share = class Share { this.dialog = d; this.dirty = false; + $(d.body).html('

' + __("Loading...") + "

"); + frappe.call({ method: "frappe.share.get_users", args: { @@ -52,8 +57,6 @@ frappe.ui.form.Share = class Share { }, }); - $(d.body).html('

' + __("Loading...") + "

"); - d.onhide = function () { // reload comments if (me.dirty) me.frm.sidebar.reload_docinfo(); @@ -188,7 +191,6 @@ frappe.ui.form.Share = class Share { } me.dirty = true; - me.render_shared(); me.frm.shared.refresh(); }, }); diff --git a/frappe/share.py b/frappe/share.py index 2556d1d484..2cdca9af91 100644 --- a/frappe/share.py +++ b/frappe/share.py @@ -82,7 +82,7 @@ def remove(doctype, name, user, flags=None): @frappe.whitelist() def set_permission(doctype, name, user, permission_to, value=1, everyone=0): """Expose function without flags to the client-side""" - set_docshare_permission(doctype, name, user, permission_to, value=value, everyone=everyone) + return set_docshare_permission(doctype, name, user, permission_to, value=value, everyone=everyone) def set_docshare_permission(doctype, name, user, permission_to, value=1, everyone=0, flags=None):